I have a database that stores images in a MySQL BLOB field. I setup a script that selects and displays the images based on an ID in the URL, and I also made it so if you append ?resize=800x600, it would resize the image (in this case, to 800x600).
The host that I use doesn't have Imagemagick installed and won't let me do it myself, so I need to use PHP's GD library to resize the image.
But I've yet to find a function like Imagick's readImageBlob(), so I can't edit the binary string that I get from the database without first creating a temporary file, editing it, getting the binary string from it, sending it to the browser, and then deleting it (which is waaaay too many steps, especially since this will be getting a few thousand hits when it goes into production).
So my question is, is there any way to replicate readImageBlob with PHP's GD without going through the temporary file solution?
imagecreatefromstring() should do the trick. I think the function example in the manual is almost exactly what you need:
$im = imagecreatefromstring($data);
if ($im !== false) {
header('Content-Type: image/png');
imagepng($im);
imagedestroy($im);
}
else {
echo 'An error occurred.';
}
Where $data is your binary data string from the database.
Related
We use PHP-cURL to download images from the web for one of our apps and sometimes the image downloads partially due to a timeout. Here is what a partially downloaded image looks like
I am wondering if there is any way to detect this using PHP? We don't see any errors as far as cURL is concerned.
Any imagick commands for example that can be used?
I realise this is an old post, but I stumbled upon it when I had the same issue.
I wrote this php code to check if the image file is valid:
function imageIsValid($local_path)
{
$im = imagecreatefromjpeg($local_path);
$valid = !!$im;
imagedestroy($im);
return $valid;
}
This works because imagecreatefromjpeg will return nothing if the image stream is corrupted.
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);
I'm wondering if there is someone who can help me with this, i'm sending an image from my windows phone c# to php and i want to save the image.
The data connection works and i can receive the POST value
see: http://posttestserver.com/data/2014/01/23/19.41.40516059397 for the information the server receives.
i now want to save this base64 encoded RGBA string to a png or jpg (i would prefer png but i dont need the alpha value).
this is the code i have server side
//getimagecontents
$data = base64_decode(file_get_contents("php://input"));
//create an image from string
$im = imagecreatefromstring($data);
if ($im !== false) {
//add an header for the image
header('Content-Type: image/png');
//save the image
imagepng($im, 'upload/test.png');
imagedestroy($im);
echo "it worked!";
}
Hopefully someone can help me with this coz it's keeping me up all night :(
Thanks in advance :)
Make sure that you are receiving the data. If yes. then try once without base64_decode and upload directory is created in place that is where your image will be saved. If it is not created, you can not save image.
You should have received warnings in both cases indicating the problem. If this your dev environment, turn the warnings reporting on in php.ini or your script.
Another thing, why are you sending header for image when only you intend to save it to file system.
The image i was sending was too big for the server to handle...
As it was send as a RAW file...
converted it to a png and now works like a charm
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!
I'm building a basic analytics service, based in theory off of how Google Analytics works, but instead of requesting an actual image, I'm routing the image request to a script that accepts the data and then outputs an image. Since browsers will be requesting this image on every load, every millisecond counts.
I'm looking for the most efficient way for a file to output a gif file from a PHP script. So far, I've established 3 main methods.
Is there a more efficient way for me output a 1x1 GIF file from within a PHP script? If not, which of these is the most efficient and scalable?
Three Identified Methods
PHP image building libraries
$im = imagecreatetruecolor(1, 1);
imagefilledrectangle($im, 0, 0, 0, 0, 0xFb6b6F);
header('Content-Type: image/gif');
imagegif($im);
imagedestroy($im);
file_get_contents the image off of the server and output it
$im = file_get_contents('raw.gif');
header('Content-Type: image/gif');
echo $im;
base64_decode the image
header('Content-Type: image/gif');
echo base64_decode("R0lGODdhAQABAIAAAPxqbAAAACwAAAAAAQABAAACAkQBADs=");
(My gut was that base64 would be fastest, but I have no idea how resource intensive that function is; and that file_get_contents would likely scale less well, since it adds another file-system action.)
For reference, the GIF I'm using is here: http://i.stack.imgur.com/LQ1CR.gif
EDIT
So, the reason I'm serving this image is that my analytics library builds a query string and attaches it to this image request. Rather than parse logs, I'm routing the request to a PHP script which processes the data and responds with an image,so that the end user's browser doesn't hang or throw an error. My question is, how do I best serve that image within the confines of a script?
maybe
header('Content-Type: image/gif');
//equivalent to readfile('pixel.gif')
echo "\x47\x49\x46\x38\x37\x61\x1\x0\x1\x0\x80\x0\x0\xfc\x6a\x6c\x0\x0\x0\x2c\x0\x0\x0\x0\x1\x0\x1\x0\x0\x2\x2\x44\x1\x0\x3b";
That will output a binary string identical to the binary file contents of a 1x1 transparent gif. I'm claiming this as efficient based on the grounds that it doesn't do any slow IO such as reading a file, nor do I call any functions.
If you want to make your own version of the above hex string, perhaps so that you can change the color, you can use this to generate the php code for the echo statement.
printf('echo "%s";', preg_replace_callback('/./s', function ($matches) {
return '\x' . dechex(ord($matches[0]));
}, file_get_contents('https://upload.wikimedia.org/wikipedia/en/d/d0/Clear.gif')));
header('Content-Type: image/gif');
header("Content-Length: " . filesize("image.gif"));
$f = fopen('image.gif', 'rb');
fpassthru($f);
fclose($f);
Probably would be fastest for image from disk, but (especially if you're using bytecode caching) for a small images known in advance the base64 way will be the fastest I think. Sending Content-Length might be a good idea too, for the small image the browser would in most cases not wait for anything after receiving the bytes so while your server would take as much time, use experience will be sightly better.
Another way would be to let Apache/lighttpd/nginx serve the image, log the access and the parse it offline.
With Laravel:
$pixel = "\x47\x49\x46\x38\x39\x61\x1\x0\x1\x0\x80\x0\x0\xff\xff\xff\x0\x0\x0\x21\xf9\x4\x1\x0\x0\x0\x0\x2c\x0\x0\x0\x0\x1\x0\x1\x0\x0\x2\x2\x44\x1\x0\x3b";
return response($pixel,200,[
'Content-Type' => 'image/gif',
'Content-Length' => strlen($pixel),
]);
If anyone wants that for some reason.
Alternatively, if you don't like long(ish) hex strings in your code:
base64_decode('R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw')
Instead of dynamically generating/outputting an image, why not just redirect to a static image?
<?php
// process query param stuff
header('Location: pixel.gif');
exit();
?>