Search code examples
phptransparentimage-resizingphp-gd

PHP imageconvolution() leaves black dot in the upper left corner


I'm trying to sharpen resized images using this code:

imageconvolution($imageResource, array(
        array( -1, -1, -1 ),
        array( -1, 16, -1 ),
        array( -1, -1, -1 ),
    ), 8, 0);

When the transparent PNG image is sharpened, using code above, it appears with a black dot in the upper left corner (I have tried different convolution kernels, but the result is the same). After resizing the image looked OK.

1st image is the original one

2nd image is the sharpened one

Original image Sharpen image

EDIT: What am I going wrong? I'm using the color retrieved from pixel.

$color = imagecolorat($imageResource, 0, 0);
    imageconvolution($imageResource, array(
        array( -1, -1, -1 ),
        array( -1, 16, -1 ),
        array( -1, -1, -1 ),
    ), 8, 0);
            imagesetpixel($imageResource, 0, 0, $color);

Is imagecolorat the right function? Or is the position correct?

EDIT2: I have changed coordinates, but still no luck. I've check the transparency given by imagecolorat (according to this post). This is the dump:

array(4) {
   red => 0
   green => 0
   blue => 0
   alpha => 127
}

Alpha 127 = 100% transparent. Those zeroes might cause the problem...


Solution

  • Looks like a bug in the convolution code (corners are special cases in some implementations).

    As a workaround, you can save the pixel value in that corner just before the convolution and restore it afterwards, with imageSetPixel().

    The pixel you need to save is at (0,0), and possibly you will need to also check the transparency (but I think it should work with just imageColorAt and imageSetPixel).

    TEST CODE

    The file 'giants.png' I wgot from the one you posted above. If I do not use imageSetPixel I experience the same extra pixel you got. With imageSetPixel, the image looks correct to me.

    Possibly there's some slight difference in the sequence I run ImageSaveAlpha or set alpha blending.

    <?php
            $giants = ImageCreateFromPNG('giants.png');
    
            $imageResource = ImageCreateTrueColor(190, 190);
    
            ImageColorTransparent($imageResource, ImageColorAllocateAlpha($imageResource, 0, 0, 0, 127));
            ImageAlphaBlending($imageResource, False);
            ImageSaveAlpha($imageResource, True);
    
            ImageCopyResampled($imageResource, $giants, 0, 0, 0, 0, 190, 190, ImageSX($giants), ImageSY($giants));
    
            $color = ImageColorAt($imageResource, 0, 0);
            ImageConvolution($imageResource, array(
                            array( -1, -1, -1 ),
                            array( -1, 16, -1 ),
                            array( -1, -1, -1 ),
                    ), 8, 0);
            ImageSetPixel($imageResource, 0, 0, $color);
            ImagePNG($imageResource, 'dwarves.png');
    ?>