snibgo's ImageMagick pages

Text data

ImageMagick can output text data that can be assigned to variables in Windows BAT or Bash scripts.

Here are some cookbook examples in both languages.

I use Windows with Cygwin, so Microsoft and Unix tools are both available on my computer, accesible from both BAT and bash scripts. Examples on this page are "pure"; either Windows or Unix, without mixing the two. The Windows BAT examples use only standard Microsoft tools, and the bash examples use only Unix tools.

Most of my scripting is in Windows BAT. I am not an expert in Unix tools or bash.

For basic information about escape characters and doubling percent sgns, see IM with Cygwin: Translating between Windows and Unix.

Setup

I use multiple versions of ImageMagic. They are contained in different directories, so I specify which version I want by giving the full path to the program.

for /F "usebackq" %%L in (`cygpath %IM%`) do set CYGIM=%%L

Image dimensions

Trim

Using -format

If the required data comes from a -format setting, we don't need to remove superfluous characters, and we can name the destination variables within the format itself. Putting the variable name with the expression means we don't need to keep counting, and debugging/maintainance is simpler.

For example: how many pixels, and what proportion of pixels, in the built-in rose: image are within 25% of pure red?

First, the BAT script:

for /F "usebackq" %%L in (`%IM%convert ^
  rose: ^
  -fuzz 25%% ^
  -fill Black +opaque Red ^
  -fill White -opaque Red ^
  -format "NUM=%%[fx:int(mean*w*h+0.5)]\nPROP=%%[fx:mean]" ^
  +write info: ^
  td_rose_blue.png`) do set %%L

echo NUM=%NUM% PROP=%PROP% 
td_rose_blue.png
NUM=772 PROP=0.239751 

Format strings can become very long, so I often break them up like this for clarity:

set FMT=^
NUM=%%[fx:int(mean*w*h+0.5)]\n^
PROP=%%[fx:mean]

for /F "usebackq" %%L in (`%IM%convert ^
  rose: ^
  -fuzz 25%% ^
  -fill Black +opaque Red ^
  -fill White -opaque Red ^
  -format "%FMT%" ^
  info:`) do set %%L

echo NUM=%NUM% PROP=%PROP% 
NUM=772 PROP=0.239751 

In bash, we use the same convert statement, inside backticks or $(), preceded by "declare". The format string is readily split into lines.

declare `${CYGIM}convert \
  rose: \
  -fuzz 25% \
  -fill Black +opaque Red \
  -fill White -opaque Red \
  -format 'NUM=%[fx:int(mean*w*h+0.5)]\n\
PROP=%[fx:mean]' \
  info:`

echo NUM=$NUM PROP=$PROP 
NUM=772 PROP=0.239751

Using identify as a calculator.

Items from identify -verbose

Suppose we want a value from identify -verbose, such as the rendering intent.

BAT version:

for /F "usebackq tokens=3" %%L in (`%IM%identify ^
  -verbose rose: ^| ^
  findstr /C:"Rendering intent:"`) do set REND=%%L

echo %REND% 
Perceptual 

Bash version:

set -- `${CYGIM}identify \
  -verbose rose: | \
  grep "Rendering intent:"`
REND=$3

echo $REND 
Perceptual

Subimage searches

In Windows BAT, the for command reads all the lines of its input, breaking each line into words which it assigns to temporary single-letter variables that persist only to the end of the for command. It can treat unwanted characters as delimiters between words.

compare sends text output to stderr. We can redirect this to stdout, and redirect stdout to a file.

%IM%compare ^
  rose: ^
  xc:blue ^
  -similarity-threshold 0 -dissimilarity-threshold 1 ^
  -subimage-search -metric RMSE ^
  NULL: >td_comp1.lis 2^>^&1

cmd /c exit /B 0

The file td_comp1.lis contains:

23474.9 (0.358203) @ 7,26

This compare command returns a non-zero error code, setting ERRORLEVEL to that value. which causes a failure in the process that builds this page. The effect of "cmd /c exit /B 0" is to reset ERRORLEVEL to zero.

Instead of redirecting to a file, we can put the four values into four temporary variables, and assign from there to more persistent variables:

for /F "usebackq tokens=1-4 delims=()@, " %%A in (`%IM%compare ^
  rose: ^
  xc:blue ^
  -similarity-threshold 0 -dissimilarity-threshold 1 ^
  -subimage-search -metric RMSE ^
  NULL: 2^>^&1`) do (
  set TD_COMP=%%A
  set TD_COMP_F=%%B
  set TD_COMP_X=%%C
  set TD_COMP_Y=%%D
)

