snibgo's ImageMagick pages

Maximise local contrast

... without clipping.

In IM, we can increase global contrast with -level or a number of other operations, and we can increase local contrast with -unsharp. If we increase contrast by too much, we push values out of gamut, so they are clipped and we lose detail. How can we increase local contrast so it is maximised, without clipping?

The problem is closely related to Adaptive blur and sharpen, but the method given on this page has a different goal. This method is developed further in Maximise local colour contrast.

The method

We will work in Q32 HDRI:

set sHDRI=^
  -depth 32 ^
  -define "compose:clamp=off" ^
  -define "quantum:format=floating-point"

We start with a gray image, from the L channel of CIELab:

set SRC=toes.png
set SRC_GR=mlc_srcgr.miff

%IMG7%magick ^
  %SRC% ^
  %sHDRI% ^
  -colorspace Lab ^
  -channel R -separate +channel ^
  -set colorspace sRGB ^
  %SRC_GR%
mlc_srcgr.miffjpg

Subtract the local mean. Values are close to zero, so we need floating-point to avoid clipping. The process will expand the range of these values.

set SIG1=2

%IMG7%magick ^
  %SRC_GR% ^
  %sHDRI% ^
  ( +clone ^
    -blur 0x%SIG1% ^
    +write mlc_blr.miff ^
  ) ^
  -compose MinusSrc -composite ^
  mlc_minblr.miff
mlc_blr.miffjpg mlc_minblr.miffjpg

mlc_minblr.miff contains high-frequency data (positive and negative). If we add it back to the blur (low-frequency data, positive only), this will reconstruct the original source image.

If the input ranges from 0 to 100%, mlc_minblr.miff has a theoretical range of -100% to +100%. In practice, most values will be close to zero.

mlc_minblr.miff isn't easy to see, so we "-auto-level" to put pixels in the 0 to 100% range, just for viewing:

%IMG7%magick ^
  mlc_minblr.miff ^
  %sHDRI% ^
  -auto-level ^
  mlc_minblr_p.png
mlc_minblr_p.pngjpg

If we double the values in mlc_minblr.miff before adding it back to the blur, this will increase the local contrast:

%IMG7%magick ^
  mlc_minblr.miff ^
  %sHDRI% ^
  -evaluate Multiply 2 ^
  mlc_blr.miff ^
  -compose Plus -composite ^
  mlc_uns1.miff
mlc_uns1.miffjpg

This operation will usually cause some clipping, as it has done here:

%IMG7%magick ^
  mlc_uns1.miff ^
  -format "min=%%[fx:minima]  max=%%[fx:maxima]\n" ^
  info: 
min=0.0137443  max=1.03843

From the image we see that most areas have not clipped. In those areas, we could multiply mlc_minblr.miff by a larger number before adding it back to the blur. To maximise local contrast everywhere without clipping, we will multiply by a number that varies across the image. This is most conveniently done by dividing by the reciprocal, something like this ...

%IMG7%magick ^
  mlc_minblr.miff ^
  %sHDRI% ^
  mlc_numbers.miff ^
  -compose Divide -composite ^
  mlc_blr.miff ^
  -compose Plus -composite ^
  mlc_max_cont.miff

... where mlc_numbers.miff contains the divider at each pixel. So now we need to calculate mlc_numbers.miff. Ideally, this would be the local peaks in mlc_minblr.miff, but this wouldn't be a smoothly changing function. mlc_minblr.miff contains positive and negative values, so we take the absolute value, and blur it. This smooths the peaks, so we multiply it by the maximum absolute value (maxA) divided by the maximum blurred absolute value (maxB). (It would be easier to "-auto-level" the blurred absolute, but outliers would squish the values too much.)

First, take the absolute and blur it, and calculate the multiplier (mult = maxA/maxB)...

set SIG2=%SIG1%

