How to reduce image sizes in Linux. I have used ImageMagick for this. But it is not working well for gif images. I have used it as:
To resize image
exec("convert $original -resize " . $width . 'x' . $height . ' ' . $destination);
To reduce image size
exec("convert $original -quality 80% $new_img");
Please let me know if you have any way to reduce image size. This code works well for jpg, but not works well for gif images.
Appreciate your help.
Quoting from the Imagemagick manual:
-quality value
JPEG/MIFF/PNG compression level.
That means that using the quality level will only work on the aforementioned image types, which do not include GIF.
For GIF's your easiest option is to use the -colors command to reduce the number of colors used in your image. The quality of the result depends very much on what your initial image contains, I have seen cases where a reduction from 256 to 16 colors did not cause significant quality loss, and others where a reduction to 128 colors rendered the image unusable. You'll have to experiment.
A last remark: you could transform your GIF to PNG format and use the -quality command on the resulting image. Quality on PNG's however is a bit of a misnomer:
For the MNG and PNG image formats, the quality value sets the zlib compression
level (quality / 10) and filter-type (quality % 10). The default PNG "quality"
is 75, which means compression level 7 with adaptive PNG filtering, unless the
image has a color map, in which case it means compression level 7 with no PNG
filtering.
So don't be surprised if the size reduction is less on PNG's than on JPG', it only improves compression of the lossless PNG image.
To reduce GIF images in size, you can try converting them to PNG or to reduce the color depth. The color depth is the number of colors used in the image. Less colors means a smaller image size.
So you can use GD
http://ua.php.net/manual/en/function.imagecopyresampled.php
<
?php
// The file
$filename = 'test.jpg';
// Set a maximum height and width
$width = 200;
$height = 200;
// Content type
header('Content-Type: image/jpeg');
// Get new dimensions
list($width_orig, $height_orig) = getimagesize($filename);
$ratio_orig = $width_orig/$height_orig;
if ($width/$height > $ratio_orig) {
$width = $height*$ratio_orig;
} else {
$height = $width/$ratio_orig;
}
// Resample
$image_p = imagecreatetruecolor($width, $height);
$image = imagecreatefromjpeg($filename);
imagecopyresampled($image_p, $image, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig);
// Output
imagejpeg($image_p, null, 100);
?>
The following works well for JPEG images and likely works for other image formats. The given density (300) is pretty high and suitable for keeping text readable, so adjust for your situation.
convert input-file -density 300 -quality 50% output-file
Related
I am working on a script which will convert jpg to gif. The problem I am facing is that the output of imagegif is with bad quality and some colors change. ( black )
Here are to samples. One in JPG and the other in GIF.
http://oi62.tinypic.com/atx1j.jpg [JPG]
http://oi62.tinypic.com/oiyscy.jpg [GIF]
As you can see the colors of the GIF image has changed alitle.
I am using the following code
$img = imagecreatefromstring(base64_decode($image));
imagegif($img, "output.gif");
How can I improve the quality of the gif image?
Here's how you could achieve slightly better quality:
<?php
// load image
$image = imagecreatefromstring(file_get_contents('http://oi62.tinypic.com/atx1j.jpg'));
// create a true color image of the same size
$image2 = imagecreatetruecolor(imagesx($image), imagesy($image));
// copy the original gif image on to the true color image
imagecopy($image2, $image, 0, 0, 0, 0, imagesx($image), imagesy($image));
// output image
header("Content-Type: image/gif");
imagegif($image2);
imagedestroy($image);
imagedestroy($image2);
?>
Source Image
PHP Generated GIF Image
As you can see, it's slightly better. Very close to orignal. But you are still limited to 256 colors in GIF =[
GIF is inherently worse in quality than JPEG, this is because GIF only has 256 colours available to use, while JPEG has 4,294,967,296 colours...
If you have fewer than 256 colours in your image, GIF is actually higher quality than JPEG, since it doesn't do any compression, while jpeg compresses.
This has nothing to do with PHP: The JPEG format is a true color (or grayscale) format, while the GIF format is a palette format, with max palette size way below true color.
You need to reconsider your conversion process.
I have been doing some tests and found out that Imagemagick creates larger file sized images compared to GD library.
I have tried using thumbnailImage method and also resizeImage method (with different filters) of Imagemagick for creating an image of max dimension 1024x680 jpeg with JPEG compression and quality 80 and at 72 pixels per inch resolution and am also using stripImage method to remove unneeded meta data. The file size created by Imagemagick is always in the range of 700KB to 800KB depending upon various filters. On the other hand GD library produces an image of size 1024x680 which is only 41KB in size.
Can anyone please explain the difference in file sizes. I opened up the 2 files in Photo shop and checked to see any differences but could not find any (DPI, color profile, 8 bit channel etc), but still cant explain the difference in file sizes.
$srgbPath = "pathTosrgbColorProfile";
$srgb = file_get_contents($srgbPath);
$image->profileImage('icc', $srgb);
$image->stripImage();
$image->setImageResolution(72,72);
$image->setImageUnits(1);
$image->setInterlaceScheme(Imagick::INTERLACE_JPEG);
$image->setImageCompression(imagick::COMPRESSION_JPEG);
$image->setImageCompressionQuality(80);
$image->setColorspace(imagick::COLORSPACE_SRGB);
$image->resizeImage($thumb_width,$thumb_nheight,imagick::FILTER_CATROM,1);
$image->writeImage($destination);
The size went down by 40KB giving an output of 711KB which is still pretty big. The Hi-res original file I am testing on is a jpeg of size 3008x2000 (4.2MB).
Edit:
I think I figured it out, the method setCompression() does it for the Object and not the image, instead I used setImageCompression() and setImageCompressionQuality() and now the size has reduced to 100KB.. All good now!
Maybe the Quality settings of GD and ImageMagick aren't easily comparable, 80% in one does not mean the same as 80% in the other. I found the following note in an article form Smashing Magazine:
It turns out that JPEG quality scales are not defined in a specification or standard, and they are not uniform across encoders. A quality of 60 in Photoshop might be the same as a quality of 40 in one program, quality B+ in another and quality fantastico in a third. In my tests, I found that Photoshop’s 60 is closest to -quality 82 in ImageMagick.
So you may pay more attention on quality when comparing the different result files. Maybe the colors differ or the gd image has more artifacts.
The differnce seems rather large; when I did some tests a couple of years ago the file size of IM was about 5x the size of GD.
It would be interesting to see your actual code used.
I am at work at the moment but have a photo resized to 592 x 592 and the filesize is 50.3KB I know it is not the same size as yours but it was saved at quality 100
You can run this and see what IM says about the output files:
convert image -verbose -identify
EDIT:
You must be doing something wrong I have just run a test and the results are below - For some reason the thumbnail size is the same as the resize size! Maybe a bug.
Original file size: 4700 x 3178 2.31MB
-resize dimensions = 1021 x 680 186kb
-thumbnail dimensions = 1021 x 680 186kb
GD dimensions = 1024 x 682 100kb
$original = 'IMG_4979_1.CR2';
// Convert to jpg as GD will not work with CR2 files
exec("convert $original image.jpg");
$image = "image.jpg";
exec("convert $image -resize 1024x680 output1.jpg");
exec("convert $image -thumbnail 1024x680 -strip output2.jpg");
// Set the path to the image to resize
$input_image = 'image.jpg';
// Get the size of the original image into an array
$size = getimagesize( $input_image );
// Set the new width of the image
$thumb_width = "1024";
// Calculate the height of the new image to keep the aspect ratio
$thumb_height = ( int )(( $thumb_width/$size[0] )*$size[1] );
// Create a new true color image in the memory
$thumbnail = ImageCreateTrueColor( $thumb_width, $thumb_height );
// Create a new image from file
$src_img = ImageCreateFromJPEG( $input_image );
// Create the resized image
ImageCopyResampled( $thumbnail, $src_img, 0, 0, 0, 0, $thumb_width, $thumb_height, $size[0], $size[1] );
// Save the image as resized.jpg
ImageJPEG( $thumbnail, "output3.jpg" );
// Clear the memory of the tempory image
ImageDestroy( $thumbnail );
While i was doing some image processing, i found out that GD and Imagick in PHP does not resize image to color pixel identical level, which in most cases, were not needed.
Now in case, i need a image from whatever dimension to scale to 256*256
To make sure the TEST results are consistent, i used a 256*256 image and resize it to it's own size.
what i've attempted:
imagecopyresized($new, $img, 0, 0, $x, 0, $width, $height, $w, $h); //256 , 256
and
$compression_type = imagick::COMPRESSION_NO;
$images_ima = new Imagick($image_path); //$image_path = path to image...
$images_ima->setImageCompression($compression_type);
$images_ima->setImageCompressionQuality(100);
$images_ima->sampleImage($X_SIZE,$Y_SIZE); // 256 ,256
$images_ima->writeImages($dest_path, true); //destination path
none of them worked, if i compare the output with the original image, it will look something like this:
it looks like the functions i've used are resampling the image since the variations in the RGB value between both image are small
i can achieve pixel to pixel identical resizing from 256*256 to 256*256 in photoshop, OSX preview, and even Pixelformer.
i was wondering how can that be done i PHP?
Since your image format (jpeg - assumed from 100 quality setting) is a lossy format you won't get a lossless throughput this way as you're recompressing the image.
You should try to detect image dimensions and use the original image if the dimensions are already correct.
When you don't change the dimensions (original dimensions = dimensions after resizing) in Photoshop or OSX preview they won't recompress the image, that's why you won't see any change.
I want to resize an image to a max width. So I don't care about the height of the image, but I just want to always resize it to a specific width.
I'm certain I've done this before I just can't remember how I did it now.
Seems this is the way it is done, noting that width is the first parameter.
convert -resize '100' image.png
For anyone else wondering about height, then you would do this:
convert -resize 'x100' image.png
Source: http://www.imagemagick.org/script/command-line-processing.php
Edit (Nov 2014): Note that in the latest versions of ImageMagick you can no longer use quotes around the values as per Kevin Labécot's comment.
Your question is ambiguous. Your titles asks to resize an image to a max width, but then you seem to say you want to resize the image to a specific width.
If you want to resize something to a max width of 600px (ie, any image with a width of less than 600px will be unaffected), use:
convert original_image.jpg -resize 600x\> result_image.jpg
Or, to directly modify the original image:
mogrify -resize 600x\> original_image.jpg
If you'd like max height rather than max width:
convert original_image.jpg -resize x600\> result_image.jpg
Are you just chasing the math to work out the correct aspect ratio?
$new_width = 400; // config
$image_width = 480; // loaded from image
$image_height = 786; // loaded from image
$new_height = $new_width * ($image_height / $image_width);
echo "$image_width x $image_height becomes $new_width x $new_height";
The way to resize to a given width in ImageMagick is:
convert image -resize Wx result
or just
convert image -resize W result
where W=width and is provided, but H=height is not included
See https://imagemagick.org/script/command-line-processing.php#geometry
I have a watermark script I am working on, the results are good on PNG and on JPG images however a gif image, not so good. I am using PHP and GD
Below you can see the difference in quality of the watermark.
Anyone know how to improve this?
For the gif version I am using
$image = imagecreatefromgif($source_file);
imagecopymerge($image, $watermark, $x, $y, 0, 0, $water_width, $water_height, 65);
imagegif($image, $source_file);
gif image = bad quality
gif image http://img2.pict.com/fd/46/00/1471179/0/gif.gif
jpg image = good
jpg image http://img2.pict.com/82/a1/5a/1471181/0/jpg.jpg
GIF images have a fixed palette that can contain a maximum of 256 colors. The issue here is probably that the image your inserting uses colors that isn't available in the target image.
I have never tried this, but it might be worth a shot. You could try converting the gif image to a true color image first, then do the watermarking and after that converting it back to gif.
$image = imagecreatefromgif($source_file);
// create a true color image of the same size
$image2 = imagecreatetruecolor(imagesx($image), imagesy($image));
// copy the original gif image on to the true color image
imagecopy($image2, $image, 0, 0, 0, 0, imagesx($image), imagesy($image));
// copy the watermark onto the new true color image
imagecopymerge($image2, $watermark, $x, $y, 0, 0, $water_width, $water_height, 65);
// write the new image to disk
imagegif($image2, $source_file);
Try it and see if it makes a difference.
There's also a couple of palette manipulation functions available that might help:
imagecolormatch()
imagetruecolortopalette()
imagepalettecopy()
I'm not sure how you would apply them, but I'm guessing that there's a few things you could do to improve the results.
GIF only supports a color palette of 256 colors. Therefore, the colors of your watermark image have to be mapped to this palette. This caused them to be rendered and saved with different colors than before. Due to this small palette, GIF is not recommended for photos in general, anyways.
GIF images will never look great, as the colour palette is 256 colours. As MrMage says, colour mapping causes a severe approximation of the true colours of the image. You are better off with PNGs, they do support transparency.