echo TD_COMP=%TD_COMP% TD_COMP_F=%TD_COMP_F% TD_COMP_X=%TD_COMP_X% TD_COMP_Y=%TD_COMP_Y% 
23474.9 (0.358203) @ 7,26

In bash, we can use the $(...) (or backtick) command-expansion to put the entire output into a single variable:

result=$(${CYGIM}compare \
  rose: \
  xc:blue \
  -similarity-threshold 0 -dissimilarity-threshold 1 \
  -subimage-search -metric RMSE \
  NULL: 2>&1)

echo $result 
23474.9 (0.358203) @ 7,26

To get the four values nto four environment variables, sed can remove the superfluous characters "()@," splitting the output into words, which "set --" assigns to positional parameters, which we then assign to more persistent variables:

set -- $(${CYGIM}compare \
    rose: \
    xc:blue \
    -similarity-threshold 0 -dissimilarity-threshold 1 \
    -subimage-search -metric RMSE \
    NULL: 2>&1 | \
  sed -e 's/[()@,+]/ /g')
TD_COMP=$1
TD_COMP_F=$2
TD_COMP_X=$3
TD_COMP_Y=$4

echo TD_COMP=$TD_COMP TD_COMP_F=$TD_COMP_F TD_COMP_X=$TD_COMP_X TD_COMP_Y=$TD_COMP_Y 
TD_COMP=23474.9 TD_COMP_F=0.358203 TD_COMP_X=7 TD_COMP_Y=26

Instead of "set --", we could use arrays:

declare -a myarray

myarray=( $(${CYGIM}compare \
    rose: \
    xc:blue \
    -similarity-threshold 0 -dissimilarity-threshold 1 \
    -subimage-search -metric RMSE \
    NULL: 2>&1 | \
  sed -e 's/[()@,+]/ /g') )
TD_COMP=${myarray[0]}
TD_COMP_F=${myarray[1]}
TD_COMP_X=${myarray[2]}
TD_COMP_Y=${myarray[3]}

echo TD_COMP=$TD_COMP TD_COMP_F=$TD_COMP_F TD_COMP_X=$TD_COMP_X TD_COMP_Y=$TD_COMP_Y 
TD_COMP=23474.9 TD_COMP_F=0.358203 TD_COMP_X=7 TD_COMP_Y=26

Connected components

Splitting sparse-color: output

Scripts

For convenience, .bat scripts are also available in a single zip file. See Zipped BAT files.

demoNoise.bat

rem From image %1, perhaps 200x200 pixels,
rem makes %2 with HTML of a table with images and statistics.
rem %3 is optional seed.


echo 1: [%1]
echo 2: [%2]
echo 3: [%3]

if "%IM16i%"=="" call %PICTBAT%setim8

set INFILE=%1
if "%INFILE%"=="." set INFILE=
if "%INFILE%"=="" set INFILE=-size 200x200 xc:gray^^^(50%%%%^^^)

set TAB_FILE=%2
if "%TAB_FILE%"=="." set TAB_FILE=
if "%TAB_FILE%"=="" set TAB_FILE=ns_table.htm

if "%3"=="" (
  set SEED=
) else (
  set SEED=-seed %3
)
if "%SEED%"=="." set SEED=

echo INFILE=%INFILE% TAB_FILE=%TAB_FILE% SEED=%SEED%


set ATTEN=-attenuate 2.5

if "%INFILE%"=="%1" (
  set PREFIX=ns_%~n1
) else (
  set PREFIX=ns_
)

echo ATTEN=%ATTEN% PREFIX=%PREFIX%
rem exit /B 1

cecho /o%TAB_FILE% /X /s\(table\)
cecho /O%TAB_FILE% /X "/s<tr><td></td><th colspan=\q3\q>no attenuate</th><th colspan=\q3\q><tt>%ATTEN%</tt></th></tr>"

cecho /O%TAB_FILE% /X "/s<tr><th><tt>+noise</tt></th><th>image</th><th>histogram</th><th>statistics</th>"
cecho /O%TAB_FILE% /X "/s<th>image</th><th>histogram</th><th>statistics</th></tr>"