for /F "usebackq" %%L in (`%IMG7%magick ^
  mlc_minblr.miff ^
  %sHDRI% ^
  -evaluate Abs 0 ^
  +write mlc_minblr_abs.miff ^
  -format "maxA=%%[fx:maxima]\n" ^
  +write info: ^
  -blur 0x%SIG2% ^
  +write mlc_minblr_avg.miff ^
  -format "maxB=%%[fx:maxima]\n" ^
  info:`) do set %%L

for /F "usebackq" %%L in (`%IMG7%magick identify ^
  -format "mult=%%[fx:%maxA%/%maxB%]\n"
  xc:`) do set %%L

echo maxA=%maxA% maxB=%maxB% mult=%mult% 
maxA=0.204846 maxB=0.0688866 mult=2.97367 
mlc_minblr_abs.miffjpg mlc_minblr_avg.miffjpg

Show auto-levelled versions of mlc_minblr_abs.miff and mlc_minblr_avg.miff.

%IMG7%magick ^
  mlc_minblr_abs.miff ^
  %sHDRI% ^
  -auto-level ^
  mlc_minblr_abs_p.png

%IMG7%magick ^
  mlc_minblr_avg.miff ^
  %sHDRI% ^
  -auto-level ^
  mlc_minblr_avg_p.png
mlc_minblr_abs_p.pngjpg mlc_minblr_avg_p.pngjpg

... and apply the multiplier:

%IMG7%magick ^
  mlc_minblr_avg.miff ^
  %sHDRI% ^
  -evaluate Multiply %mult% ^
  mlc_minblr_avg2.miff
mlc_minblr_avg2.miffjpg

Auto-levelled:

%IMG7%magick ^
  mlc_minblr_avg2.miff ^
  %sHDRI% ^
  -auto-level ^
  mlc_minblr_avg2_p.png
mlc_minblr_avg2_p.pngjpg

Now we can divide mlc_minblr.miff by the numbers in mlc_minblr_avg2.miff to locally maximise the high frequency component.

%IMG7%magick ^
  mlc_minblr.miff ^
  %sHDRI% ^
  mlc_minblr_avg2.miff ^
  -compose DivideSrc -composite ^
  mlc_minblr_div.miff
mlc_minblr_div.miffjpg

mlc_minblr_div.miff ranges from -100% to +100%, more or less. "-auto-level" would reduce this to exactly 0 to 100%, but outliers would squish this by too much, so we divide by two and add 50% to get a nominal range of 0 to 100%, and use oogPower.bat (see Putting OOG back in the box: Power modulation).

%IMG7%magick ^
  mlc_minblr_div.miff ^
  %sHDRI% ^
  -evaluate Divide 2 ^
  -evaluate Add 50%% ^
  mlc_minblr_div2.miff
mlc_minblr_div2.miffjpg
call %PICTBAT%oogPower ^
  mlc_minblr_div2.miff ^
  mlc_minblr_div3.png
mlc_minblr_div3.pngjpg

This is the high frequency component of the maximum-contrast image. For some purposes, this is what we want. Or we can maximise further, by thresholding:

%IMG7%magick ^
  mlc_minblr_div3.png ^
  -threshold 50%% ^
  mlc_minblr_div3_t.png
mlc_minblr_div3_t.pngjpg

Or a "-contrast-stretch" makes roughly half-and-half black and white:

%IMG7%magick ^
  mlc_minblr_div3.png ^
  -contrast-stretch 49.9x49.9%% ^
  -threshold 50%% ^
  mlc_minblr_div3_t2.png
mlc_minblr_div3_t2.pngjpg

Or convert to black and white with dithering:

%IMG7%magick ^
  mlc_minblr_div3.png ^
  ( xc:Black xc:White +append +repage ^
    -write mpr:MSK +delete ^
  ) ^
  -remap mpr:MSK ^
  mlc_minblr_div3_t3.png
mlc_minblr_div3_t3.pngjpg

However, it is more correct to add the high frequency component back to the blur. The high frequency component, mlc_minblr_div3.png, has the null point at 50%, so we also subtract 50%.

%IMG7%magick ^
  mlc_blr.miff ^
  %sHDRI% ^
  mlc_minblr_div3.png ^
  -compose Mathematics ^
    -define compose:args=0,1.0,1.0,-0.5 ^
  -composite ^
  +define compose:args ^
  -clamp ^
  mlc_maxc.miff
