I'm currently teaching myself PHP's GD library, and I have a question about image types. Do certain GD functions only apply to certain image types, like jpegs for example? I'm not very knowledgeable about image types. I am wanting to learn their differences and if I should be a little more careful about the functions I'm using or am I just overthinking this stuff too much?
In memory, an image is just plain bitmap data. The only time an image type becomes involved is when loading an image from a file (it has to know what type so that it can decode it into an in-memory bitmap) and when writing the file to disk (same thing, in reverse).
Only the imagecreatefrom...() and the converse "save" functions are format-specific. Once loaded, they're in a gd-specific internal format.
That being said, some GD functions don't make sense in certain contexts. e.g. JPEG images don't support transparency, so specifying an alpha channel on an image that'll be saved to .jpg isn't very useful. But internally within GD, alpha-involved operations will still function as normal.
Related
I would like to create PNG images using PHP on a website. These shall be printed at a defined scale. So I would like to set the DPI value of the images using PHP directly. Unfortunately I did not find any function call for this.
Is there any function that can set/update metadata of PNG files?
Maybe an other solution is more reasonable as using a HTML-Wrapper with CSS style sheet for printing which externally defines the resolution. But I would prefer the "directly on the image" approach...
PNGs can contain arbitrary headers. If you look at the PNG specification, you can add tEXt blocks (which are called chunks) to a given PNG. See section 4.2.3 of the specification for more information on tEXT chunks.
As an example, Adobe Photoshop adds meta XML to its PNGs. I'm not sure if GD supports this, but I'd look there to start. It's definitely possible.
Here is some PHP code that deals with parsing PNG chunks. It might steer you in the right direction. http://code.svn.wordpress.org/imagelibs/libpng.php
Here's an screenshot for a text editor of a PNG, showing the XML that was generated by Photoshop. https://stackoverflow.com/a/14356339/278976
THe pHYs chunk (Physical resolution) lets you set a DPI (well, actually pixels by meter, but it's just a unit conversion). Of course, the PNG reader might ignore it.
PHP does not include (AFAIK) support for reading/writing full PNG metadata, you must do it yourself, see eg
The easiest way is to use ImageMagick, as suggested in this answer. If You want to set PNG resolution in pure PHP, you may look at my answer to the similar question.
I've been doing some speed optimization on my site using Page Speed and it gives recommendations like so:
Optimizing the following images could reduce their size by 35.3KiB (21% reduction).
Losslessly compressing http://example.com/.../some_image.jpg could save 25.3KiB (55% reduction).
How are the calculations done to get the file size reduction numbers? How can I determine if an image is optimized in PHP?
As I understand it, they seem to base this on the image quality (so saving at 60% in Photoshop or so is considered optimized?).
What I would like to do is once an image is uploaded, check if the image is fully optimized, if not, then optimize it using a PHP image library such as GD or ImageMagick. If I'm right about the number being based on quality, then I will just reduce the quality as needed.
How can I determine if an image is fully optimized in the standards that Page Speed uses?
Chances are they are simply using a standard compression or working on some very simple rules to calculate image compression/quality. It isn't exactly what you were after but what I often use on uploaded images etc etc dynamic content is a class called SimpleImage:
http://www.white-hat-web-design.co.uk/blog/resizing-images-with-php/
this will give you the options to resize & adjust compression, and I think even change image type (by which I mean .jpg to .png or .gif anything you like). I worked in seo and page optimization was a huge part of my Job I generally tried to make the images the size the needed to be no smaller or bigger. compress JS & CSS and that's really all most people need to worry about.
It looks like you could use the PageSpeed Insights API to get the compressions scores: https://developers.google.com/speed/docs/insights/v1/reference, though I'm guessing you'd want to run a quality check/compression locally, rather than sending everything through this API.
It also looks like they've got a standalone image optimizer available at http://code.google.com/p/page-speed/wiki/DownloadPageSpeed?tm=2, though this appears to be a Windows binary. They've got an SDK there as well, though I haven't looked into what it entails, or how easy it would be to integrate into an existing site.
I have a lot of jpeg images which I want to optimize for web but I need a process which can also be done for incoming images in real time. In other words I don't want to use a service like Smush.it or drop them into photoshop for manipulation but I do want to know what I can do in php. I would prefer a solution which only requires php image processing functions but if necessary and it would provide significant improvement then a command line tool like jpegcrush could be used as well.
I have read that simply by making the image in php the EXIF data is stripped. What other things can I do without degrading the actual quality? When I save in photoshop using the 'save for web' feature, the savings are significant without a noticeable quality loss so I was wondering if anyone knew exactly what operations are done in there. One other thing I have noticed is that images from youtube are normally much larger area-wise than they need to be but they have very small file sizes... does anyone know what is going on there or is this some secret technique?
If it makes any difference the images I am working with are mostly 320x320 and I want to make them progressive jpg. Thanks in advance.
I'd use the PHP GD library to create a jpg with quality set to around 80:
imagejpeg ( resource $image [, string $filename [, int $quality ]] )
If you want to output Progressive JPEGs, you need to set interlacing on with imageinterlace().
Are you looking for something more than this?
Assuming "optimizing for the web" is converting to GIF, PEAR does it if i'm not mistaken. You don't need fancy functions to do this.
check this question:
Convert jpg image to gif, png & bmp format using PHP
I want my site to have a feature for users to upload images, but I want to do it safely. Namely, I want to strip the EXIF data and any malicious code that could be in their image. I was thinking of a way to do this involving direct manipulation of the file, but it struck me, would it make more sense to just convert the image they provide to BMP and then convert that back to the original format? It would suffer a generational loss, but I believe that would meet my project's requirements. BMP doesn't contain EXIF, does it? And the reprocessing should strip any malicious content.
It wouldn't even have to be BMP: You could use PHP's GD functions, open the image using imagecreatefrom[xyz], copy it unresized, and write it back out in the original format.
That should be pretty watertight, save for the remote (and negligeable) possibility of course that a vulnerability is one day discovered in GD itself.
Limitations and caveats I can think of:
Images with transparency may be an issue, especially transparent GIFs would probably require special treatment (allocating the transparent colour in the new image etc., not sure)
Animated GIFs would be destroyed this way, GD can't deal with them
This method would be limited by PHP's memory limit (you'll need at least {image width} x
{ image height } x 3 bytes for the resize operation)
More exotic sub-formats like progressive JPG, CMYK JPG may cause trouble, but that's okay IMO - the latter woulnd't show in IE anyway
I am working on a project that resizes images using PHP. This project utilizes PEL to copy EXIF data from the source image to the resized image. However, when resizing images to be really small, the embedded EXIF data contains a thumbnail that is actually much larger than the resized image itself. I would love to use PEL to remove this thumbnail from the EXIF data while keeping all of the other goodies. Any ideas?
I'm sure there are other ways but the simplest way I can see from here is to read the file in using GD, output a new image and copy the EXIF across. This is by no means a simple process but if you're already doing resizing, it would make some sense.
PEL is a bit stale. If you're doing this on any real scale, you might want to look at playing around with some simple Python scripting. You have access to much better graphics and EXIF libraries and you can cron the script to run on a set period... Though I admit this might not suit your website's image processing flow.
You would need to use an image processing library, imagemagik (imagik) or gmagik would work.
Basically you would grab all of the info you wanted via exif then use $image -> stripimage() to remove ALL the meta-data, including the thumbnail, then use gmagic again to take the data you pulled out via exif to add it back in. ($image -> commentimage for example).
The only catch is that none of the documentation specifies whether the image will be re-added as exif, or some other meta-data type.