Fredrik Lundh wrote:
In my tests, all the resize and stretch filters appear to shift theI've attached a (preliminary) patch.
image down and to the right by about half an output pixel.
It certainly works for me. Area-averaged and stretched images are mostly visually indistinguishable -- the exceptions being high contrast drawings.
Stretch-resized images are consistently 1/256th darker than the same images resized by other means. My understanding of this is that when
a region of input pixels is (say) all 255s, except for one pixel of 254, then the float average is 254.9xx, so the output pixel becomes 254. On average this should darken by 0.5, but over the two passes, it darkens by a unit. I've attached a patch.
Here's an example, resizing a 450x325 image to 16x12 (as seen on http://halo.gen.nz/pil/examples.html), showing mean, RMS, and extreme differences between pixels.
before the patch, comparing stretched(NEAREST) to gimp:
R: mean: 1.020833 RMS: 1.190238, extrema: (-2.0, 4.0) G: mean: 0.973958 RMS: 1.120361, extrema: (-1.0, 4.0) B: mean: 0.911458 RMS: 1.058202, extrema: (-1.0, 3.0)
with the patch:
R: mean: 0.010417 RMS: 0.595119, extrema: (-3.0, 3.0) G: mean: 0.000000 RMS: 0.595119, extrema: (-2.0, 3.0) B: mean: -0.08854 RMS: 0.535218, extrema: (-2.0, 2.0)
Contrary to my earlier assertion, I have discovered the area averaged images differ from the gimp on the bottom row of the image.
comparing area-averaged to gimp:
R: mean: 0.041667 RMS: 0.204124, extrema: (0.0, 1.0) G: mean: 0.052083 RMS: 0.228218, extrema: (0.0, 1.0) B: mean: 0.020833 RMS: 0.144338, extrema: (0.0, 1.0)
douglas
--- Imaging-1.1.5/libImaging/Antialias.c 2004-12-20 03:35:54.000000000 +1300 +++ svn/libImaging/Antialias.c 2005-05-13 13:52:27.000000000 +1200 @@ -170,8 +170,8 @@ ss = 0.0; for (y = (int) ymin; y < (int) ymax; y++) ss = ss + imIn->image8[y][xx] * k[y - (int) ymin]; - ss = ss * ww; - if (ss <= 0.0) + ss = ss * ww + 0.5; + if (ss < 0.5) imOut->image8[yy][xx] = 0; else if (ss >= 255.0) imOut->image8[yy][xx] = 255; @@ -187,8 +187,8 @@ ss = 0.0; for (y = (int) ymin; y < (int) ymax; y++) ss = ss + (UINT8) imIn->image[y][xx] * k[y-(int) ymin]; - ss = ss * ww; - if (ss <= 0.0) + ss = ss * ww + 0.5; + if (ss < 0.5) imOut->image[yy][xx] = (UINT8) 0; else if (ss >= 255.0) imOut->image[yy][xx] = (UINT8) 255; @@ -246,8 +246,8 @@ ss = 0.0; for (x = (int) xmin; x < (int) xmax; x++) ss = ss + imIn->image8[yy][x] * k[x - (int) xmin]; - ss = ss * ww; - if (ss <= 0.0) + ss = ss * ww + 0.5; + if (ss < 0.5) imOut->image8[yy][xx] = (UINT8) 0; else if (ss >= 255.0) imOut->image8[yy][xx] = (UINT8) 255; @@ -265,8 +265,8 @@ ss = 0.0; for (x = (int) xmin; x < (int) xmax; x++) ss = ss + (UINT8) imIn->image[yy][x*4+b] * k[x - (int) xmin]; - ss = ss * ww; - if (ss <= 0.0) + ss = ss * ww + 0.5; + if (ss < 0.5) imOut->image[yy][xx*4+b] = (UINT8) 0; else if (ss >= 255.0) imOut->image[yy][xx*4+b] = (UINT8) 255;
_______________________________________________ Image-SIG maillist - Image-SIG@python.org http://mail.python.org/mailman/listinfo/image-sig