mlc_maxc.miffjpg

This addition can cause clipping, so we do another oogPower:

call %PICTBAT%oogPower ^
  mlc_maxc.miff ^
  mlc_maxc2.miff
mlc_maxc2.miffjpg

Restore the colour from the a* and b* channels of the source:

%IMG7%magick ^
  %SRC% ^
  %sHDRI% ^
  -colorspace Lab ^
  -separate ^
  mlc_maxc2.miff ^
  -swap 0,3 ^
  +delete ^
  -combine ^
  -set colorspace Lab ^
  -colorspace sRGB ^
  mlc_maxc3.miff
mlc_maxc3.miffjpg

Aside: limiting the effect

As an aside: we can limit the effect of the increased contrast. The method shown in Limit min-max imposes a severe limit so we get sharpening with no overshoot, no halos, no out-of-gamut and no clipping.

call %PICTBAT%limitMinMax ^
  %SRC_GR% ^
  mlc_maxc.miff ^
  mlc_limit.miff ^
  3x3

%IMG7%magick ^
  mlc_limit.miff ^
  -channel R -separate +channel ^
  mlc_limit.miff
mlc_limit.miffjpg
%IMG7%magick ^
  %SRC% ^
  %sHDRI% ^
  -colorspace Lab ^
  -separate ^
  mlc_limit.miff ^
  -swap 0,3 ^
  +delete ^
  -combine ^
  -set colorspace Lab ^
  -colorspace sRGB ^
  mlc_maxc3_limit.miff
mlc_maxc3_limit.miffjpg

The script

We put most of the above into a script, maxLocCont.bat.

Option Description
%1 Input image.
%2 Output file.
%3 Sigma to find the local mean. Default: 2.
%4 Sigma to find local maxima. Default: %3.
%5 Blend percentage. Default: 100.
%6 Col or Gray. Default: Col
%7 Post-process, eg -auto-level. Default: no post-process.

For example:

call %PICTBAT%maxLocCont ^
  %SRC% ^
  mlc_sc1.png 0.5
mlc_sc1.pngjpg
call %PICTBAT%maxLocCont ^
  %SRC% ^
  mlc_sc2.png 1
mlc_sc2.pngjpg
call %PICTBAT%maxLocCont ^
  %SRC% ^
  mlc_sc3.png 2
mlc_sc3.pngjpg
call %PICTBAT%maxLocCont ^
  %SRC% ^
  mlc_sc4.png 3
mlc_sc4.pngjpg
call %PICTBAT%maxLocCont ^
  %SRC% ^
  mlc_sc5.png 10
mlc_sc5.pngjpg
call %PICTBAT%maxLocCont ^
  %SRC% ^
  mlc_sc6.png 20
mlc_sc6.pngjpg
call %PICTBAT%maxLocCont ^
  %SRC% ^
  mlc_sc7.png 50
mlc_sc7.pngjpg

Generally, the two sigmas should be equal. If the second is larger than the first, the contrast is reduced. If the second is smaller than the first, contrast is increased.

call %PICTBAT%maxLocCont ^
  %SRC% ^
  mlc_sc13.png 1 3
mlc_sc13.pngjpg
call %PICTBAT%maxLocCont ^
  %SRC% ^
  mlc_sc31.png 3 1
mlc_sc31.pngjpg

We can use the blend percentage from 0 to 100 to control the degree of the effect, or use a value beyond that range.

call %PICTBAT%maxLocCont ^
  %SRC% ^
  mlc_b1.png 0.5 . 50
mlc_b1.pngjpg
call %PICTBAT%maxLocCont ^
  %SRC% ^
  mlc_b2.png 2 . 50
mlc_b2.pngjpg
call %PICTBAT%maxLocCont ^
  %SRC% ^
  mlc_b3.png 2 . 150
mlc_b3.pngjpg
call %PICTBAT%maxLocCont ^
  %SRC% ^
  mlc_b4.png 2 . -150
