The problem is pretty basic.
(I am puzzled why the search didn’t find anything)
I have a rectangular “picture” that stores it’s pixel color line
after line in a std::vector
I want to copy a rectangular region out of that picture.
How would I elegantly code this in c++?
My first try:
template <class T> std::vector<T> copyRectFromVector(const std::vector<T>& vec, std::size_t startx, std::size_t starty, std::size_t endx, std::size_t endy, std::size_t fieldWidth, std::size_t fieldHeight)
{
using namespace std;
vector<T> ret((endx-startx)*(endy-starty)+10); // 10: chickenfactor
// checks if the given parameters make sense:
if (vec.size() < fieldWidth*endy)
{
cerr << "Error: CopyRectFromVector: vector to small to contain rectangular region!" << std::endl;
return ret;
}
// do the copying line by line:
vector<T>::const_iterator vecIt = vec.begin();
vector<T>::forward_iterator retIt = ret.end();
vecIt += startx + (starty*fieldWidth);
for(int i=starty; i < endy; ++i)
{
std::copy(vecIt, vecIt + endx - startx, retIt);
}
return ret;
}
does not even compile…..
Addit: Clarification:
I know how to do this “by hand”. It is not a problem as such. But I would love some c++ stl iterator magic that does the same, but faster and… more c++ stylish.
Addition: I give the algorithm the pictureDataVector, the width and height of the picture and a rectangle denoting the region that I want to copy out of the picture.
The return value should be a new vector with the contents of the rectangle.
Think of it as opening your favorite image editor, and copy a rectangular region out of that.
The Picture is stored as a long 1D array(vector) of pixelcolors.
Your question asks for a C++ way of copying a rectangular field of elements in some container. You have a fairly close example of doing so and will get more in the answers. Let’s generalize, though:
You want an iterator that travels a rectangular range of elements over some range of elements. So, how about write a sort of adapter that sits on any container and provides this special iterator.
Gonna go broad strokes with the code here:
I’m sure this is totally do-able, but I’m not comfortable coding stl-style template stuff off-the-cuff. If I have some time and you’re interested, I may re-edit a rough-draft later, since this is an interesting concept.
See this SO question’s answer for inspiration.