Fred's ImageMagick Scripts



    Licensing:

    Copyright © Fred Weinhaus

    My scripts are available free of charge for non-commercial (non-profit) use, ONLY.

    For use of my scripts in commercial (for-profit) environments or non-free applications, please contact me (Fred Weinhaus) for licensing arrangements. My email address is fmw at alink dot net.

    If you: 1) redistribute, 2) incorporate any of these scripts into other free applications or 3) reprogram them in another scripting language, then you must contact me for permission, especially if the result might be used in a commercial or for-profit environment.

    Usage, whether stated or not in the script, is restricted to the above licensing arrangements. It is also subject, in a subordinate manner, to the ImageMagick license, which can be found at: http://www.imagemagick.org/script/license.php

    Please read the Pointers For Use on my home page to properly install and customize my scripts.

DOWNSIZE


Downsizes (reduces) an image to a specified file size.

Download Script

last modified: August 01, 2021



USAGE: downsize [-s size] [-t toler] [-m maxiter] [-c copy] [-S strip] infile outfile
USAGE: downsize [-help]

-s .... size ........ desired output file size in kilobytes; float>0;
..................... default=200
-t .... toler ....... tolerance or allowed size of result greater than
..................... desired size expressed as percent of desired size;
..................... float>=0; default=10
-m .... maxiter ..... maximum number of iterations to stop; integer>1;
..................... default=20
-c .... copy ........ copy to output when not downsizing and no image
..................... format change; yes (y) or no (n); default=yes
-S .... strip ....... strip all meta data; yes (y) or no (n); default=yes

PURPOSE: To downsize (reduce) an image to a specified file size.

DESCRIPTION: DOWNSIZE reduces an image's dimensions to achieve a specified file size. For non-JPG images, processing will continue until either the desired tolerance is achieved or the maximum number of iterations is reached. For JPG images, processing will continue as above, but may stop when no change of file size (or quality) occurs. Thus the desired file size may not full be achieved to within the specified tolerance. Approximately 1% tolerance is practical amount that can be achieved for non-JPG images. For JPG images, the value may or may not be achieved. When strip is no, processing will be skipped, if the input file size is less than or equal to the combined desired file size plus the size of the meta data or if the desired size is less than the meta data size.

ARGUMENTS:

-s size ... SIZE is the desired output image size in kilobytes. Values are floats>0. The default=200

-t toler ... TOLER is allowed size of the result within than the desire size expressed as a percent of the desired size. Values are floats>=0. The default=10. Processing will iterate until the resulting image size is within the tolerance. If the tolerance is too low, then iterations will stop when it reaches a value of maxiter. The default=10 (10%). If both toler and maxiter are too small, then iteration could continue indefinitely, since the algorithm may not be able to get as close as desired.

-m maxiter ... MAXITER is the maximum number of iterations to stop. Values are integer>1. The default=20. If both toler and maxiter are too small, then iteration could continue indefinitely, since the algorithm may not be able to get as close as desired.

-c copy ... COPY will copy the input to the output when both no downsize processing happens and the input and output formats are the same. Values are either: yes (y) or no (n). Yes means make a copy of the input with the output name and no means simply skip processing and do not copy The input data to the output file. The default=yes.

-S strip ... STRIP all meta data. Choices are: yes (y) or no (n). The default=yes. Note that if you do not strip, the file size will be limited to the size of the meta data.

NOTE: Images will be converted to 8 bits/pixel/channel.

CAVEAT: No guarantee that this script will work on all platforms, nor that trapping of inconsistent parameters is complete and foolproof. Use At Your Own Risk.


NOTE: The algorithm has been changed. Results below may not be identical.


EXAMPLES


Original:
(756 x 572; 726.153 KB)

Arguments:
-s 200 -t 1 -c yes
(default)
(404 x 305; 200.249 KB)



What the script does is as follows:

  • copies the image to the same file type (format)
    in case IM has different compression
  • computes the size of copied image
  • computes the resize ratio between the copied image size
    and the desired size
  • resizes the copied image
  • iterates if the resized image is larger than the desired
    size by the tolerance amount.

This is equivalent to the following IM commands for the default case

  • convert -quiet -regard-warnings "$infile" -strip +repage "$tmpA1"
  • fullsize=`convert $tmpA1 ${ftype}:- | convert - -ping -format "%b" info:`
  • size2=`convert xc: -format "%[fx:$size*1000]" info:`
  • i=1
  • diffsize=0
  • iterate=1
  • while [ $iterate -eq 1 ]; do
    size2=`convert xc: -format "%[fx:$size2-($diffsize*1000)]" info:`
    pratio=`convert xc: -format "%[fx:100*sqrt($size2/$fullsize)]" info:`
    convert $tmpA1 -resize ${pratio}% ${ftype}:$outfile
    newsize=`convert $outfile -ping -format "%b" info:`
    newsize=`convert xc: -format "%[fx:$newsize/1000]" info:`
    echo "i=$i; newsize=${newsize}kB"
    diffsize=`convert xc: -format "%[fx:($newsize-$size)]" info:`
    iterate=`convert xc: -format "%[fx:$diffsize>($toler*$size/100)?1:0]" info:`
    i=$(($i+1))
    done