mlc_b4.pngjpg

By default, the process modifies the L channel of Lab. The Gray option is slightly faster, returning just the L channel.

call %PICTBAT%maxLocCont ^
  %SRC% ^
  mlc_m1.png 0.5 . 50 Gray

call %PICTBAT%maxLocCont ^
  %SRC% ^
  mlc_m1b.png 2 . 50 Gray
mlc_m1.pngjpg mlc_m1b.pngjpg
call %PICTBAT%maxLocCont ^
  %SRC% ^
  mlc_m2.png 0.5 . 100 Gray

call %PICTBAT%maxLocCont ^
  %SRC% ^
  mlc_m2b.png 2 . 100 Gray
mlc_m2.pngjpg mlc_m2b.pngjpg
call %PICTBAT%maxLocCont ^
  %SRC% ^
  mlc_m3.png 0.5 . 150 Gray

call %PICTBAT%maxLocCont ^
  %SRC% ^
  mlc_m3b.png 2 . 150 Gray
mlc_m3.pngjpg mlc_m3b.pngjpg

The script also returns the name of a temporary file in mlcAVG.

Show mlcAVG:

%IMG7%magick ^
  %mlcAVG% ^
  -auto-level ^
  mlc_mlcavg.png
mlc_mlcavg.pngjpg

This image is black where there is no detail and lightest where there is most detail, so we can use it as a mask for the effect. (See also Adaptive blur and sharpen.) Working with the last example above, mlc_m3b.png:

Greatest effect in areas with detail

%IMG7%magick ^
  %SRC% ^
  -colorspace Lab ^
  -channel R -separate +channel ^
  -set colorspace sRGB ^
  mlc_m3b.png ^
  ( %mlcAVG% -auto-level ) ^
  -compose Over -composite ^
  mlc_mskd.png
mlc_mskd.pngjpg

Greatest effect in areas with no detail

%IMG7%magick ^
  %SRC% ^
  -colorspace Lab ^
  -channel R -separate +channel ^
  -set colorspace sRGB ^
  mlc_m3b.png ^
  ( %mlcAVG% -auto-level -negate ) ^
  -compose Over -composite ^
  mlc_mskdn.png
mlc_mskdn.pngjpg

JPEG source

For the source, we can use a JPEG image. However, the detail that is revealed may be JPEG artefacts:

Make a JPEG image

%IMG7%magick ^
  %SRC% ^
  -quality 50 ^
  mlc_src_jpg.jpg
mlc_src_jpg.jpg

Maximise local contrast

call %PICTBAT%maxLocCont ^
  mlc_src_jpg.jpg ^
  mlc_sj.png 0.5 . 100 Gray
mlc_sj.pngjpg

Increasing grizzle

The script makes grizzled old men even more so.

set SKIN_SRC=%PICTLIB%20130201\AGA_1201_sRGB.tiff

for /F "usebackq" %%L in (`%IMG7%magick identify ^
  -format "ss_size=%%wx%%h" ^
  %SKIN_SRC%`) do set %%L

echo ss_size = %ss_size% 
ss_size = 4924x7378 

As usual, we operate on the full-size image and create small versions for the web.

set WEBSIZE=-resize 600x600
%IMG7%magick ^
  %SKIN_SRC% ^
  -strip ^
  -colorspace Gray ^
  +write mlc_face.miff ^
  %WEBSIZE% ^
  mlc_face_sm.miff
mlc_face_sm.miffjpg
call %PICTBAT%maxLocCont ^
  mlc_face.miff ^
  mlc_face_mlc.miff 20

%IMG7%magick ^
  mlc_face_mlc.miff ^
  %WEBSIZE% ^
  mlc_face_mlc_sm.miff
mlc_face_mlc_sm.miffjpg

Show a 1:1 crop:

%IMG7%magick ^
  mlc_face_mlc.miff ^
  -crop 600x400+2800+2830 +repage ^
  mlc_eye_mlc.jpg
mlc_eye_mlc.jpg

