|  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #40158 Artifact left on transparent pngs using image filters
Submitted: 2007-01-18 10:40 UTC Modified: 2017-01-22 15:06 UTC
Avg. Score:4.0 ± 0.8
Reproduced:2 of 2 (100.0%)
Same Version:2 (100.0%)
Same OS:0 (0.0%)
From: henus at mail dot ru Assigned: pajoye (profile)
Status: Closed Package: GD related
PHP Version: 5CVS-2008-11-03 OS: *
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
Block user comment
Status: Assign to:
Bug Type:
From: henus at mail dot ru
New email:
PHP Version: OS:


 [2007-01-18 10:40 UTC] henus at mail dot ru
After using imagefilter (IMG_FILTER_COLORIZE) on transparent png image the result color of translucent pixels is wrong.

I.e. the edge of non-transparent part of image, which contain translucent antialiasing area - wrong colored.

Reproduce code:
$mask=imagecreatefrompng("mask.png"); // (mask for colorize, contain translucent)
imagealphablending($mask, TRUE);
imagealphablending($imagemain, TRUE);
$color=imagecolorallocate($imagemain, 0, 0, 0);
imagefill($imagemain, 0, 0, $color);
imagefilter($mask, IMG_FILTER_COLORIZE, -255, -255, 0);
imagecopy($imagemain, $mask, 0, 0, 0, 0, $imagewidth, $imageheight);
imagepng($imagemain,"result_incorrect.png"); // 

Expected result:
The result image - absolutely black square

Actual result:
The result image - black square with gray line (on the edge of mask image)


Add a Patch

Pull Requests

Add a Pull Request


AllCommentsChangesGit/SVN commitsRelated reports
 [2007-01-18 11:03 UTC] henus at mail dot ru
My mistake...

correct 12 line in Reproduce code:

imagefilter($mask, IMG_FILTER_COLORIZE, -255, -255, -255);
 [2007-01-18 14:23 UTC] henus at mail dot ru

Lines 3682-3685:

