PHP GD issues with ImageCreateTrueColor and PNGs - php

I am resizing PNG images using the GD image library function ImageCopyResampled(). It all works fine, I can even keep alpha blending transparency with the use of ImageCreateTrueColor() rather than using ImageCreate() to create the resized image.
The problem is, that if I use ImageCreateTrueColor() rather than ImageCreate() the file size of PNG files increases from something like 80kb to 150kb. If I use ImageCreate() the file size stays around the same size, but colors screw!
So my question is, how can I retain alpha blending when resizing PNG images without increasing the file size?
Oh and I am reducing the dimensions of the PNGs.

With imagecreate() you're creating an indexed-color PNG file and with imagecreatetruecolor() you're creating a 24-bit color PNG file. Of course the resampling quality is going to appear much better with the true color image, since it has a much larger range of colors to use when resampling. With imagecreate(), the system can only use the much smaller palette.
You can try this out using Photoshop or Gimp, scaling images in the different color modes (indexed and RGB). Unfortunately it's the nature of the game-- the file size will be larger when there are more colors to store.
I'm not sure if it would make a difference, but you could try using imagecopyresampled() to copy to a true-color resource (from imagecreatetruecolor()), then copy (but not resample) that to a palette image resource. This way the palette is determined based on the resampled result. I'm not sure that you'd be able to retain the alpha channel, though.

Related

Are resampled images actually smaller in size than non-resampled images?

When I started working with images in PHP, I learned images should be resized and resampled to reduce file size. I'm taking resizing here to be reducing an image height and width without intentionally altering image quality and resampling to be resizing and intentionally altering image quality with imageconvolution() function. When comparing a group of images of the same dimensions, one resampled with PHP, the other not, I noticed not-so-subtle differences in the file sizes. These are my findings for one set of images, and they were similar to the other sets:
Resampled and Resized Image:
Dimensions: 550 * 366
File Size: 25.19KB
Resized Image without Resampling:
Dimensions: 550 * 366
File Size: 20.89KB
Original Image:
Dimensions: 4896 * 3264
File Size: 1.1MB
The resampled image is 4.3KB bigger than the non-resampled image. This difference is relatively small, but if the resampled image turns out to be greater than the non-resampled image, what then is the importance of resampling? Is this a rare occurrence? Does this only happen to jpeg files?
N/B: I worked with imagecreatefromjpeg, imagecreatetruecolor, imagecopyresampled, and imageconvolution (when resampling).
Changing the size of an image always requires resampling in some form or another. See the definition of resampling at Wikipedia: https://en.wikipedia.org/wiki/Image_scaling#Mathematical. The difference in the final file size is probably entirely due to the different scaling techniques producing visually different images, which compress differently by the final JPEG algorithm. E.g. the larger file contains more details or graininess, which doesn't compress as well. You will have to choose which resizing algorithm and compression format you prefer and balance visual quality vs. file size of the end result.

better to resize before or after layering in GD?

I'm layering a number of png images using GD in PHP and then outputting a smaller version.
Which is more efficient, to imagecopy all of the layers and then imagecopyresampled the composite image onto a blank image of the desired size, or to start by creating a blank image of the desired size and then imagecopyresampled each layer onto the canvas?

PHP JPEG Crop : Loss of quality?

I'm developing a web-to-print, poster printing application.
I'm considering using PHP to crop user-uploaded images, and we will ultimately print the PHP-cropped image.
My concern is there will be a difference in 'quality' between the original user uploaded image, and image after it is cropped by PHP.
Will PHP affect the quality of the image when handling it? Or does it preserve the image's quality and simply crop the relevant area?
Many thanks,
BK
JPEG is lossy compression. A bit of oversimplification, but it works by analyzing pixels around other pixels to see how similar they are. Not every pixel is stored, and that means it isn't possible to simply chop bytes out of the image data to perform the crop. If you are outputting JPEG, you will be re-compressing an already compressed image, and you will have some loss in quality. However, if you crop the image and your output is a non-lossy format, then you will not have loss of quality.
To be clear, the loss of the quality isn't in the crop operation. It is in the way the image is compressed itself. If the source image is compressed with JPEG, quality has already been lost. When you crop that image, you aren't losing anything more, but if you were to output JPEG again afterwards, this would require a re-compression, and thus more loss.
So in the end, make your final output PNG or something non-lossy and you have nothing to worry about.