As before, we can use %mlcAVG% as a mask to modulate the effect. We equalize the mask to get an even spread of the effect.

%IMG7%magick ^
  mlc_face.miff ^
  mlc_face_mlc.miff ^
  ( %mlcAVG% -equalize ) ^
  -compose Over -composite ^
  %WEBSIZE% ^
  mlc_mod1.jpg
mlc_mod1.jpg

From %SKIN_SRC%, an unpublished tool finds the bounding boxes for the eyes. This gives:

set leftEye=792x419+262+3157
set rightEye=1148x486+2585+2901

The script selCoordsBB.bat makes a mask, using the bounding boxes as gradient ellipses.

call %PICTBAT%selCoordsBB ^
  mlc_eyes_msk.miff ^
  %ss_size% ^
  "%leftEye% %rightEye%"

%IMG7%magick ^
  mlc_eyes_msk.miff ^
  %WEBSIZE% ^
  mlc_eyes_msk_sm.miff
mlc_eyes_msk_sm.miffjpg

We can then use this mask to apply the effect to just the eyes:

%IMG7%magick ^
  mlc_face.miff ^
  mlc_face_mlc.miff ^
  mlc_eyes_msk.miff ^
  -compose Over -composite ^
  +write mlc_eyes_comp_sm.miff ^
  %WEBSIZE% ^
  mlc_eyes_comp_sm.miff
mlc_eyes_comp_sm.miffjpg

Scripts

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

maxLocCont.bat

rem From image %1,
rem writes %2 with maximised local contrast.
rem %3 sigma to find the local mean.
rem %4 sigma to find local maxima.
rem %5 blend percentage
rem %6 Col or Gray [default Col]
rem %7 Post-process, eg -auto-level
@rem
@rem Reference:
@rem   http://im.snibgo.com/maxloccont.htm
@rem
@rem Updated:
@rem   23-December-2017 Replaced oogPower.bat with "-process oogbox".
@rem   28-November-2019 Use v7 magick
@rem

@if "%1"=="" findstr /B "rem @rem" %~f0 & exit /B 1

@setlocal enabledelayedexpansion

rem @call echoOffSave

call %PICTBAT%setInOut %1 mlc


set INFILE=%~1

if not "%2"=="" if not "%2"=="." set OUTFILE=%2

set SIG1=%3
if "%SIG1%"=="." set SIG1=
if "%SIG1%"=="" set SIG1=2

set SIG2=%4
if "%SIG2%"=="." set SIG2=
if "%SIG2%"=="" set SIG2=%SIG1%

set BLENDPC=%5
if "%BLENDPC%"=="." set BLENDPC=
if "%BLENDPC%"=="" set BLENDPC=100

set COLGR=%6
if "%COLGR%"=="." set COLGR=
if "%COLGR%"=="" set COLGR=Col

set POST_PROC=%7
if "%POST_PROC%"=="." set POST_PROC=

set TMPDIR=\temp\
set GRAY=%TMPDIR%mlc_gray.miff
set BLR=%TMPDIR%mlc_blr.miff
set MINBLR=%TMPDIR%mlc_minblr.miff
set AVG=%TMPDIR%mlc_minblr_avg.miff
set DIV=%TMPDIR%mlc_minblr_div.miff
set MAXC=%TMPDIR%mlc_maxc.miff


set "sHDRI=-depth 32 -define compose:clamp^=off -define quantum:format^=floating-point"

if %BLENDPC%==100 (
  set WR_GRAY=
) else (
  set WR_GRAY=+write %GRAY%
)

%IMG7%magick ^
  %INFILE% ^
  %sHDRI% ^
  -colorspace Lab ^
  -channel 0 -separate +channel ^
  -set colorspace sRGB ^
  %WR_GRAY% ^
  ( +clone ^
    -blur 0x%SIG1% ^
    +write %BLR% ^
  ) ^
  -compose MinusSrc -composite ^
  %MINBLR%

