Search code examples
imagemagickimagemagick-convert

Why does blurring using ImageMagick's convert work as advertised?


My question is not how to blur a portion of an image, but why the following statement works correctly.

convert rose: \( +clone -scale 5%  -scale 2000% \) \
\( +clone -gamma 0 -fill white \
-draw 'rectangle 20,10 40,20' -blur 10x4 \) \
-composite target.png

rose-blurred

My understanding so far is that the first part

\( +clone -scale 5%  -scale 2000% \)

takes the source image, which is initially the only one on the stack, and duplicates it on the stack then modifies that top of the stack by minifying by 1/20 then magnifying by 20/1, in that order. Hence the image on top of the stack remains at the same resolution as the one below it.

The next command

\( +clone -gamma 0 -fill white \
-draw 'rectangle 20,10 40,20' -blur 10x4 \) \

once again duplicates the top image. Hence there are now three images on the stack. Gamma is set to the unusual value of zero to be absolutely certain that the next command, filling with white, will fill with a pure RGB of 1.0,1.0,1.0. The -fill command does not actually do anything. It merely sets the parameter. The actual drawing action is performed by the -draw command. That command draws a particular primitive (a rectangle in this case), and fills it with white. The blur filter is applied after the rectangle is drawn. Hence not much will happen to the rectangle itself. It is the rest of the image that will be blurred with that filter.

Next I'm lost. The -composite operator will overlay the image on top of the stack, over the image one below it on the stack. But since we have three images on the stack, the effect is that the image at the bottom of the stack will be ignored. Care to clarify?

I'd also like to learn how to fish rather than be offered a fish: man convert points to this page, but nowhere does "stack" appear on that page. Which reference page should I start from to understand brief convert snippets like the one above?


Solution

  • Firstly, for some "fishing lessons" you could have a read here about command-line processing and order of commands etc. Also, have a look at Anthony Thyssen's excellent "Usage" pages here.

    As regards, your question, the explanation is that when there are three images on the stack (as you rightly say), the third one acts as a mask for the operation of the other two. It is explained here.

    Further "fishing lesson"... if you are stuck with ImageMagick, you can debug it in a number of ways...

    Technique 1

    Remove the last part of your command (the bit that creates the output file, including the last -composite) and replace it with a filename like this:

    convert rose:                          \
      \( +clone -scale 5%  -scale 2000% \) \
      \( +clone -gamma 0 -fill white -draw 'rectangle 20,10 40,20' -blur 10x4 \) \
      temp-%d.png
    

    Now run it and you will see all the images in your stack in failed called temp-0.png, temp-1.png etc.

    Technique 2

    Add intermediate -writes at various stages of your processing pipeline:

    convert rose: \( +clone -scale 5%  -scale 2000% -write temp1.png \) \
     \( +clone -gamma 0 -fill white -draw 'rectangle 20,10 40,20' -blur 10x4 -write temp2.png \) \
    ...