new_pxl = gdImageColorAllocateAlpha(src, (int)r, (int)g, (int)b, a);
if (new_pxl == -1) {
	new_pxl = gdImageColorClosestAlpha(src, (int)r, (int)g, (int)b, a);

....should be without alpha...
 [2007-01-18 14:26 UTC]
>...should be without alpha...
Could you plz elaborate?
A unified diff would explain it much better, btw.
 [2007-01-18 15:22 UTC]
Can you provide an image to show what you expect?

I did not check your script but having an image will help to really understand what you are trying to achieve.

By the way, filters work only with truecolor images, allocate will never fail.
 [2007-01-18 17:56 UTC] henus at mail dot ru
i create black image and overlay it by colorized white-truecolor-png24-image ( )
the result of colorize like:
imagefilter($mask, IMG_FILTER_COLORIZE, -255, -255, -255);
is image: 
which contain artefacts...

also, the result of such script ( )

is truecolor - 1
before - Array ( [red] => 255 [green] => 255 [blue] => 255 [alpha] => 63 ) 
wrong result, using filter - Array ( [red] => 126 [green] => 126 [blue] => 126 [alpha] => 31 ) 
wrong result, using imagecolorallocatealpha and imagesetpixel - Array ( [red] => 126 [green] => 126 [blue] => 126 [alpha] => 31 ) 
correct result, using imagefill, imagecolorallocatealpha and imagesetpixel - Array ( [red] => 0 [green] => 0 [blue] => 0 [alpha] => 63 )

colorizing pixel ( [red] => 255 [green] => 255 [blue] => 255 [alpha] => 63 ) to black 
should be with ( [red] => 0 [green] => 0 [blue] => 0 [alpha] => 63 ), 
not  ( [red] => 126 [green] => 126 [blue] => 126 [alpha] => 31 )
 [2007-01-18 18:09 UTC]
Please provide an *image* showing what you expect.
 [2007-01-18 18:11 UTC] henus at mail dot ru
correction fo my previous post about

Lines 3682-3688:
new_pxl = gdImageColorAllocateAlpha(src, (int)r, (int)g, (int)b, a);
if (new_pxl == -1) {
	new_pxl = gdImageColorClosestAlpha(src, (int)r, (int)g, (int)b, a);
if ((y >= 0) && (y < src->sy)) {
	gdImageSetPixel (src, x, y, new_pxl);

in gdImageSetPixel src should be absolutely transparent, with  alpha=127
differently it mix colors.
 [2007-01-18 18:32 UTC] henus at mail dot ru
i expect absolutely black image like
instead of

i use colorizing by black for clearness.
 [2007-01-18 18:51 UTC]
An absolute black image is not what you should expect.

imagefilter($mask, IMG_FILTER_COLORIZE, -255, -255, 0); will replace the white color with blue (you remove all components but the blue):

imagecopy($imagemain, $mask, 0, 0, 0, 0, $imagewidth, $imageheight); will copy it over the $imagemain, the border of the quadrant will be blended over black:

Each pixel in your circle are rgb(255,255,255) with some alpha value in the edges (and only in the edges). You are substracting 255 to the R and G component, the result is blue.

Now, take a look at this image:

It is what you are expecting (if I understand correctly your problem). The edges of the circle have a blue color with various alpha values (rgba(255,0,0,xxx)). You can reproduce it by disabling the alpha blending mode in the mask image (imagealphablending($mask, false); ). The alpha component will be kept and stored in the image instead of being used as a blending value.

Let me know if that solves your problem.

By the way, COLORIZE uses gdImageColor. The lines you are referring to are in the contrast function.

 [2007-01-18 18:51 UTC]
(rgba(255,0,0,xxx)) should have been (rgba(0,0,255,xxx)) but you noticed it :)
 [2007-01-18 19:37 UTC] henus at mail dot ru
it`s not solve my problem.... :(
first - 
about blue color - look at my submission from 
[18 Jan 11:03am UTC]

if use 
imagefilter($mask, IMG_FILTER_COLORIZE, -255, -255, -255);
the result is
with legibly visible artefacts.

second - 
also has artefacts at the adges...
pixel from edge with coord (95,11) have wrong color
(why is red>0  and green>0 ????????? after substracting 255???) 

(should be

third - 
look at my submission from [18 Jan 5:56pm UTC]
why is 255-255=126????????????????

one more demo - 
imagefilter($mask, IMG_FILTER_COLORIZE, -255, -255, 0);

mask -
incorrect image -
correct image -
 [2007-01-18 19:54 UTC]
"pixel from edge with coord (95,11) have wrong color.
red-98 green-98 blue-164 (why is red>0  and green>0 ????????? after substracting 255???)  (should be red-0 green-0 blue-102)"

It is blended over the destination pixel. You have to disable alpha blending *before* the imagefilter call.

This image:

shows exactly what you are trying to do (blue, black or purple, it really does not matter), the script being:

imagealphablending($mask, false); //<<< Important!
imagefilter($mask, IMG_FILTER_COLORIZE, -255, -255, -255);
//<<< save alpha, so we see its value
imagesavealpha($mask, true);

Using your last example, the resulting image is like your "result_correct3.png".

 [2007-01-19 11:53 UTC] henus at mail dot ru
Yes, the is global problem with alphablending in libgd\gd.c

but about "imagealphablending($mask, false); //<<< Important!":
i absolutely should not care about ebabling\disabling imagealphablending before imagefilter, 
because of function shoud colorize image by new values of red,gree,blue 
(!!!there is no alpha in parameters)

if IMG_FILTER_COLORIZE will have in parameters alpha,
if alphablending enable, value of alpha should allow for calculation of new color values
(in gdImageColor it will before new_pxl = gdImageColorAllocateAlpha(src, (int)r, (int)g, (int)b, a);)
and gdImageSetPixel shoul with disabled alphablending.

otherwise function work like merging of two images with alphablending.
first image - source image from function parameters.
second image - correct colorized copy of source image.

it is not logically. it is incorrect.

another bug in imagefill:
this function not only fill image, it is also disable alphablending.
php example:

/* first colorizing */
imagealphablending($im1, TRUE);
imagefilter($im1, IMG_FILTER_COLORIZE, -255, 255, 0);

/* second colorizing */
imagealphablending($im2, TRUE);
/* att!!! after imagefill another enabling alphablending */
imagealphablending($im2, TRUE);
imagefilter($im2, IMG_FILTER_COLORIZE, -255, 255, 0);

print"<br>before 1 - ";
print"<br>after  1 - ";
print"<br><br>before 2 - ";
print"<br>after  2 - ";

before 1- Array ( [red] => 255 [green] => 0 [blue] => 0 [alpha] => 63 ) 
after  1 - Array ( [red] => 0 [green] => 255 [blue] => 0 [alpha] => 63 ) 

before 2- Array ( [red] => 0 [green] => 255 [blue] => 0 [alpha] => 63 ) 
after  2 - Array ( [red] => 126 [green] => 128 [blue] => 0 [alpha] => 31 )

after 1 - correct result of IMG_FILTER_COLORIZE, because of imagefill disable alphablending
after 2 - incorrect result of IMG_FILTER_COLORIZE, because of after imagefill i manually enable alphablending

disabling alphablending in code it is good solutions for gdImageColor, but after it is necessary to restore old value of alphaBlendingFlag.
 [2007-01-19 12:02 UTC]
Can you *PLEASE* confirm that it works when you disable alpha blending? Answer should be Yes or No, I got the details already. I really do not have the time to explain/ask again and again the same thing.

About imagefill, yes, that's a bug. Please open a new one if you like. I will fix it as soon as possible.
 [2007-01-19 12:11 UTC] henus at mail dot ru
Yes, it work
 [2007-01-19 12:14 UTC]
Ok, good, thanks for the test. I will disable alpha blending and restore it on exit in imagefilter.

About the imagefill bug, it happens only with small images (< 4 pixels large), thanks for the notice.
 [2007-01-19 16:08 UTC]
For the record, the imagefill bug is fixed in cvs, it will be in 5.2.1 .
 [2008-11-03 09:09 UTC]
not fixed, imagefill was opened in another bug report.
 [2017-01-22 15:06 UTC]
-Status: Assigned +Status: Closed
 [2017-01-22 15:06 UTC]
I'm closing this ticket, because the originally reported issue was
not a bug, and the imagefill() issue should have its own ticket
(preferably filed against libgd) – if there is an issue at all.
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu May 30 03:01:30 2024 UTC