php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #68629 Transparent artifacts when using imagerotate
Submitted: 2014-12-19 14:12 UTC Modified: 2016-09-14 15:56 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:0 (0.0%)
Same OS:0 (0.0%)
From: bas5winkel at gmail dot com Assigned: pajoye
Status: Analyzed Package: GD related
PHP Version: 5.5Git-2014-12-19 (Git) OS: Windows7
Private report: No CVE-ID:
Have you experienced this issue?
Rate the importance of this bug to you:

 [2014-12-19 14:12 UTC] bas5winkel at gmail dot com
Description:
------------
---
From manual page: http://www.php.net/function.imagerotate
---

Linux (RHEL6+PHP5.3.3) works fine.
But with WAMP (Windows7+PHP5.5.12) transparent artifacts appear when using imagerotate.
The artifacts appear only in the transparent area of the image that is rotated.
The transparent aera should only contain pixels with the color code 0X7F000000 but a 'grid'-like pattern of pixels with color code 0x7E000000 appears.
(the alpha channel value should be 127 but some pixels become 126).
In the test script I have replaced the incorrect pixels with a non transparent color to show the pattern.



Test script:
---------------
<?PHP

// create fully transparent canvas
$canvas = imagecreatetruecolor(200,200);
imagesavealpha($canvas, true);
$trans_colour = imagecolorallocatealpha($canvas, 0, 0, 0, 127);
imagefill($canvas, 0, 0, $trans_colour); 
imagesavealpha($canvas, true);

// rotate the canvas 45 degrees
$outputCanvas = imagerotate($canvas, 45, imageColorAllocateAlpha($canvas, 0, 0, 0, 127),0);
imagealphablending($outputCanvas, false);
imagesavealpha($outputCanvas, true);
	
// replace colors not being fully transparent
$blue_color = imageColorAllocateAlpha($outputCanvas, 0, 0, 255, 0);
$width = imagesx($outputCanvas);
$height = imagesy($outputCanvas);
for($y=0;$y<$height;$y++)
{
	for($x=0;$x<$width;$x++)
	{
		$rgb = imagecolorat($outputCanvas, $x, $y);
		if ($rgb != 0x7F000000)
		{
			imagesetpixel($outputCanvas,$x,$y,$blue_color);
		}
	}
}

header("Content-Type: image/png");
imagepng($outputCanvas);

imagedestroy($canvas);
imagedestroy($outputCanvas);
		
?>

Expected result:
----------------
The script rotates a fully transparent image and should show a fully transparent image (shown as a grey image in most browsers).
Pixels that are not fully transparent are colored blue.
No blue pixels should be visible.

Actual result:
--------------
When running the script on windows7 (wamp2.5-PHP5.5.12),
a grid like grey/blue pattern appears which shows that most fully transparent pixels have become not fully transparent during the rotation.
I replaced the pixels that are not correct with a blue color in order to visualize the pattern. 
All pixels should have a alpha value of 127 but somehow most of them become 126.


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-09-14 14:28 UTC] cmb@php.net
-Status: Open +Status: Verified -Assigned To: +Assigned To: cmb
 [2016-09-14 14:28 UTC] cmb@php.net
I can confirm this issue for latest bundled GD, and also that
external libgd is not affected.
 [2016-09-14 15:09 UTC] cmb@php.net
The reason for the different behavior is that PHP's bundled libgd
has optimized implementations for IMG_BILINEAR_FIXED and
IMG_BICUBIC_FIXED, which the external libgd has not yet. However,
apparently both implementations have a bug wrt. to alpha (might be
rounding issues). Anyhow, setting the interpolation method to
IMG_BICUBIC, for instance, gives the desired result.
 [2016-09-14 15:56 UTC] cmb@php.net
-Status: Verified +Status: Analyzed -Assigned To: cmb +Assigned To: pajoye
 [2016-09-14 15:56 UTC] cmb@php.net
Yes, that is definitely a precision issue. Switching to double
arithmetic almost solves the issue on my machine (still, several
alpha values would be off).

Pierre, it seems to me that the 8-bit shift is simply not
sufficient to have the desired precision (particular with regard
to the trigonometric functions). On the other hand, there *might*
already be issues on 32-bit Windows, where a long has only 32 bit.
 
PHP Copyright © 2001-2017 The PHP Group
All rights reserved.
Last updated: Tue Aug 29 15:01:52 2017 UTC