for /F "usebackq" %%N in (`%IM%convert -list noise`) do (
  echo %%N

  cecho /O%TAB_FILE% /X "/s<tr><td><tt>%%N</tt></td>"

  %IMDEV%convert ^
    %INFILE% ^
    %SEED% ^
    +noise %%N ^
    -clamp ^
    -format "min=%%[fx:minima]<br />\nmean=%%[fx:mean]<br />\nmax=%%[fx:maxima]<br />\nsd=%%[fx:standard_deviation]<br />\n" ^
    +write info: ^
    ^( +clone ^
      -separate ^
      -fill White -opaque Black ^
      -fill Black +opaque White ^
      -background Black ^
      -compose Lighten -layers Merge ^
      -format "clipped=%%[fx:mean]" ^
      +write info: ^
      +delete ^
    ^) ^
    +write %PREFIX%_nse_%%N.png ^
    -process 'mkhisto capnumbuckets 256 norm' ^
    %PREFIX%_hist_%%N.png >%PREFIX%_nse_%%N.lis

  if ERRORLEVEL 1 exit /B 1

  call %PICTBAT%graphLineCol %PREFIX%_hist_%%N.png . . 0 %PREFIX%_hist_%%N_glc.png

  if ERRORLEVEL 1 exit /B 1

  %IMDEV%convert ^
    %INFILE% ^
    %ATTEN% ^
    %SEED% ^
    +noise %%N ^
    -clamp ^
    -format "min=%%[fx:minima]<br />\nmean=%%[fx:mean]<br />\nmax=%%[fx:maxima]<br />\nsd=%%[fx:standard_deviation]<br />\n" ^
    +write info: ^
    ^( +clone ^
      -separate ^
      -fill White -opaque Black ^
      -fill Black +opaque White ^
      -background Black ^
      -compose Lighten -layers Merge ^
      -format "clipped=%%[fx:mean]" ^
      +write info: ^
      +delete ^
    ^) ^
    +write %PREFIX%_nse_a_%%N.png ^
    -process 'mkhisto capnumbuckets 256 norm' ^
    %PREFIX%_hist_a_%%N.png >%PREFIX%_nse_a_%%N.lis

  if ERRORLEVEL 1 exit /B 1

  call %PICTBAT%graphLineCol %PREFIX%_hist_a_%%N.png . . 0 %PREFIX%_hist_a_%%N_glc.png

  if ERRORLEVEL 1 exit /B 1

  cecho /O%TAB_FILE% /X "/s<td class=\qnotwhite\q><img src=\q%PREFIX%_nse_%%N.png\q /></td>"
  cecho /O%TAB_FILE% /X "/s<td class=\qnotwhite\q><img src=\q%PREFIX%_hist_%%N_glc.png\q /></td>"
  cecho /O%TAB_FILE% /X "/s<td>\n@%PREFIX%_nse_%%N.lis\n</td>"

  cecho /O%TAB_FILE% /X "/s<td class=\qnotwhite\q><img src=\q%PREFIX%_nse_a_%%N.png\q /></td>"
  cecho /O%TAB_FILE% /X "/s<td class=\qnotwhite\q><img src=\q%PREFIX%_hist_a_%%N_glc.png\q /></td>"
  cecho /O%TAB_FILE% /X "/s<td>\n@%PREFIX%_nse_a_%%N.lis\n</td>"

  cecho /O%TAB_FILE% /X "/s</tr>"

)

cecho /O%TAB_FILE% /X /s\(/table\)


type %PREFIX%_nse*.lis

type %TAB_FILE%

expAt /i%TAB_FILE% /o%TAB_FILE%

All images on this page were created by the commands shown, using:

%IM%identify -version

bash --version |head -n 3 
Version: ImageMagick 6.9.2-5 Q16 x64 2015-10-31 http://www.imagemagick.org
Copyright: Copyright (C) 1999-2015 ImageMagick Studio LLC
License: http://www.imagemagick.org/script/license.php
Visual C++: 180031101
Features: Cipher DPC Modules OpenMP 
Delegates (built-in): bzlib cairo freetype jng jp2 jpeg lcms lqr openexr pangocairo png ps rsvg tiff webp xml zlib
GNU bash, version 4.3.39(2)-release (x86_64-unknown-cygwin)
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

To improve internet download speeds, some images may have been automatically converted (by ImageMagick, of course) from PNG to JPG.

Source file for this web page is txtdata.h1. To re-create this web page, run "procH1 txtdata".


This page, including the images, is my copyright. Anyone is permitted to use or adapt any of the code, scripts or images for any purpose, including commercial use.

Anyone is permitted to re-publish this page, but only for non-commercial use.

Anyone is permitted to link to this page, including for commercial use.


Page version v1.0 6-September-2015.

Page created 26-May-2016 16:43:56.

Copyright © 2016 Alan Gibson.