Hi Brett, don't have much time right now. Have you read the tutorial?
http://www.boost.org/doc/libs/1_42_0/libs/gil/doc/html/giltutorial.html
I'll read your email for thoroughly tomorrow.
Regards,
Christian
On Wed, Mar 31, 2010 at 5:33 PM, Brett Gmoser
Hello everybody,
I've been toying with GIL a bit for the last few days in my spare time, and I've got a few questions that I can't seem to find answers to in the documentation. The following function which I've written works, but I'd like to get a better understanding of how to use iterators to accomplish the same task (the documentation says that view(x, y) = z is inefficient), as well as a few other things. The job of this function is to crop an image, discarding any white background. In other words, find the top-most, left-most, right-most, and bottom-most pixel that isn't the background color (white), and crop the image around those coordinates.
template
void crop_image(ViewType& src, boost::scoped_ptr<ImageType>& dst) const { int top = 0; int right = 0; int bottom = 0; int left = 0; // Find the top, right, bottom, and left extents. First, find the top. for(int y=0; y < src.height(); ++y) { for(typename ViewType::x_iterator xpos = src.row_begin(y); xpos != src.row_end(y); ++xpos) { if(rgb8_pixel_t(255,255,255) != *xpos) { top = y; break; } } if(top) break; }
// ... Do similar things for finding the right, bottom, and left extents.
// We should now have the rectangle of the image, and it should be easy to copy everything over. dst.reset(new ImageType(1 + (right - left), 1 + (bottom - top))); for(int x = left; x <= right; ++x) for(int y = top; y <= bottom; ++y) view(*dst)((x - left), (y - top)) = src(x, y); }
So, my first question is - is there a better way to do that first chore of finding each extent? Such as a way to use std::find or std::find_if, keeping in mind that I have to do two of the four sides in reverse (bottom-to-top to find bottom-most, right-to-left to find right-most)?
The next question is about the final loop which copies from the source view to the newly created destination image. It seems that using iterators, I could do something like this, assuming that I had the above loops find iterator positions for all four extents (left, top, bottom, and right are iterators):
// Start the copying process by creating a column iterator for the destination table beginning at column 0. // The top iterator starts at the top-most extent - and we cycle through the source image in a top-to-bottom, // left-to-right fashion. for(typename ImageType::view_t::y_iterator dst_y = view(*dst).col_begin(0); top <= bottom; ++dst_y,++top) { // The left iterator needs to be initialized with whatever row we're on - this appears to be impossible. There doesn't // seem to be any suitable way to do this, so consider it pseudocode. typename ViewType::x_iterator src_x = left.y();
// The destination X iterator also needs to know what Y position to begin on. You'd think you would be able to initialize // it with an iterator position, but it doesn't seem that you can. Again, this doesn't actually compile (it's the // view(*dst).row_begin(y) part). for(typename ImageType::view_t::x_iterator dst_x = view(*dst).row_begin(y); // Here, I need to be able to tell if src_x has hit the right extent. src_x <= right doesn't seem it will work, because // again right doesn't know it's Y position. src_x != right;
// And increment both src and destination iterators. ++src_x,++dst_x ) { // Finally do the should-be-simple task of assigning the source pixel to the destination pixel. *dst_x = *src_x; } }
If you read the comments, most of this doesn't seem to be possible. I've seen that there is a "transform_pixel_positions" algorithm that may do something close to what I want, but unfortunately I cannot find any documentation on it (other than mentioning that it exists, and a short example that really doesn't help - one of the few examples actually provided by the documentation). It seems to pass a unary argument to a functor, but that doesn't seem useful if I don't have both the X and Y coordinates, or an X iterator and Y iterator. Also, nowhere can I find where it says what the argument passed to the functor actually /is/.
So after I figure these few things out, I'm hoping to be able to speed up my program a little bit. Right now everything is pretty slow using that view(x, y) method. I'd appreciate any help that anybody can give, thanks!
Brett
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users