given an image file path, I want to get its content - than add metadata to that content (either EXIF, IPTC, XMP etc.) and then display that image's content, with that metadata included (probably in base64 format), in an HTML tag without saving the file.
why without saving the file on server? the action I'm trying to perform is for a case a user saves the image file to his computer, for copyright purposes - I want his IP and the my site's URL to be stored in the metadata of the image he downloaded.
there will be thousands of users viewing the image in a minute so I cannot create temporary copies of this image on server.
I can generate either a JPEG or PNG format image - any format needed in order to make it work.
I currently know how to store IPTC meta data in a JPEG image using PHP's "iptcembed" but of course that stores (saves) the file.
I know you said you cannot create temporary files, but there is a manual temporary file that you delete yourself, and a PHP managed temporary file.
Have a look at tmplfile(), which allows you to save the file on the server but it will be cleared once the request is done.
Then you can do all the things you need, then get the content of the tmpfile as base64 and return that content. The file will be gone afterwards, so more or less it happened in memory per request.
I somehow missed the fact that the third argument of iptcembed, "spool", can do the job:
Spool flag. If the spool flag is less than 2 then the JPEG will be returned as a string. Otherwise the JPEG will be printed to STDOUT.
I tried it with the various options and it worked for me.
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 am working on a PHP web application in which I have to introduce a cache layer over my database.
Specifically to store images in the cache layer taken from the db, the images are large in size: 4-8 MP. What would be the best way to do this? What data sources should I use?
Here's a suggestion for a scheme:
Create three folders - thumbnails, display images and original images. In these you'll store cached versions of thumbnails, resized versions for web display, and your original image.
When an image is uploaded assign it a unique name in your file system and store it there. Store the original name and the unique name in your database, along with any other pertinent information.
Assuming you have some sort of image browser to select from these images...
Retrieve image data from the database. Use that to locate thumbnails, display versions or originals.
When an image is browsed look for an existing thumbnail. If you have one, send it. If you don't, create one, store it in your thumbnails folder, and send it.
When an image is enlarged for display in the browser, check for a display version, etc. as for thumbnails. Use a resized version for display since 4-8Mp is a lot of data to send just for a web browser.
When an image is selected for download, send the original.
You need to be careful with cache-control in all this - PHP output won't automatically be cached, so you need to add the headers yourself. Doing this properly can dramatically speed up your application.
You can play with this to add sub folders if that's justified, adjust the size of your cached resized images, etc.
Good luck!
First of all as suggested by everyone storing images in DB is not a good idea... I think here by "Caching Layer" you mean not to fire a query to database if image is already present in filesystem.. if thats the case ...
Keep all the final images which you have created from using script in a directory. Then use a rewrite rule which serves the image if present, otherwise pass off the creation to PHP.
More explanation..
http://www.sitepoint.com/forums/showthread.php?719010-PHP-image-caching-in-server
First off designate a directory for your cache to live in ... this should be writable by the web server.
Then map your request parameters to a filename in that directory.
$filename = $_GET["id"]."_".$_GET["width"].".jpg";
Then you will basically follow this pattern.
if (!file_exists($cache_dir.$filename)){
// do your db query get the image and resize it to the width and then
// save it to $cache_dir.$filename
}
header("Content-Type: image/jpeg");
header("Content-Size: ".filesize($cache_dir.$filename));
readfile($cache_dir.$filename);
You may also want to add a check to see if the cache record has expired (time vs modified time) along with the file_exists check.
To manually flush something from the cache you can just delete the files from the cache directory and they will be regenerated, you may want to perform this when a database record is updated with a new file to keep the cache up to date.
I have a page that is generating image data urls from a snapshot tool and inserting the resulting string into a MySQL database via PHP. Later on I have a page that takes and uses those images. This would be fine except I need to save the resulting html to my server for some post processing and the length of the image data urls is giving me a headache and making the html files upwards of 8 to 10 MBs which slows down the entire process. The image looks something like this:
<img src="data:image/png:base64,iVBORw0K43+gAA4u...">
Where there is an extremely long string of characters making the resulting html very large. Is there a way to host this on my server as a png so the link is a normal looking image? Something like this:
<img src="http://www.mysite.com/image1.png">
What about converting base64 to an original image, what you would be doing is saving the image as a actual file to the server.
Php to convert base64 data to image
function toImage($base_code){
$img_file = imagecreatefromstring(base64_decode($base_code));
imagejpeg($img_file, 'new.jpg');
}
Calling the function
echo toImage($encoded_image);
Make sure to only pass the base64 encoded string without the image tag
You can save the files elsewhere, but my guess is that you've got a requirement the images exist in the DB. If you save the files elsewhere, you've just doubled your disk requirements.
In any case, the general fix for this would be to save that image string to disk, and in your DB keep track of the path. Then when you generate the HTML, you'd use the path in the DB, rather than the binary data in the DB.
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 am storing images in mysql Db directly. what is the best way to display the image in good quality (thumbnail and original size images) using php.
So, you are storing the binary content of a image files in your database (probably a BLOB field), right?
Displaying the original size image is not a big deal, I hope you have stored the file name / file extension (or at least mime type) of the original image along with the binary data.
If you table images e. g. contains two, content which holds the binary data and file_name which holds the file name and file extension of the stored image, you can think of code like this:
$res = mysql_query("select * from images");
while($row = mysql_fetch_assoc($res)) {
$pathname = 'some/path/' . $row['file_name'];
file_put_contents($pathname, $row['content']);
}
What this does is selecting all entries from the images table and writes the binary content from the database to an outfile named after the orignal image. Consider setting the [chmod][1] after writing the outfile, depending on your server setup.
If you dont have the file name property available, then you must generate some random name (maybe using md5($row['content'])? Could be very slow though.). But you need the original file extension or the mime type of the stored image, otherwise its not easy to find out if the image is abc.JPG or abc.PNG or abc.GIF etc.
Now you can access your created image (e. g. XYZ.jpg) using http://www.domain.com/some/path/XYZ.jpg if some/path/ is within your document root folder.
With the original image stored on disk it is easy to create a thumbnail. I heartly recommend Imagemagick (check if installed on your server), but you can also roll your own thumbnail script using PHPs GDLib which is bundled with PHP and most likely available. There already a ton of prebuilt thumbnail scripts for PHP which rely on Imagemagick and/or GDLib. I havenĀ“t tried yet but heard good things about phpThumb().
One last word: you probably noticed it yourself, storing images as binary in a database is not really a good idea. Of course, if the application is already built and you have to work with things the way they are, you dont have a choice on this. But performance-wise it is way better to store just the image pathname in the database along with some meta data (like filesize, width, height etc.), keeps your db size down and the select/php code for processing the resultset fast.
The best way to display the image in good quality (thumbnail and original size images) using php is storing both original image and thumbnail in the filesystem and then generate an <img> tag to display it.