|
From: Maxim S. <mc...@an...> - 2005-12-09 21:14:21
|
> I run into another error related to image filters. The weird behavior > occurs > when the attached 1 pixel wide image gradient (attached) is passed to the > image resampler using bilinear filter. The image is used to create the > effect of a linear gradient, however when the image is drawn as a > rectangle > (e.g. filling the whole screen) the result is a weird conic like gradient. > The image should be resampled in the vertical direction (and this part > seems > to be correct), but the error occurs in horizontal direction. I believe > that > this error is just another aspect of image-filtering bug I previously > reported. Once again, it's not an error! It's exactly what I expect and it will work in this very way if you consider an infinite image, with fully transparent background color. Yes, it will be that, even if you calculate the colors manually. If it doesn't fit your needs it doesn't obligatory mean there's a bug. However, I have tried to generalize the access to source pixels: http://antigrain.com/stuff/image_filter2_test.zip With this approach the code can be simplified a lot. In fact, it determines clipping and/or wrapping modes. It can be as before, it can propagate the edge pixels as simple as that: if(x < 0) x = 0; if(y < 0) y = 0; if(x >= (int)m_rbuf->width()) x = m_rbuf->width() - 1; if(y >= (int)m_rbuf->height()) y = m_rbuf->height() - 1; It can also tile the image, with repeat/reflect options by X and Y. I would love to get rid of the existing bunch of code and leave just these compact functions. But there's a sacrifice too. It's performance, and potentially it's slower. Well, sometimes it works even faster, but you should expect some slowdown, about 10-20%. So, what would you say? Ivan, once again, you try to simulate a gradient with image transformer. The idea itself is crazy, but it's especially crazy to use image resampling. However, you can easily achieve what you need even with the existing code. First, you can use 3xN pixel image instead of 1xN and form the transformer as follows: double d = 1.0; x1 = d; y1 = d; x2 = img_width() - d; y2 = img_height() - d; quad[0] = dst_x1; quad[1] = dst_y1; quad[2] = dst_y2; quad[3] = dst_y2; quad[4] = dst_y3; quad[5] = dst_y3; agg::trans_affine tr(quad, x1, y1, x2, x2); Or, you don't have to do that, you can keep using your 1xN image, but just reduce the image size by 0.5: double d = 0.5; x1 = d; y1 = d; x2 = img_width() - d; y2 = img_height() - d; quad[0] = dst_x1; quad[1] = dst_y1; quad[2] = dst_y2; quad[3] = dst_y2; quad[4] = dst_y3; quad[5] = dst_y3; agg::trans_affine tr(quad, x1, y1, x2, x2); Of course, you won't achieve the effect of pixel propagation, but you will solve your task with the gradient. So, I need your opinions about extending functionality with slight degradation of image transformation performance. McSeem |