for /F "usebackq" %%L in (`%IMG7%magick ^
  %MINBLR% ^
  %sHDRI% ^
  -precision 19 ^
  -evaluate Abs 0 ^
  -format "maxA=%%[fx:maxima]\n" ^
  +write info: ^
  -blur 0x%SIG2% ^
  +write %AVG% ^
  -format "maxB=%%[fx:maxima]\n" ^
  info:`) do set %%L

for /F "usebackq" %%L in (`%IMG7%magick identify ^
  -precision 19 ^
  -format "mult=%%[fx:%maxA%/%maxB%]\n"
  xc:`) do set %%L

echo %0: maxA=%maxA% maxB=%maxB% mult=%mult%

%IM7DEV%magick ^
  %MINBLR% ^
  -channel RGB ^
  %sHDRI% ^
  ( %AVG% ^
    -evaluate Multiply %mult% ^
  ) ^
  -compose DivideSrc -composite ^
  -evaluate Divide 2 ^
  -evaluate Add 50%% ^
  -process 'oogbox' ^
  +channel ^
  %DIV%

%IM7DEV%magick ^
  %BLR% ^
  -channel RGB ^
  %sHDRI% ^
  %DIV% ^
  -compose Mathematics ^
    -define compose:args=0,1.0,1.0,-0.5 ^
  -composite ^
  -process 'oogbox' ^
  +channel ^
  %MAXC%

if %BLENDPC%==100 (
  set CHAN_L=%MAXC%
) else (
  set CHAN_L=%GRAY% %MAXC% -compose blend -define compose:args=%BLENDPC% -composite
)

if /I %COLGR%==Col (

  %IMG7%magick ^
    %INFILE% ^
    %sHDRI% ^
    -colorspace Lab ^
    -channel RGB -separate +channel ^
    ^( %CHAN_L% ^) ^
    -swap 0,3 ^
    +delete ^
    -combine ^
    -set colorspace Lab ^
    -colorspace sRGB ^
    %POST_PROC% ^
    %OUTFILE%

) else if /I %COLGR%==Gray (

  %IMG7%magick ^
    %sHDRI% ^
    %CHAN_L% ^
    %POST_PROC% ^
    %OUTFILE%

) else (
  echo Bad COLGR [%COLGR%]
  exit /B 1
)


call echoRestore

@endlocal & set mlcOUTFILE=%OUTFILE%& set mlcAVG=%AVG%

selCoords.bat

rem Makes a mask, white around selected coordinates, otherwise black.
rem %1 output name.
rem %2 dimensions, WxH. [default 600x400]
rem %3 quoted list of coordinate quadlets. Use "c" for percent.
rem   Each quadlet is:
rem     x, y    coordinate [each defaults to 50c]
rem     rx, ry  radii of effect [each defaults to 5c]
rem   Each quad becomes a radial gradient.
@rem
@rem Updated:
@rem   15-August-2022 for IM v7.
@rem

@if "%1"=="" findstr /B "rem @rem" %~f0 & exit /B 1

@setlocal enabledelayedexpansion

@call echoOffSave

call %PICTBAT%setInOut %1 do


set OUTFILE=%1
if "%OUTFILE%"=="." set OUTFILE=
if "%OUTFILE%"=="" set OUTFILE=sc_out.png

set DIMS=%~2
if "%DIMS%"=="." set DIMS=
if "%DIMS%"=="" set DIMS=600x400

set COORDLIST=%~3
if "%COORDLIST%"=="." set COORDLIST=
if "%COORDLIST%"=="" set COORDLIST=50c,60c,.,.,11,12,4,.

call parseXxY2 600 400 dim %DIMS%

rem set dim


:: Parse COORDLIST into gx, gy, grx, gry
::   and use these for radial gradients.

call parseCommaList "%COORDLIST%" nCoordList CoordList

rem echo nCoordList=%nCoordList%
rem set CoordList

set /A remCoord=%nCoordList%%%4

if not %remCoord%==0 (
  echo %~0: COORDLIST should have multiple of 4 entries.
  exit /B 1
)

set /A numCoord=%nCoordList%/4

%IMG7%magick ^
  -size %dim_X%x%dim_Y% ^
  xc:Black ^
  %OUTFILE%