image resize but without any compromise in DPI?

I want to resize a image with DPI 300 or greater..
I want it's DPI to remain intact...
I have used GD library function to resize image cropped but it brings down DPI to 90!
please give a solution as my requirement involves no downsizing of DPI
Take image, say it's 1000 x 1000 Pixels large
Crop / resize image to a portio, say, 100 x 100 Pixels large
Enlarge 100 x 100 portion to 1000 x 1000 Pixels - use imagecopyresampled() for best results - manual
Done!
This comes at the price of lower quality, obviously.
It's going to be impossible to enlarge an image with no quality loss. You won't be able to retain the original image quality when enlarging because the pixel information simply isn't there. There are resizing algorithms that employ antialiasing and other techniques (like resampling in imagecopyresampled() to help the quality, but it will never be perfect.
If you want to display a large image smaller without losing any image data, you would put it into a img tag and then scale it down using the css width property. Note: This is not going to give you any better quality than resizing the image. In addition you are transferring more data than necessary, and in some browsers the result of the resizing may look bad due to the use of low-quality (but fast) algorithms - so the image may end up looking worse.
DPI means dots per inch. If you resize the image, the amount of inches stays the same (you show the same image), but the amount of dots goes down (less pixels).
So if you lower the size of the image, you always lower the DPI.
So if you lower the size of the image,
you always lower the DPI.
thats not true
the DPI is just a "conversion" used when you print something, it says nothing about the quality of the picture onscreen.
if you resize a picture (pixelsize that is) the printed versions shrinks the same way if you don't touch the DPI.
you could keep the printed size the same, but that would mean lowering the DPI
1200*1200px image with 300dpi is 4"*4" printed
600*600px image with 300dpi is 2"*2"
600*600px image with 150dpi is 4"*4"
if you use imagecopyresampled() the DPI should stay the same in the image
If you want to cropp an image and retain the source image PPI on the cropped area (which will be a new image) you can use Imagick following these steps:
// copy the original source to a new image, on which you'll be working
copy('example_source.jpg', 'example_cropped.jpg');
// set the resource path to work on
$resource = new Imagick('example_cropped.jpg');
// cropp the image
$resource->cropImage($cropp_width, $cropp_height, $left_offset_in_px, $top_offset_in_px);
// save the image (in this case, the same path as the one we're working on)
$resource->writeImage('example_cropped.jpg');
This is the most reasonable method I've found, since imagecopyresampled and imagejpeg seem to change the PPI of an image to the default 96 ppi (even for sources, with 300 ppi).

Image Processing & Creation in PHP - How To Create 300DPI Images

When creating images using the GD library in PHP ie) imagecreatetruecolor() what is the DPI of the resulting image? I haven't been able to find anyone specifying where the dpi can be set or what it defaults to.
I require a 300DPI tiff or jpeg to be created and then saved to the file system from the program.
If this isn't possible using the GD library, is there another that would work for this situation?
Thanks for your help
Edit: Yes this is creating an image - I would like to have a 300dpi file saved from the script not have to open up each file in photoshop to specify the dpi.
I don't think there's a way of setting DPI with GD. The DPI of an image is specified in the leading bytes of the image data - I believe for JPEG images that's bytes 15-18. Bytes 15-16 are horizontal DPI, 17-18 vertical. The values are stored as octals.
I'm a bit ropey with byte-level editing, but you could resize the image in GD to the target pixel size and then edit the file to adjust the DPI.
I believe its always 72dpi. So you should multiply your pixel dimensions acoordingly to produce the desired resolution image.

Categories