Page 1 of 1
Resample to a Pixel Count Limit
Posted: 2013-11-11T08:58:33-07:00
by elmimmo
The examples page on
Resize or Scaling (General Techniques) states one can -resize an image to a certain
Pixel Count Limit:
Code: Select all
convert dragon.gif -resize 4096@ pixel_dragon.gif
My problem with -resize is that it will keep the ppi of the output unchanged, resulting in the output image and the input image having different physical sizes (fewer pixels at the same ppi produce shorter physical distances). When I resize an image, most of the time, I want to keep its printed size unchanged and thus reduce both its number of pixels and its ppi values stored in its metadata.
That same page introduces
-resample, stating that:
"-resample" is also a simple wrapper around the normal "-resize" operator.
But then again, -resample wants a ppi value as parameter, while I want to resize based on a certain Pixel Count Limit. I want to give "convert" that pixel count limit, and have it calculate itself the new ppi value it has to store into the output file so that its physical size remains unchanged.
Any idea how to do it?
Re: Resample to a Pixel Count Limit
Posted: 2013-11-11T09:06:18-07:00
by snibgo
If you want to change the resolution so the input and output are the same number of inches, you could do the calculation in a script.
new_resolution = old_resolution * new_width/old_width
where width is measured in pixels. You've have to set the new "-density" in another convert, so beware of multiple saves to JPEG.
Re: Resample to a Pixel Count Limit
Posted: 2013-11-12T05:47:59-07:00
by elmimmo
Yes, I know I can calculate it myself and feed it with exiftool (`convert -density` is out of the question as it is not a lossless operation).
That adds complexity. I was wishing for a `convert` one liner that both resizes to a Pixel Count Limit AND writes the new ppi metadata.
Re: Resample to a Pixel Count Limit
Posted: 2013-11-12T23:31:06-07:00
by snibgo
I don't think you can currently do this in a single convert command. Perhaps v7 will enable %fx[...] expressions in "-density".
Re: Resample to a Pixel Count Limit
Posted: 2013-11-13T08:48:43-07:00
by elmimmo
Well, here it is:
Code: Select all
# Change paths and value
MY_INPUT="/path/to/inputImage.tif"
MY_OUTPUT="/path/to/outputImage.jpg"
MY_PX_LIMIT=2000000
# Go!
IMG_RES=( $(identify -units PixelsPerInch \
-format "%w %h %x %y" \
"$MY_INPUT" ) )
IMG_X_DENSITY=$(echo "${IMG_RES[2]} * sqrt($MY_PX_LIMIT/(${IMG_RES[0]}*${IMG_RES[1]}))" | bc -l)
IMG_Y_DENSITY=$(echo "${IMG_RES[3]} * sqrt($MY_PX_LIMIT/(${IMG_RES[0]}*${IMG_RES[1]}))" | bc -l)
IMG_DENSITY=${IMG_X_DENSITY}x${IMG_Y_DENSITY}
convert "$MY_INPUT" \
-resize ${MY_PX_LIMIT}@ \
-units PixelsPerInch \
-density $IMG_DENSITY \
"$MY_OUTPUT"
although IMHO it is pretty ridiculous that I have to go through these hoops to get a resized image while keeping its physical size intact.
And this is not even a solution, as for whatever reason, identify and convert will be reading/writing the ppi from/in the JPEG header, but if the input image also has the proprietary ppi fields that Photoshop uses, convert will copy them unto the output image. As a result, even if one took the effort to calculate and embed the ppi that the output image should have, Photoshop will not give a damn and still use the ppi of the original image.
Is there a way to have convert overwrite Photoshop's proprietary ppi fields when using -density?
Re: Resample to a Pixel Count Limit
Posted: 2013-11-13T09:08:48-07:00
by elmimmo
Just to answer to myself: apparently the options are to keep all metadata of the input image or none of it (adding the option -strip; unless one wants to rely on an extra tool like exiftool to be able to target metadata more granularly), in which case Photoshop will read the ppi resolution that convert stored in the JPEG header.
Code: Select all
# Change paths and value
MY_INPUT="/path/to/inputImage.tif"
MY_OUTPUT="/path/to/outputImage.jpg"
MY_PX_LIMIT=2000000
# Go!
IMG_RES=( $(identify -units PixelsPerInch \
-format "%w %h %x %y" \
"$MY_INPUT" ) )
IMG_X_DENSITY=$(echo "${IMG_RES[2]} * sqrt($MY_PX_LIMIT/(${IMG_RES[0]}*${IMG_RES[1]}))" | bc -l)
IMG_Y_DENSITY=$(echo "${IMG_RES[3]} * sqrt($MY_PX_LIMIT/(${IMG_RES[0]}*${IMG_RES[1]}))" | bc -l)
IMG_DENSITY=${IMG_X_DENSITY}x${IMG_Y_DENSITY}
convert "$MY_INPUT" \
-strip \
-resize ${MY_PX_LIMIT}@ \
-units PixelsPerInch \
-density $IMG_DENSITY \
"$MY_OUTPUT"