resizing images - imagemagick using - quality and jpeg:extent in one command - php

I am using imagemagick to resize images...
however I want to resize the images so that it uses both jpeg:extent and quality...
i.e. if I have a large image that i want to resize, and I use the following:
-resize 720 -quality 80
if the resulting image is larger than 250kb then I want the command to use jpeg:extent=250kB instead of -quality 80
Is this possible to do in one command?.. or do I have to do multiple proceedures to achieve this?... regards J
By the by, I dont want to just use jpeg:extent=250kB as if the image saved at 80% quality is alot smaller than 250kb i am creating images larger than they need be... cheers J

You can use both options at the same time. According to documentation:
Restrict the maximum JPEG file size, for example -define
jpeg:extent=400kb.
This command doesn't define the actual size, it only defines a size limit. This means that quality will be 80 if the size limit is not reached

Related

ImageMagick - Smaller resized image is a much larger file size

In ImageMagick, I'm running a:
convert -trim -density 200 myfile.tif -resize 70% myconvertedfile.png
If I remove -resize 70%, the image size is only 78,527.
However, when the file is stored at 70%, the file size is 860,504
What makes the smaller image a larger file size, and is there a way to decrease the file size without quality loss?
Most likely your smaller image has a larger number of colors due to interpolation of pixels during the resizing operation. To resize without adding colors, use -sample 70% instead of -resize 70%.
Your tiff may be compressed, Imagemagick, then decompresses and outputs to png. The resulting png compression may produce a file size larger than your tiff compression. Also, the tif may be 8-bit color, but when resized, it gets new colors and so must be saved as 24-bit color into PNG. I suspect this latter.
Also you should use proper ImageMagick syntax, which reads the input image before applying settings and then operators. However, ImageMagick 6 is forgiving in this regard.
convert myfile.tif -trim -resize 70% -density 200 myconvertedfile.png
If you want an 8-bit result, then you can use PNG8:myconvertedfile.png for your output.
When specifying density, you should specify units. PNG only stores units of pixels per centimeter, but will convert density and pixels per inch into the correct pixels per centimeter.
You could replace -resize with -sample and not interpolate pixels to new values. -sample will just grab every nth pixel.

FFmpeg - Resize Largest Video Dimension to 320

I'm trying to dynamically change the resolution of videos uploaded to a server via PHP, using FFmpeg. IE, I want to preserve portrait or landscape orientation - if Y is higher than X, I want to change Y to 320 and X to a corresponding value, and vice versa. I'm not having trouble with the resizing itself - it's quite straightforward, actually. What I'm having trouble with is detecting which dimension is larger.
I grabbed this solution off StackOverflow: how to check if video is landscape or portrait using ffmpeg php?
However, it doesn't appear to be working. While I track down what isn't working - I'm assuming the way the output is formatted has changed since that solution was posted, and it now needs to be parsed differently - I wanted to ask if there was a better way to do this. I'm open to using FFmpeg or a PHP-based solution.
ffmpeg -i input.jpg -vf 'scale=320:320:force_original_aspect_ratio=decrease' output.png
According to FFmpeg documentation, the force_original_aspect_ratio option is useful to keep the original aspect ratio when scaling:
force_original_aspect_ratio
Enable decreasing or increasing output video width or height if
necessary to keep the original aspect ratio. Possible values:
disable
Scale the video as specified and disable this feature.
decrease
The output video dimensions will automatically be decreased if
needed.
increase
The output video dimensions will automatically be increased if
needed.
Use decrease to make the largest dimension to 320, or use increase to make the smallest dimension to 320.
Have a look at the resizing page on the FFmpeg wiki. You basically want to look specifically at this section:
Sometimes there is a need to scale the input image in such way it fits
into a specified rectangle, i.e. if you have a placeholder (empty
rectangle) in which you want to scale any given image. This is a
little bit tricky, since you need to check the original aspect ratio,
in order to decide which component to specify and to set the other
component to -1 (to keep the aspect ratio). For example, if we would
like to scale our input image into a rectangle with dimensions of
320x240, we could use something like this:
ffmpeg -i input.jpg -vf scale="'if(gt(a,4/3),320,-1)':'if(gt(a,4/3),-1,240)'" output_320x240_boxed.png
You can obviously use this for videos as well as for images.
You can use a if statement to select the larger one
-vf scale='if(gt(iw,ih),320:-2)':'if(gt(iw,ih),-2:320)'
FYI, the correct way to do this is to use FFprobe, which comes with FFmpeg.
https://www.ffmpeg.org/ffprobe.html

General Image Optimisation for the Web in ImageMagick

