Search code examples
imageimage-processingimagemagickchaining

How to chain image conversions with ImageMagick's convert command?


I've got an original image (say, 1600x1200) for which I want to create a series of thumbnails with a variety of resolutions:

  • 900x0 (i.e. means that the image is scaled proportionally to 900 px wide)
  • 700x0
  • 0x550 (i.e. means that the image is scaled proportionally to 550 px tall)
  • 0x400
  • 0x150
  • 200x200 (i.e. cropped and centred)

Individually, I can process each of these conversions with a convert command. The problem is that it's a huge waste of resources to continually reinitialize convert; it would be better to chain things so that convert could reuse its work.

Using ImageMagick 6.7.0-10 I've tried the following (using the +write option, see http://www.imagemagick.org/script/command-line-options.php#write), but it doesn't work as the +write command appears to be ineffective in restoring the image to its original state:

convert '/tmp/original.jpg'[0] -quality 95 -density 72x72 -resample 72x72 +profile '!xmp,*'\
-resize '900>' +write '/tmp/900.jpg'\
-resize '700>' +write '/tmp/700.jpg'\
-resize '200x' -crop '200x200+0+35' +repage +write '/tmp/200.jpg' \
-resize 'x550>' +write '/tmp/550.jpg'\
-resize 'x400>' +write '/tmp/400.jpg'\
-resize 'x150>' '/tmp/150.jpg'\

* end-of-line backslashes for readability purposes

Alternatively, I tried the following (using +clone and -delete). It seems to work, but could probably be made more efficient (perhaps with mpr:, http://www.imagemagick.org/Usage/files/#mpr):

convert 'original.jpg'[0] -quality 95 -density 72x72 -resample 72x72 +profile '!xmp,*' \
    \(+clone -resize 'x150>' -write '150.jpg' \) \ 
-delete 1 \(+clone -resize 'x400>' -write '400.jpg' \) \ 
-delete 1 \(+clone -resize 'x550>' -write '550.jpg' \) \ 
-delete 1 \(+clone -resize '200x' -crop '200x200+0+35' +repage -write '200.jpg' \) \ 
-delete 1 \(+clone -resize '700>' -write '700.jpg' \) -delete 1 -resize '900>' '900.jpg' \

Can anyone explain what I'm doing wrong in the first example (with the +write command)? Also, can anyone suggest any improvements to make things more CPU/memory efficient?

POST-ANSWER

I'm still curious why +write doesn't work.


Solution

  • Turns out that using mpr: is the way to go (from what I've seen on forums and whatnot):

    convert 'original.jpg'[0] -quality 95 -density 72x72 -resample 72x72 +profile '!xmp,*' \
    -write mpr:orig +delete \
    mpr:orig -resize 'x150>' -write '150.jpg' +delete \
    mpr:orig -resize 'x400>' -write '400.jpg' +delete \
    mpr:orig -resize 'x550>' -write '550.jpg' +delete \
    mpr:orig -resize '200x' -crop '200x200+0+35' +repage -write '200.jpg' +delete \ 
    mpr:orig -resize '700>' -write '700.jpg' +delete \ 
    mpr:orig -resize '900>' '900.jpg' +delete 
    

    NOTE: just in case you missed it, you don't need a -write command for the last image in the chain.

    ALSO NOTE: it's important that you use an extension on the files being output. If you omit it, convert doesn't know which format it should use when writing them (presumably because storing the image in mpr: destroys that information).