for /L %%i in (1,1,%numCoord%) do (
  call :getQuad %%i

  if "!coord.x!"=="." set coord.x=
  if "!coord.x!"=="" set coord.x=50c

  if "!coord.y!"=="." set coord.y=
  if "!coord.y!"=="" set coord.y=50c

  if "!coord.rx!"=="." set coord.rx=
  if "!coord.rx!"=="" set coord.rx=5c

  call parseNum !coord.x! %dim_X% gx
  call parseNum !coord.y! %dim_Y% gy
  call parseNum !coord.rx! %dim_X% grx
  call parseNum !coord.ry! %dim_Y% gry

  %IMG7%magick ^
    -size %dim_X%x%dim_Y% ^
    -define gradient:center=!gx!,!gy! ^
    -define gradient:radii=!grx!,!gry! ^
    radial-gradient: ^
    %OUTFILE% ^
    -compose Lighten -composite ^
    %OUTFILE%
)

rem set coord

call echoRestore

@endlocal scOUTFILE=%OUTFILE%

@exit /B 0

::----------------------------------
:: Subroutines

:getQuad

set /A n0=(%1-1)*4
set /A n1=(%1-1)*4+1
set /A n2=(%1-1)*4+2
set /A n3=(%1-1)*4+3

set coord.x=!CoordList[%n0%]!
set coord.y=!CoordList[%n1%]!
set coord.rx=!CoordList[%n2%]!
set coord.ry=!CoordList[%n3%]!

exit /B 0

selCoordsBB.bat

rem Makes a mask, white around selected coordinates, otherwise black.
rem %1 output name.
rem %2 dimensions, WxH. [default 600x400]
rem %3 quoted list of bounding boxes.
@rem
@rem Updated:
@rem   15-August-2022 for IM v7.
@rem

@if "%1"=="" findstr /B "rem @rem" %~f0 & exit /B 1

@setlocal enabledelayedexpansion

@call echoOffSave

call %PICTBAT%setInOut %1 do


set OUTFILE=%1
if "%OUTFILE%"=="." set OUTFILE=
if "%OUTFILE%"=="" set OUTFILE=sc_out.png

set DIMS=%~2
if "%DIMS%"=="." set DIMS=
if "%DIMS%"=="" set DIMS=600x400

set BBLIST=%~3
if "%BBLIST%"=="." set BBLIST=
if "%BBLIST%"=="" set BBLIST=10x10+40+50

call parseCommaList "%BBLIST%" nBbList BbList

set /A nBbm1=%nBbList%-1


set sQuads=
for /L %%i in (0,1,%nBbm1%) do (
  echo %%i  !BbList[%%i]!

  for /F "usebackq tokens=1-4 delims=x+" %%A in ('!BbList[%%i]!') do (
    echo %%A %%B %%C %%D

    for /F "usebackq" %%L in (`%IMG7%magick identify ^
      -format "%%[fx:%%C+%%A/2],%%[fx:%%D+%%B/2],%%[fx:%%A/2],%%[fx:%%B/2]" ^
      xc:`) do set sQuads=!sQuads! %%L
  )
)

echo sQuads=[%sQuads%]

call %PICTBAT%selCoords %OUTFILE% %DIMS% "%sQuads%"

call echoRestore

@endlocal scOUTFILE=%OUTFILE%

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

%IMG7%magick -version
Version: ImageMagick 7.1.0-49 Q16-HDRI x64 7a3f3f1:20220924 https://imagemagick.org
Copyright: (C) 1999 ImageMagick Studio LLC
License: https://imagemagick.org/script/license.php
Features: Cipher DPC HDRI OpenCL 
Delegates (built-in): bzlib cairo freetype gslib heic jng jp2 jpeg jxl lcms lqr lzma openexr pangocairo png ps raqm raw rsvg tiff webp xml zip zlib
Compiler: Visual Studio 2022 (193331630)

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

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


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 4-December-2017.

Page created 17-Mar-2023 20:40:32.

Copyright © 2023 Alan Gibson.