I have an image resource that is manipulated with imagecopyresampled. I need to pass that image to a set of methods that expect a string input, not a resource. But I don't need to store the file locally.
Is this the proper way:
Store the image with imagepng and imagejpeg
Pass string (filename) to the methods
Destroy the stored file with #unlink
Is that right? Seems sloppy.
Note: the image is not coming from a file upload and hence can't be accessed with $_FILES["Filedata"]["tmp_name"]
I took a look at the Amazon S3 PHP API:
http://docs.amazonwebservices.com/AWSSDKforPHP/latest/index.html#m=AmazonS3/upload_part
I assume you are using something like the upload_part method that takes a string filename. In that case, unless you plan to modify their library, you will need to store the file to disk and pass them the filename so they can read the file and perform the upload.
Besides the steps mentioned in your question you can take a look at imagedestroy to make sure you are freeing up the memory for your image resource after it is written to disk with imagepng. And then, as you stated, you can delete your temp file with unlink after your upload is complete.
I agree, it does seem a bit wasteful, but in this case necessary since the API doesn't seem to provide an alternative.
Related
I created an image class, it loads and resizes image, then crops and lastly watermarks it.
For last step, I would like to add IPTC data to the this image. For what I know there is only iptcembed function to accomplish this. The problem is iptcembed needs the path of image as parameter. I'm keeping image as object before using it to render views.
$content = iptcembed($data, "./image.jpg");
I do not want to save image to storage just to create a path for iptcembed but I couldn't find another way to add IPTC data to the image.
Is there any way (or function) to access to this object from memory instead of saving and loading from storage?
You could use php://memory to have a file handle that reference in-memory data instead of data written to a file.
Credit goes to this original answer
I use CFX_OpenImage to read and write IPTC_ data in .jpg files using ColdFusion Language versions 8 thru 11. I also use CFX_OpenImage for image resize and rotation.
For more CFX_OPENIMAGE INFO go to http://www.kolumbus.fi/jukka.manner/cfx_openimage/
The software download includes a good manual of at least 65 pages.
I'm working on a PHP project, and I record Images DATA URI in a table called "Images", the thing is that that long string takes lot of place for nothing so its heavy to load.
My questions :
How can I resize a Data URI image using PHP (knowing that the input and output wanted will be both DATA URI)
Is there any function or something alike that can compress the DATA URI before put it on my MySQL Database ? (Compress decompress)
There is a library that will do this, you can get it here.
If you want to roll your own solution, PHP allows you to open data URIs with the various file* functions. If you don't mind saving the file to disk while you work on it, you can just do this:
$fileName = md5($dataURI);
file_put_contents($fileName, file_get_contents($dataURI));
Then you can use your preferred image processing library to manipulate the image. To send it again as a data URI, you can use the technique outlined here. Then, delete the temporary file and you're done.
I am wondering what the difference between $_FILES["file"]["type"] and end(explode(".", $name), as well as an appropriate method to determine if the retrieved file type is really the correct content of the file.
For example, what's the best way to sort a file that was named "image.exe" and renamed "image.jpg."
I've seen a lot of talk about MIME types, but it seems that method has been deprecated.
This is the correct way to read an extension:
$ext = pathinfo($name, PATHINFO_EXTENSION);
The correct way to check if something is an image is to try and read it with an image tool, such as imagemagick or GD. GD is easier, but imagemagick is better at handling big images, such as one uploaded from a 12 megapixel camera.
If you're worried a jpg is really an exe, the only way to safely process it is to read it as a jpg and try to create a new jpg (typically resizing it at the same time). Gmail does this with image attachments.
Also beware a real jpeg might have some kind of exploit, so even if it is an image it is not safe to just pass it onto the user anyway. You really should resize it to create a new "safe" jpeg and then give that to the user. You could make a new jpg the same size if you want, but passing the original data on to other users is dangerous.
I wouldn't even allow an admin user for your website to access a jpg uploaded by a random internet user. It could be used to hack into the admin's PC.
$_FILES["file"]["type"] is supplied by the user's browser and hence useless for security.
The file extension, as you note, is easy to fake as well.
If you want to make sure an image is an image, the easiest way is to run getimagesize() on it.
If you want to make super sure and remove any and all metadata possibly embedded in the image, use GD's imagecreatefromstring() to copy the image to an empty canvas (but be prepared for a possible slight loss in quality.)
For other file types, there apparently is the Fileinfo library now. It uses the underlying Operating System's mime.magic file to estimate a file's type by checking certain characteristics and "header bytes" in the file.
If you're just working with image files, then getimagesize() should do it:
http://www.php.net/manual/en/function.getimagesize.php
It will return the image type as an element of the array it returns or FALSE if the file is not a valid image.
Beware of double extensions when using end(explode(".", $name).
Apache will read the right-most extensions if 2 extensions are given which map onto the same meta information. E.g. file.gif.html will be associated as an html file.
As stated above, the client-provided browser info is useless as a security measure.
Best bet - getimagesize();
As with everything, there are ways around it. A malicious code comment could be added to the picture that bypasses the getimagesize() check because the header is still valid
PHP ships with various methods of identifying the type of a file, but is it possible to identify a data type when the file in question only exists as a binary string representation and not as an actual file on disc?
The reason for this is I'm doing some maintenance work on a CMS where the previous developer, being a bit of a wally, decided to store image data into the system as database BLOBs. My current project is dumping the BLOBs out into files, and saving the path to the files into the database in place of the BLOBs.
As I said, my predecessor was a bit of a wally and not only did he store all this data as BLOBs, he also didn't save the datatype of the data anywhere.
The migration utility I wrote for part of this project saves the file to disc without an extension, tries to determine the type of the file with exif_imagetype() and if it manages to identify the file type, renames the file with the correct extension.
However, the classes that use the image data also need updating so they can continue to function with paths and files on disc instead of BLOBs.
The methods that create and update images expect binary strings (to BLOB into the database) and in an ideal world I'd rather rewrite these methods to use is_uploaded_file, move_uploaded_file, etc. However, there's no evidence anywhere in the class of direct manipulation of the $_FILES array so the filedata obviously comes from outside the classbut given how convoluted the code is (and no comments to help out) I can't find it.
As a stopgap solution until I finally track down the actual file upload management code, I plan to manipulate the file data as strings in the class as is currently done, but saving the strings to files instead of into the database. This should minimize the impact on other parts of the codebase that are relying on this class.
I could just do what the migration script is doing and rename the file after saving and then identifying it, but this could prove problematic in the case where there is already a file there. I'd rather know what the data type is before I commit the data to disc.
finfo_buffer() is what you want. You can pass it your string and it will tell you what the file type is based on your mime.magic file.
More info here: http://us3.php.net/manual/en/function.finfo-buffer.php
You can use finfo_buffer. It works on strings rather than on-disk files.
If you are working only with images, you can find the filetype looking in the first few bytes of the string - PNG files begin with 0x89 0x50 0x4E 0x47 0x0D 0x0A 0x1A 0x0A, GIF - with GIF, and JPEG contains FFD8 in the header. I've wrote script for parsing headers of those 3 types, but since I don't have it here, I'll update my answer as soon as I get it
I'm currently using a simple $_FILES upload script to upload pictures from my iPhone app to server. The image sizes, however, are large and I'd like to resize them before sending the image to the server.
The downside of this, however, is that the resize function converts them to "blob" images (which, as I understand it, is a way of storing the image in the database). I'd prefer to save the files directly to the filesystem. How would I go about converting a blob back into a $_FILE or finding a script that saves blob images to disc??
Thank you!
The BLOB is the binary image. You can write that image to your filesystem once it's on your server. So if your image is in the variable $my_blob, you would do something like
file_put_contents('/path/to/new/file_name', $my_blob);
and there you go.
You might want to save the file to a tmp location first, then do some checks on it before you move it to a final location (with PHPs rename() function).
Btw: why not just save the BLOB to DB? That is a legitimate way of handling files these days, that's what the BLOB MySQL data type is for after all.
Try just writing it to a file with an image/[fill-in-the-blank] mimetype. Or maybe imagecreatefromstring will work. (NOT sure about any of these)
Or you can find another way to resize the images.