Note : SO has converted the above reference image to jpeg. Here is the transparent PNG.
Following is an example code which recreates a png image on a new canvas and preserves the transparency. As you can see, it also allows pixel level manipulation eg. with a custom function like custom_func($r, $g, $b)
, which is illustrated better at the bottom of this question.
Basically this code recreates/redraws the above image on a new canvas successfully as it is. Please note, that sky is completely transparent in the above image.
$image = imagecreatefrompng('grass.png');
$x_dimension = imagesx($image);
$y_dimension = imagesy($image);
$new_image = imagecreatetruecolor($x_dimension, $y_dimension);
// create a transparent canvas
$trans_color = imagecolorallocatealpha($new_image, 0x00, 0x00, 0x00, 127);
imagefill($new_image, 0, 0, $trans_color);
for ($x = 0; $x < $x_dimension; $x++) {
for ($y = 0; $y < $y_dimension; $y++) {
$rgb = imagecolorat($image, $x, $y);
$r = ($rgb >> 16) & 0xFF;
$g = ($rgb >> 8) & 0xFF;
$b = $rgb & 0xFF;
$alpha = ($rgb & 0x7F000000) >> 24;
//$pixel = custom_function($r, $g, $b);
imagesetpixel($new_image, $x, $y, imagecolorallocatealpha($image, $r, $g, $b, $alpha));
}
}
imagesavealpha($new_image, true);
imagepng($new_image, 'grass-result.png');
However when I run the same code on this particular png image below.
It gives me an almost black image like this.
I would like to understand what is happening here and why ? Most importantly, I would like to know about possible factors that could influence the process, so I could look into it. Why is it that the result differs from one png to another ?
Ideally, I would like my code to be able to preserve and transfer the transparency state ( transparent, semi-transparent or opaque ) of the source png image, as it is, to the recreated image. As you can see, I have been able to achieve it, except for the case above.
Just in case, here is my environment. Windows 7 - 64 bit ** Wampserver2.5 ** Apache-2.4.9 ** Mysql-5.6.17 ** php5.5.12-64b. Also here is a var_dump of the image with getimagesize()
:
array (size=6)
0 => int 228
1 => int 230
2 => int 3
3 => string 'width="228" height="230"' (length=24)
'bits' => int 8
'mime' => string 'image/png' (length=9)
UPDATE
Here is the proof that the example image is indeed transparent and also that it can be manipulated, while keeping the transparency. Notice the bottom of the image is more brownish now. This was achieved by a slight modification of this line imagesetpixel($new_image, $x, $y, imagecolorallocatealpha($image, 100, $g, $b, $alpha));
Your second image is 8-bit, meaning it only supports a maximum of 256 colours. This makes it a 'palette-based' image and as such it doesn't support alpha transparency.
By simply adding the following line after creating $image
you can fix the problem:
imagepalettetotruecolor($image);
This doesn't have any impact on images that are already true colour, so grass.png
continues to be processed correctly. From the PHP manual page:
Returns TRUE if the conversion was complete, or if the source image already is a true color image, otherwise FALSE is returned.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With