Fredrik Lundh wrote:

In my tests, all the resize and stretch filters appear to shift the
image down and to the right by about half an output pixel.
I've attached a (preliminary) patch.


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

Reply via email to