I currently do a strait copy() of images that are the correct width/height to go into my site. I was wondering what sort of best practicies in Imagemagick should I be doing to ensure filesize is lowest it can be without loosing quality of the JPEG?
What you can do is that identify the current image quality & size before you do your copy and compression
Example
identify -verbose rose.jpg
Would return all information including
Compression
Quality
Resolution
Depth
File Size
etc ...
To do your own Optimization
Don't just use fixed values .. used the information too calculated possible and ideal compression and size for the image
Example
If an image quality is 70 and 60 is your bench mark .. all you need so do is reduce it by 10% and its it is 100 reduce by 40% .. at all times you would images with the same level of quality
I resize on upload as even if you read a jpg into Imagemagick and save without doing anything it recompresses it.
If you resize and use -resize all EXIF data is kept; using -thumbnail all EXIF data ( including the embeded thumbnail ) apart from the colour profile is stripped. You can also use -strip on its own which will remove all EXIF data and the colour profile.
To keep the quality in jpg use -quality 100 so you could use something like:
convert input.jpg -strip -quality 100 output.jpg

How can I estimation the file size of an image using its width and height?

I have recently written an image resizing program using php, which works by downloading images off another server, resizing them and saving them to our own.
The bad news is that my Hosting account only allows a php memory limit of 64M, and this is just not set up to resize the HUUUUGE file sizes that my client is uploading (3 - 4mb). It spits out a fatal error if it meets these images and breaks the script.
Even though I have notified said client of this drawback, said client continues to upload large images and script keeps breaking.
I can obtain the width and the height of the image before downloading it using getimagesize(), and if I could use this info to work out the total file size I could break out before the image resizer gets going and suppliment the image with a nice "no image available" alternative.
How can I make an accurate estimation of an images file size using its width and height, assuming it has a bit depth of 24?
An image in memory always weights the same weight compressed in JPEG or GIF or BMP. It's called a BIT-MAP. So, if you want to calculate the size of an image in memory, take the width, the height and the bit size to get the bit weight, divide by 8 and you get the bytesite.
$ByteSize = Width*Heigh*(24/8)
Note that it is possible to get more weight from an image in some parts such as a paletized image, it will have to store the image color palette in memory but most of the time this should weight less than a bitmap.
A multiplication.
Just multiply height by width by 3.
and throw in some spare memory to process all these bytes. say, twice the image size.
It has nothing to do with file size though.
before the upload on the server you can't with php,
but you can use javascript!
https://developer.mozilla.org/en/DOM/File
will work in conjunction of and will instantly provide the filesize using
fileInput.files[0].fileSize
read these:
https://developer.mozilla.org/en/Using_files_from_web_applications
http://hacks.mozilla.org/2009/12/multiple-file-input-in-firefox-3-6/
hope this helps!
The size will always depend on the format. When compressing images, the size of the image itself won't have any effect on the filesize. The only way that you can get a good readout of the filesize is if you use a Bitmap (or simmilar) format.
Example, A JPEG could be 10MB in size, and then when rotated only 1 MB in size because of how the compression works.

print quality images with php and GD

I need to take a photo someone has uploaded through a form, resize, merge with a high-res frame # 300dpi and keep it all # 300dpi for the best quality for print.
is it possible to handle high-res images through GD and if so, could you provide some information on how? I have code that already does the resizing and merging, but i'm not sure if its going to work at the correct dpi.
Thanks
It's basically possible: Just use the proper amount of pixels. (The dpi unit has no meaning in digital imaging, it serves only to convert a digital [pixel] image into a physical format).
Example:
11 x 8 inch canvas #300 dpi = 3300 x 2400 pixels
However, you'll need plenty of memory to deal with images this large. The rule of thumb is
needed bytes = width x height x 3 (or 4 if alpha-channels are used)
this requirement increases if you do copying or resizing, because the script needs to keep multiple copies in memory.
You will need a very generous memory_limit setting for this to work.
Also note that GD can only deal with RGB images.
For large images and CMYK data, ImageMagick may be a better option if you can use it on your server.
DPI is a conversion factor for print purposes. It has absolutely no bearing on how GD will see the image. An image that is 200 pixels by 150 pixels will always be 200 pixels by 150 pixels, whether it's 10dpi or 5000dpi.
however, when you print out the image, 200x150 # 10dpi would make for 20 inch by 15 inch image (300 square inches), while the 5000dpi version would make for 0.04x0.03 (0.0012 square inches).
The only limitation is that you have to have enough memory available for PHP to hold the DECODED image contents in memory. a 24bit 1000x1000 pixel image requires 1000x1000x3 = roughly 3meg bytes of memory, at mininum (plus internal overhead). Then extra memory to hold the new images which will have the results of your image manipulations.
The default image dpi on a web page is 72 or 96 ( Mac or Windows/Linux ). You can specify the width and heigth of a image using the width and height attibutes of the img tag and generate the image with the desired dpi within.
<img src="/images/image.png" width="300" height="200">
Let's say that your default screen resolution is 72, than make a $resdpi variable:
$resdpi = $resolution / 72;
then, make the image on GD multiplying the width and height by that variable and you'll get a large image that will appear like a default 72dpi on screen, but will print with much more resolution.
GD is all about pixels, DPI does not come in to it, as that requires some sort of device output. If you know your final print size, then just ensure that the dimensions in pixels scale correctly at the DPI you require.
Generally, if you are using large images, your main problem is going to be efficiency, both in speed and memory usage. I would recommend using ImageMagick for more complicated jobs.

Categories