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!
Related
I'm working on setting up a simple pixel tracking script with PHP, and the below technically works, but when I look at the inspector in Safari I get the following warning (1by1.gif is a 42B gif):
esource interpreted as document but
transferred with MIME type image/gif.
header("Content-type: image/gif");
header("Content-Length: 42");
echo file_get_contents("/path/to/1by1.gif");
// do tracking stuff below here
I've looked at other tracking pixels, and they all show in the inspector as if they are an actual image, even with the .php extension. Any ideas how to fix that warning?
EDIT:
I tried doing the following and I get the same warning:
header("Content-type: image/gif");
$img = imagecreatefromstring(file_get_contents("/path/to/1by1.gif"));
imagegif($img);
You could write 1x1.gif (or some other made up name) in your HTML source and then have Apache actually serve the PHP script. You can do this with .htaccess with something along the lines of:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^1x1\.gif$ tracking_script.php [NC,L]
This way Safari sees the gif extension and won't complain.
Well this is interesting. If I remove the content-length and just use the following, it appears to work perfectly. Anyone know why that might be?
header("Content-type: image/gif");
echo file_get_contents("/path/to/1by1.gif");
// do tracking stuff below here
I'm a puzzled. Function file_get_contents() is for getting content from a text file. What is your intend here? The function returns the content as string or false. Your echo statement essentially transfers that result which is correctly interpreted as document and not a gif.
Update: Took me a while to even reproduce this and see the warning. Echoing the file_get_contents() shows indeed the gif in the browser, so does a simple include() which also shows the warning. Does this warning causes you any trouble or is this just for a beauty contest? I can only speculate that the Safari's Inspector is a little picky. The same tool in Chrome does not show a warning.
$img = imagecreatefromstring(file_get_contents("/path/to/1by1.gif"));
imagegif($img);
This code
Reads in a GIF image
Passes the image bytes to GD
Asks GD to write a new image.
Many things could go wrong here. For example, writing the image back out might not produce the same exact stream of bytes, maybe more, maybe less. This could make your Content-Length header invalid, and browsers don't like it when you lie about such stuff. Or maybe there's a Notice or Warning in one of the lines, which would be emitted as content before the GIF data. That would certainly look like a "document" instead of as image data to Webkit.
Serving the file through file_get_contents / include / echo eliminates the filter-through-GD step. If the code works properly without that step, the error was somewhere there.
I am using following code to render a JPEG file, which is on disk, through the imagejpeg function:
//.... some headers....
$image = imagecreatefromjpeg($the_file);
imagejpeg($image);
Now, problem is, imagejpeg compresses the image (reduces the quality in my case) and does not output the same file. I know I can control the quality through a parameter, but it seems that imagejpeg does jpeg encoding/decoding. I don't want that (seems a waste, as the file is already a jpeg file). I want a simple function that will just "RENDER" the image (which is what I thought imagejpeg did till now). Can someone tell what to use?
You could use the readfile() function, to read the file from the disk, and output its content -- without doing any manipulation / transformation on it.
Last week I converted my page img src values from pointing at image files to using a PHP script to serve up the images. The primary reason was to accommodate both files and database BLOBs as the actual source.
Now when a user goes to a page, sometimes images show and sometimes not. If not, and the page is refreshed\reloaded, then the image appears. When images do not appear, sometimes it is an image the user has already accessed previously today.
I am stumped.
Here is the img tag:
<img src="../somedir/image_script.php?i=1234">
The image_script.php file figures out where to get the image from, then finishes up with:
header("Content-type: image/jpeg");
if($from_db){
print $image_blob;
} else {
$im = imagecreatefromjpeg($image_file);
imagejpeg($im,null,100);
imagedestroy($im)
}
I am using PHP 5.2.8 on IIS 6 using FastCGI. There are no cache headers on the image_script.php file nor on the directory it is in. Currently 99.9% of the images are file based, so I do not know if there is a difference in result between db-based and file-based images. When I go directly to image_script.php in my browser it returns the requested image (i=????) 100% of the time.
a> Any clue as to why the hit and miss with images being displayed? and,
b> what would be a proper way to actually cache the images served up by the PHP script? (they are very static)
Scott
Hmm. Can't tell for sure, but maybe your imagecreatefromjpeg is occasionally running out of memory? In that case, you'd serve an error message out as JPEG data and never see it, right?
Incidentally, wouldn't just grabbing the image file in as a string and shovelling it out without going through imagecreatefromjpeg/imagejpeg/imagedestroy be more efficient? It looks like you're reading a JPEG file, creating an internal PHP memory image from it, then reconverting it to a JPEG (at hefty 100% quality) then serving that data out, when you could simply read the JPEG file data in and print it, like you do from the database.
What happens if you do, say...
...
} else {
header ('Content-length: ' .filesize($image_file));
readfile ($image_file);
}
I am trying to display an image from a MySQL blob field. I have tried a few different things and none of them seem to work.
I have tried:
header("Content-type: $type"); img src = $blobData;
header("Content-type: $type"); echo($blobData);
<?php
header("Content-type: $type");
echo $blobData;
?>
This code looks perfectly OK. However, I heard a similar complain from another person and I was able to troubleshoot it by assuring that:
The php script does not output any extra character before or after sending the binary image data.
The php script is saved as a pure ASCII text file, not as a Unicode/UTF-8 encoded file. The Unicode/UTF-8 encoded PHP files might include a signature as the first bytes. These bytes will be invisible in your text editor but server will send these few extra bytes to the browser before the JPEG/GIF/PNG data. The browser will therefore find the wrong signature in the beginning of data. To workaround, create a blank text file in notepad, paste in the php code and save the file in ANSI encoding.
Another option you might consider (assuming you are on Apache):
Create an .htaccess file with a mod_rewrite for all image extensions (png, jpg, gif).
Have it redirect to a php script that looks up the image requested in the DB. If it is there, it echos out the header and BLOG. If it isn't there, it returns a standard 404.
This way you can have:
<img src="adorablepuppy.jpg" />
Which then gets redirected ala:
RewriteEngine on
RewriteRule \.(gif|jpg|png)$ imagelookup.php
This script does a query for the image, which (obviously) assumes that the requested image has a unique key that matches the filename in the URL:
$url = $_SERVER['REQUEST_URI'];
$url_parts = explode("/", $url);
$image_name = array_pop($url_parts);
Now you have just the image filename. Do the query (which I shall leave up to you, along with any validation methods and checks for real files at the address, etc.).
If it comes up with results:
header('Content-type: image/jpeg');
header('Content-Disposition: inline; filename="adorablepuppy.jpg"');
print($image_blog);
otherwise:
header("HTTP/1.0 404 Not Found");
FYI: I have no idea if this would be bad in terms of performance. But it would allow you to do what I think you want, which is output the image as though it were a flat image file on the server using a simple image element. I'm inclined to agree that BLOBs are not the best way to go, but this does avoid any cross-browser issues.
I believe that the issue that you are encountering is an issue with encoding. This resource claims that you can use the print function.
Just get the image from the database. And print it using the correct headers.
$image = mysql_fetch_array(...)
header("Content-type: image/jpeg"); // change it to the right extension
print $image['data'];
For performance reasons... this is not advisable. There are several reasons to put images in databases but the most common are:
a) keeping them indexed (duh!)
You can do this by storing the images flat on the server and just indexing the image filename.
b) keeping the image hidden/protected
Flickr and alike still store the images flat on the server and use a different approach. They generate a URL thats hard to find.
This link points to a protected image on my account. You can still access it once you know the correct URL. Try it!
farm2.static - a farm optimized for delivering static content
1399 - perhaps the server
862145282 - my username
bf83f25865_b - the image
In order to find all my secret images any user can hard hit Flickr with the above address and change the last part. But it would take ages and the user would probably be blocked for hammering the server with thousands of 404s.
That said there is little reason to store images on BLOBs.
Edit:Just a link pointing to someone that explained much better than I did why BLOB is not the way to go when storing images.
I would like to generate a dynamic image from a script, and then have it load to the browser without being persistent on the server.
However, I cannot call this by setting the image's src="script.php", since that would require running the script that just generated the page and its data all over again, just to get the final data that will generate the graph.
Is there a way to do this that is similar to setting image's src="script.php", but which is called from within another script, and just sends the image without saving it? I need access to the data that is used in the generation of the markup, in order to create this dynamic image.
Or, if not, what is the easiest way to destroy the image once the page is loaded? a quick ajax call?
Is there any way to cache certain data for some limited time frame in order for it to be available to some other script?
Any ideas would be greatly appreciated, as I'm having a really hard time finding the right solution to this...
Thanks!
You can inline the image into a <img> tag if you need to.
Like
<?php
$final_image_data; // Your image data, generated by GD
$base64_data = base64_encode($final_image_data);
echo "<img src=\"data:image/png;base64,{$base64_data}\" ... />";
?>
That should work on all modern browsers, and IE8. Doesn't work well with some email clients tho (Outlook, for one).
Also, another solution I found is to store the image in a session variable which is then called from a php script in the image tag. This would allow a user specific image to be served, and then removed from memory by the script... This also avoids messy img src="" tags...
Hopefully that is helpful to someone.
Use a rewrite rule.
RewriteRule ^magicimage.jpg$ /myscript.php
Then simply echo your image data from gd, instead of writing it to disk -- which is as simple as not providing a filename to the appropriate image*() function
myscript.php
<?php
$im = imagecreatetruecolor($w, $h);
//...do gd stuff...
header('Content-type: image/jpeg');
//this outputs the content directly to the browser
//without creating a temporary file or anything
imagejpeg($im);
And finally, utilize the above
display.php
<img src="magicimage.jpg">