PNG manipulation removes transparency - php

I am simply trying to return an PNG image through PHP, but I have a problem with the transparency not showing right. (Basically one PHP file will be capable of returning any of my images.)
I use simple code to return the image:
<?php
$im = imagecreatefrompng("images/fakehairsalon.png");
header('Content-Type: image/png');
imagepng($im);
imagedestroy($im);
?>
The original image looks like this:
And the one returned via PHP (and that piece of code) looks like this:
Is there anything I can do to prevent this and make the image come through normal?

As explained in a user comment, you must do this:
<?php
$im = imagecreatefrompng("borrame.png");
header('Content-Type: image/png');
imagealphablending($im, true); // setting alpha blending on
imagesavealpha($im, true); // save alphablending setting (important)
imagepng($im);
imagedestroy($im);
?>
Update: This answer was assuming that your code is an except from a bigger script you are using to do on-the-fly image manipulation.
If you don't want to change the original file, this is a plain waste of memory and CPU cycles. You can use file system functions to read it as a regular file, such as readfile().
It's also worth noting that using PHP to deliver a file only makes sense if you want to do something else as well, such as:
Restricting access to the file
Keeping a counter

Related

how to render a php page as a png image using data uri

I've the data uri of a png image, I've stored the data uri in mysql data base. Lets say img.php is the file that returns as a png image
<?php
$id=$_GET['id];
//data base connection and mysql queries
$data = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOAAAADMCAYAAABqQ6+sAAAEn0lEQVR4Xu3TUQkAIBAFQc1iHsOaUMES+zNX4MFwO9fZdzgCBBKBKcDE3SiBLyBAj0AgFBBgiG+agAD9AIFQQIAhvmkCAvQDBEIBAYb4pgkI0A8QCAUEGOKbJiBAP0AgFBBgiG+agAD9AIFQQIAhvmkCAvQDBEIBAYb4pgkI0A8QCAUEGOKbJiBAP0AgFBBgiG+agAD9AIFQQIAhvmkCAvQDBEIBAYb4pgkI0A8QCAUEGOKbJiBAP0AgFBBgiG+agAD9AIFQQIAhvmkCAvQDBEIBAYb4pgkI0A8QCAUEGOKbJiBAP0AgFBBgiG+agAD9AIFQQIAhvmkCAvQDBEIBAYb4pgkI0A8QCAUEGOKbJiBAP0AgFBBgiG+agAD9AIFQQIAhvmkCAvQDBEIBAYb4pgkI0A8QCAUEGOKbJiBAP0AgFBBgiG+agAD9AIFQQIAhvmkCAvQDBEIBAYb4pgkI0A8QCAUEGOKbJiBAP0AgFBBgiG+agAD9AIFQQIAhvmkCAvQDBEIBAYb4pgkI0A8QCAUEGOKbJiBAP0AgFBBgiG+agAD9AIFQQIAhvmkCAvQDBEIBAYb4pgkI0A8QCAUEGOKbJiBAP0AgFBBgiG+agAD9AIFQQIAhvmkCAvQDBEIBAYb4pgkI0A8QCAUEGOKbJiBAP0AgFBBgiG+agAD9AIFQQIAhvmkCAvQDBEIBAYb4pgkI0A8QCAUEGOKbJiBAP0AgFBBgiG+agAD9AIFQQIAhvmkCAvQDBEIBAYb4pgkI0A8QCAUEGOKbJiBAP0AgFBBgiG+agAD9AIFQQIAhvmkCAvQDBEIBAYb4pgkI0A8QCAUEGOKbJiBAP0AgFBBgiG+agAD9AIFQQIAhvmkCAvQDBEIBAYb4pgkI0A8QCAUEGOKbJiBAP0AgFBBgiG+agAD9AIFQQIAhvmkCAvQDBEIBAYb4pgkI0A8QCAUEGOKbJiBAP0AgFBBgiG+agAD9AIFQQIAhvmkCAvQDBEIBAYb4pgkI0A8QCAUEGOKbJiBAP0AgFBBgiG+agAD9AIFQQIAhvmkCAvQDBEIBAYb4pgkI0A8QCAUEGOKbJiBAP0AgFBBgiG+agAD9AIFQQIAhvmkCAvQDBEIBAYb4pgkI0A8QCAUEGOKbJiBAP0AgFBBgiG+agAD9AIFQQIAhvmkCAvQDBEIBAYb4pgkI0A8QCAUEGOKbJiBAP0AgFBBgiG+agAD9AIFQQIAhvmkCAvQDBEIBAYb4pgkI0A8QCAUEGOKbJiBAP0AgFBBgiG+agAD9AIFQQIAhvmkCAvQDBEIBAYb4pgkI0A8QCAUEGOKbJiBAP0AgFBBgiG+agAD9AIFQQIAhvmkCAvQDBEIBAYb4pgkI0A8QCAUEGOKbJiBAP0AgFBBgiG+agAD9AIFQQIAhvmkCAvQDBEIBAYb4pgkI0A8QCAUEGOKbJiBAP0AgFBBgiG+agAD9AIFQQIAhvmkCAvQDBEIBAYb4pgkI0A8QCAUEGOKbJiBAP0AgFBBgiG+agAD9AIFQQIAhvmkCAvQDBEIBAYb4pgkI0A8QCAUEGOKbJiBAP0AgFBBgiG+awANJn7JcDjYVEQAAAABJRU5ErkJggg==";
//$data is obtained from mysql database
header('Content-Type: image/png');
$im = imagecreatefromstring($data);
imagepng($im);
imagedestroy($im);
?>
I've tried the above code, but its not giving me any output,
please help.
Thanks in advance.
The code is mostly pointless. You already have a PNG inside the data uri, so there is exactly ZERO point in loading that PNG into GD, then re-compressing to a PNG. that's massive waste of RAM and CPU time to basically accomplish nothing.
Also, GD doesn't understand data uris, so you cannot feed this uri into GD functions and expect something useful to happen.
You already have a PNG, so all you need to do is basically this:
$b64_png = string_operation_to_extract_base64_data_from_data_uri($datauri);
header('Content-type: image/png');
echo base64_decode($b64_png);

How to get and save THIS transparent image with PHP

I am trying to get a image from a URL, and then save it to the server. It is a simple task, yeah, but this image has transparency... The thing is, when i save that file to my PC or when I try to get and save it via PHP to my server, then I get the same result: the image gets all messed up with its transparency set to black. The URL of the image is:
http://cellufun.com/p/avatarimage/agb.aspx?i=Body|M04001|Shirt|M10020|
Another weird thing is my browser says the image is MIME Type image/png but I can't use imagecreatefrompng(); because I get the "image not a valid PNG" error...
Here is my code (I did try other solutions, this is what I tryed the last time):
<?php
$result=file_get_contents("http://cellufun.com/p/avatarimage/agb.aspx?i=Body|F04001|Shirt|F10020|Pants|MO55|");
$img = imageCreateFromstring($result);
imageAlphaBlending($img, true);
imageSaveAlpha($img, true);
imagecolortransparent($img);
header("Content-type: image/png");
imagepng($img);
?>
Oh, and I just tryed this image against the copy() function, and still get the same result... It looks like the image is smaller in size then the original image...
Just tryed this:
file_put_contents("files/test.png",file_get_contents($result));
and still not working... so it has something to do with the image itself, because whatever i try to get the data, it does not work.
Try this code (changes at lines 2-4):
<?php
$img = imageCreateFromgif("http://cellufun.com/p/avatarimage/agb.aspx?i=Body|M04001|Shirt|M10020|");
$index = imagecolorexact($img, 0, 0, 0);
imagecolortransparent($img, $index);
header("Content-type: image/png");
imagepng($img);
?>
It works for me although it's a little trick ;) ..and I don't know exactly why the quality is worse..
PS: The main problem I see is that the image at the url you provided is not really a png.

imagepng Very Slow

I have a .php file that's supposed to load an image for display in an img tag(i.e., <img src="the_file.php?which=0"/>). It looks like this:
<?php
ob_clean();
header("Content-type: image/png");
include_once("util.php");
//Do a simple calculation to get $name from (int)$_GET["which"];
$im = imagecreatefrompng("protected_directory/".$name.".png");
imagepng($im,NULL,0,NULL);
imagedestroy($im);
ob_end_flush();
?>
It works correctly, but the image loads substantially slower than just loading it directly(i.e. <img src="protected_directory/the_name.png"/>, where "the_name" was calculated the same way as in the PHP file, but I can't just do this because the protected_directory isn't world readable).
My question is, why is this suddenly so much slower? It's not a large image, but nor is it terribly small.
If you're just displaying an existing file, use readfile() to output it to the browser. There's no need to go through all the overhead of creating an editable GD object for this.
imagepng is known to be slow, if you need to output images with a PHP script, use code like this:
$filename = md5(time() . mk_rand());
imagepng($im, $filename);
echo file_get_contents($filename);
As another answer, I figured out that you can use the third parameter to compress the image (PNG uses zlib). Setting it to 9 works about as well as the other solutions.

working with image from imagecreatefromstring PHP

So i have an iphone app that that uploads an image to my webserver and i looked around and people seem to be doing something like
$data = file_get_contents($_FILES['file']['tmp_name']);
$image = imagecreatefromstring($data);
header('Content-Type: image/png');
imagepng($image);
imagedestroy($image);
I looked at the php docs, but i still don't understand what the header() does; does it convert the image into whatever format i want?
And for the imagepng(), where is the image outputted to? memory? is that why i need the imagedestroy()?
and where would i put in
move_uploaded_file()
Thanks in advance!
This code is intended to return as output an image - you could use it as a valid src for an image tag. That is, you could do this:
<img src="thatfile.php?something=1" />
The headers tell the browser that the data the server is going to send is an image (a PNG image, specifically).
In your example code, the file never actually gets written anywhere: the data stays in memory until the script ends, then it is simply "forgotten". imagedestroy frees up the memory and is good practice, but it really isn't necessary since the memory will be garbage collected after the request ends. If you want to preserve the image in a file, you'd have to use one of the related functions such as imagepng: http://www.php.net/manual/en/function.imagepng.php. The only difference between writing the file or not in your example code is the lack of a second argument for imagepng - second argument would be the desired file path.
It would help to read through the docs on this entire subject to gain a firm grasp of how these functions work and what each does. There are plenty of demos on the doc pages that show this in action.
This particular example gets the image uploaded through POST from the $_FILES array and simply outputs it back to the browser. The header is there to inform the browser that the content following is a PNG image.
Since you create an image from a string, it doesn't have "an extension". It's just an image resource at this point. You can create an actual file from it using imagepng, imagejpeg or any of the other methods to save an image resource to a file. You decide the extension (and file name) at that stage yourself.
E.g.:
imagepng($image, 'path/to/file.png');
and where would i put in move_uploaded_file()?
You wouldn't, since you don't have an uploaded file, only a string.
Header is purely for the server to let the browser know "Oh hey this is a png image please render it so"
imagepng encodes it into the png format and "prints" to the output
imagedestroy frees the memory taken by the image resource.
If you need to force extension you can use mod_rewrite
Here's a sample couple lines from my .htaccess:
RewriteEngine on
RewriteRule images/000000/00FF00/newmyinfo.jpg images/newmyinfo.php?bgcolor=000000&color=00ff00 [L]
Hope this helps!

how would i make a dynamic image?

I have a online.png and a offline.png
My idea is to do serverstatus.php?sid=1
then have it check if the server is online or not, i know how to run the checks for that.
Then have it return the online or offline image with the mime type of png but really a php file and show up like a image. No text or anything added to it. just the original online or offline png. So it can be used for img tags.
From PHP documentation at http://php.net/manual/en/function.imagepng.php
<?php
$im = imagecreatefrompng("test.png");
header('Content-type: image/png');
imagepng($im);
imagedestroy($im);
?>
You can use the imagecreatefrompng function

Categories