snibgo's ImageMagick pages

Displacement by masked SRT

A method for graduated distortion.

IM provides an operator -distort SRT to scale, rotate and translate an entire image. We might want to apply this distortion to part of the image, and graduate the effect between that part and unaffected parts.

The general method is:

  1. Make a same-size grayscale mask that is black where we want no effect, white where we want full effect, and gray for a transition between the two.
  2. Make an identity absolute displacement map.
  3. Distort the entire map as required.
  4. Blend the distorted and identity maps with the mask.
  5. Displace the image with the blended map from the previous step.

Where the mask is gray, each result pixel will come from somewhere on the straight line between the source pixel with the same coordinates, and the source pixel corresponding to the full distortion.

This method needs a two-dimensional (WWxHH) mask. For a similar method that instead uses two look-up tables (WWx1 and HHx1) see Specify scaling by LUTs.

Sample input

For the source, we use an image with a grid so we can see what is happening.

set SRC=dms_src.png

call %PICTBAT%gridOver ^
  toes.png %SRC% 10 10 1 yellow

for /F "usebackq" %%L in (`%IMG7%magick ^
  %SRC% ^
  -format "WW=%%w\nHH=%%h\n" ^
  info:`) do set %%L

echo WW=%WW% HH=%HH% 
WW=267 HH=233 
dms_src.pngjpg

Masks

We make some sample masks:

%IMG7%magick ^
  -size %WW%x%HH% ^
  gradient: ^
  dms_msk1.png
dms_msk1.pngjpg
call %PICTBAT%mEllipMsk ^
  dms_msk2.png ^
  %WW%x%HH% "0.7p,0.6p" 0.4px0.3p
dms_msk2.pngjpg
call %PICTBAT%mPntEdgeMsk ^
  dms_msk3.png ^
  %WW%x%HH% "0.7p,0.6p" . both 10 90
dms_msk3.pngjpg
%IMG7%magick ^
  toes.png ^
  -colorspace Gray ^
  -blur 0x10 ^
  -auto-level ^
  -sigmoidal-contrast 5,50%% ^
  dms_msk4.png
dms_msk4.pngjpg

Each mask has a transition between black and white. If there were no transition, the result would contain sudden "jumps" in displacement -- a lack of first-order continuity.

Masks can be made or modified using methods shown in the Gradients Cookbook.

Displace the image

The script mskdSrt.bat performs the remaining steps. It takes parameters:

Parameter Description
%1 input image to be distorted
%2 input grayscale mask
%3 output file
%4 up to 7 quoted comma-separated numbers

The comma-separated numbers are:

Parameter Description
CX,CY Centre of effect.
Each number may be suffixed with one of %cCpP,
which mean the number is a percentage or proportion of the width or height.
Default: 0.5p,0.5p, half width and height.
ScaleX,ScaleY Scale factors for the two directions.
Default: 1.
Angle Rotation, degrees clockwise.
Default: 0.
dX,dY Deltas, which are added to CX and CY to make the last two parameters to IM's -distort SRT.
Each number may be suffixed with one of %cCpP,
which mean the number is a percentage or proportion of the width or height.
Default: 0.

Trailing numbers can be omitted.

The seven parameters are very similar to the seven-parameter version of IM's -distort SRT, but:

The output will be the same size as the input. Depending on the effect, parts of the input may not be present in the output.

In the examples, we set the centre of effect to be the same as the centre of the mask.

Scale (magnifying) effect:

call %PICTBAT%mskdSrt ^
  %SRC% ^
  dms_msk1.png ^
  dms_out_s1.png ^
  "0.7p,0.6p,1.3,1.3"
dms_out_s1.pngjpg
call %PICTBAT%mskdSrt ^
  %SRC% ^
  dms_msk2.png ^
  dms_out_s2.png ^
  "0.7p,0.6p,1.3,1.3"
dms_out_s2.pngjpg
call %PICTBAT%mskdSrt ^
  %SRC% ^
  dms_msk3.png ^
  dms_out_s3.png ^
  "0.7p,0.6p,1.3,1.3"
dms_out_s3.pngjpg
call %PICTBAT%mskdSrt ^
  %SRC% ^
  dms_msk4.png ^
  dms_out_s4.png ^
  "0.7p,0.6p,1.3,1.3"
dms_out_s4.pngjpg

Scale (magnifying) in just the y-direction:

call %PICTBAT%mskdSrt ^
  %SRC% ^
  dms_msk1.png ^
  dms_out_sy1.png ^
  "0.7p,0.6p,1,1.3"
dms_out_sy1.pngjpg
call %PICTBAT%mskdSrt ^
  %SRC% ^
  dms_msk2.png ^
  dms_out_sy2.png ^
  "0.7p,0.6p,1,1.3"
dms_out_sy2.pngjpg
call %PICTBAT%mskdSrt ^
  %SRC% ^
  dms_msk3.png ^
  dms_out_sy3.png ^
  "0.7p,0.6p,1,1.3"
dms_out_sy3.pngjpg
call %PICTBAT%mskdSrt ^
  %SRC% ^
  dms_msk4.png ^
  dms_out_sy4.png ^
  "0.7p,0.6p,1,1.3"
dms_out_sy4.pngjpg

When we magnify where the mask is white, and the mask edge is black so there is no change at the image edge, then the transition area will include image reduction.

Magnify in the y-direction, and reduce in the x-direction:

call %PICTBAT%mskdSrt ^
  %SRC% ^
  dms_msk1.png ^
  dms_out_sxsy1.png ^
  "0.7p,0.6p,0.7,1.3"
dms_out_sxsy1.pngjpg
call %PICTBAT%mskdSrt ^
  %SRC% ^
  dms_msk2.png ^
  dms_out_sxsy2.png ^
  "0.7p,0.6p,0.7,1.3"
dms_out_sxsy2.pngjpg
call %PICTBAT%mskdSrt ^
  %SRC% ^
  dms_msk3.png ^
  dms_out_sxsy3.png ^
  "0.7p,0.6p,0.7,1.3"
dms_out_sxsy3.pngjpg
call %PICTBAT%mskdSrt ^
  %SRC% ^
  dms_msk4.png ^
  dms_out_sxsy4.png ^
  "0.7p,0.6p,0.7,1.3"
dms_out_sxsy4.pngjpg

Rotation effect:

call %PICTBAT%mskdSrt ^
  %SRC% ^
  dms_msk1.png ^
  dms_out_r1.png ^
  "0.7p,0.6p,1,1,20"
dms_out_r1.pngjpg
call %PICTBAT%mskdSrt ^
  %SRC% ^
  dms_msk2.png ^
  dms_out_r2.png ^
  "0.7p,0.6p,1,1,20"
dms_out_r2.pngjpg
call %PICTBAT%mskdSrt ^
  %SRC% ^
  dms_msk3.png ^
  dms_out_r3.png ^
  "0.7p,0.6p,1,1,20"
dms_out_r3.pngjpg
call %PICTBAT%mskdSrt ^
  %SRC% ^
  dms_msk4.png ^
  dms_out_r4.png ^
  "0.7p,0.6p,1,1,20"
dms_out_r4.pngjpg

In the transition area, where the mask is between black and white, we do not get a reduced rotation. This is because each destination pixel is set to an input colour that lies on a straight line between that coordinate and the full-effect distortion coordinate. As a rotation does not move pixels in straight lines, the chosen coordinate will not represent a reduced rotation that corresponds to the grayscale lightness.

The other transformations (scale and translation) do move pixels in straight lines, so partial transformations are correct.

Translation effect:

call %PICTBAT%mskdSrt ^
  %SRC% ^
  dms_msk1.png ^
  dms_out_t1.png ^
  "0.7p,0.6p,1,1,0,-0.08p,0.05p"
dms_out_t1.pngjpg
call %PICTBAT%mskdSrt ^
  %SRC% ^
  dms_msk2.png ^
  dms_out_t2.png ^
  "0.7p,0.6p,1,1,0,-0.08p,0.05p"
dms_out_t2.pngjpg
call %PICTBAT%mskdSrt ^
  %SRC% ^
  dms_msk3.png ^
  dms_out_t3.png ^
  "0.7p,0.6p,1,1,0,-0.08p,0.05p"
dms_out_t3.pngjpg
call %PICTBAT%mskdSrt ^
  %SRC% ^
  dms_msk4.png ^
  dms_out_t4.png ^
  "0.7p,0.6p,1,1,0,-0.08p,0.05p"
dms_out_t4.pngjpg

Scale, rotate and translate effect:

call %PICTBAT%mskdSrt ^
  %SRC% ^
  dms_msk1.png ^
  dms_out_srt1.png ^
  "0.7p,0.6p,1.3,1.3,20,-0.08p,0.05p"
dms_out_srt1.pngjpg
call %PICTBAT%mskdSrt ^
  %SRC% ^
  dms_msk2.png ^
  dms_out_srt2.png ^
  "0.7p,0.6p,1.3,1.3,20,-0.08p,0.05p"
dms_out_srt2.pngjpg
call %PICTBAT%mskdSrt ^
  %SRC% ^
  dms_msk3.png ^
  dms_out_srt3.png ^
  "0.7p,0.6p,1.3,1.3,20,-0.08p,0.05p"
dms_out_srt3.pngjpg
call %PICTBAT%mskdSrt ^
  %SRC% ^
  dms_msk4.png ^
  dms_out_srt4.png ^
  "0.7p,0.6p,1.3,1.3,20,-0.08p,0.05p"
dms_out_srt4.pngjpg

Scripts

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

mEllipMsk.bat

rem Makes elliptical mask, with gradation.
rem %1 output file
rem %2 WWxHH image width and height, pixels, eg 1920x1080
rem %3 quoted CX,CY ellipse centre
rem %4 ERXxERY ellipse radius width and height, pixels, eg 150x100
rem %5 angle of rotation of ellipse, degrees [0]
rem %6 RF, thickness of gradation, 0.0 < RF <= 1.0 [0.5]

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

@setlocal

rem @call echoOffSave

set OUTFILE=%1

set IMGSIZE=%2
if "%IMGSIZE%"=="." set IMGSIZE=
if "%IMGSIZE%"=="" set IMGSIZE=600x400
call parseXxY2 600 400 mem_ %IMGSIZE%

set ELL_CENT=%3
if [%ELL_CENT%]==[.] set ELL_CENT=
if [%ELL_CENT%]==[] (
  set /A CX=%mem__X%/2
  set /A CY=%mem__Y%/2
  set ELL_CENT="!CX!,!CY!"
)
call parseCommaList %ELL_CENT% mem_argc mem_argv
if ERRORLEVEL 1 exit /B 1
call propOf %mem__X% %mem_argv[0]% mem_argv[0]
if ERRORLEVEL 1 exit /B 1
call propOf %mem__Y% %mem_argv[1]% mem_argv[1]
if ERRORLEVEL 1 exit /B 1

set ELL_RAD=%~4
if "%ELL_RAD%"=="." set ELL_RAD=
if "%ELL_RAD%"=="" (
  set /A RX=%mem__X%/4
  set /A RY=%mem__Y%/4
  set ELL_RAD=!RX!x!RY!
)
call parseXxY2 %mem__X% %mem__Y% mem_er_ %ELL_RAD%

set ANG=%5
if "%ANG%"=="." set ANG=
if "%ANG%"=="0.0" set ANG=0
if "%ANG%"=="" set ANG=0

if "%ANG%"=="" (
  set ROT=
) else (
  set ROT=-distort SRT 1,%ANG%
  set ROT=-define gradient:angle=%ANG%
)

set RF=%6
if "%RF%"=="." set RF=
if "%RF%"=="" set RF=0.5

set mem_

%IMG7%magick ^
  -size %mem__X%x%mem__Y% ^
  -define gradient:center=%mem_argv[0]%,%mem_argv[1]% ^
  -define gradient:radii=%mem_er__X%,%mem_er__Y% ^
  %ROT% ^
  radial-gradient: ^
  -level 0,%%[fx:QuantumRange*%RF%] ^
  %OUTFILE%

call echoRestore

@endlocal

mPntEdgeMsk.bat

rem Make a mask white at point, black at edges.
rem %1 output file
rem %2 WWxHH image width and height, pixels, eg 1920x1080
rem %3 quoted CX,CY centre
rem %4 composite method [gm]
rem %5 smoothing: none, start, end, or both [none]
rem %6 L1, percentage start of gradation [0]
rem %7 L2, percentage start of gradation [100]

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

@setlocal

@call echoOffSave

call %PICTBAT%setInOut %1 pem

set OUTFILE=%1

set IMGSIZE=%2
if "%IMGSIZE%"=="." set IMGSIZE=
if "%IMGSIZE%"=="" set IMGSIZE=600x400
call parseXxY2 600 400 pem_ %IMGSIZE%

set CENT=%3
if [%CENT%]==[.] set CENT=
if [%CENT%]==[] (
  set CX=0.5
  set CY=0.5
  set CENT="!CX!,!CY!"
)
call parseCommaList %CENT% pem_argc pem_argv
if ERRORLEVEL 1 exit /B 1
call propOfProp %pem__X% %pem_argv[0]% pem_argv[0]
if ERRORLEVEL 1 exit /B 1
call propOfProp %pem__Y% %pem_argv[1]% pem_argv[1]
if ERRORLEVEL 1 exit /B 1

set WW=%pem__X%
set HH=%pem__Y%

set CX=%pem_argv[0]%
set CY=%pem_argv[1]%

set pem_

set P1h=%CX%
set S1h=1/%CX%
set S2h=1/(%CX%-1)

set P1v=%CY%
set S1v=1/%CY%
set S2v=1/(%CY%-1)

set MTHD=%4
if "%MTHD%"=="." set MTHD=
if "%MTHD%"=="" set MTHD=gm

set SMTH=%5
if "%SMTH%"=="." set SMTH=
if "%SMTH%"=="" set SMTH=none

set L1=%6
if "%L1%"=="." set L1=
if "%L1%"=="" set L1=0

set L2=%7
if "%L2%"=="." set L2=
if "%L2%"=="" set L2=100

set sLEV=
if %L1% NEQ 0 if %L2% NEQ 100 (
  set sLEV=-level %L1%%%,%L2%%%
)

if /I "%MTHD%"=="Darken" (
  set COMPOS=-compose Darken -composite
) else if /I "%MTHD%"=="Lighten" (
  set COMPOS=-compose Lighten -composite
) else if /I "%MTHD%"=="Mean" (
  set COMPOS=-evaluate-sequence Mean
) else if /I "%MTHD%"=="Multiply" (
  set COMPOS=-compose Multiply -composite
) else if /I "%MTHD%"=="gm" (
  set COMPOS=-compose Multiply -composite -evaluate Pow 0.5
) else (
  echo %0: Bad MTHD [%MTHD%]
  exit /B 1
)

if /I "%SMTH%"=="none" (
  set sSMTH=
) else if /I "%SMTH%"=="start" (
  set sSMTH=-function sinusoid 0.25,-90,1,1
) else if /I "%SMTH%"=="end" (
  set sSMTH=-function sinusoid 0.25,0,1,0
) else if /I "%SMTH%"=="both" (
  set sSMTH=-function sinusoid 0.5,-90,0.5,0.5
) else (
  echo %0: Bad SMTH [%SMTH%]
  exit /B 1
)

%IMG7%magick ^
  ( -size 1x%WW% gradient: -rotate 90 ^
    -fx "u<%P1h%?u*%S1h%:1+(u-%P1h%)*%S2h%" ^
    %sSMTH% ^
    -scale "%WW%x%HH%^!" ^
  ) ^
  ( -size 1x%HH% gradient: -flip ^
    -fx "u<%P1v%?u*%S1v%:1+(u-%P1v%)*%S2v%" ^
    %sSMTH% ^
    -scale "%WW%x%HH%^!" ^
  ) ^
  %COMPOS% ^
  %sLEV% ^
  %OUTFILE%

call echoRestore

@endlocal

parseCommaList.bat

rem Given %1 is a (quoted) comma- or space-separated list,
rem sets environment variables %2 to the number of values
rem and %3 (as an array) to the values.

set LIST=%~1

set pclNUM=%2
if "%pclNUM%"=="." set pclNUM=
if "%pclNUM%"=="" set pclNUM=argc

set pclVALS=%3
if "%pclVALS%"=="." set pclVALS=
if "%pclVALS%"=="" set pclVALS=argv

call :doParse %LIST%
set /A %pclNUM%=%pclN%

rem echo %0: pclVALS=%pclVALS%

exit /B 0

:: --------------------------------------------
:: Subroutine

:doParse

set pclN=0
:loop
if "%1"=="" exit /B 0

rem echo %0: 1=%1 2=%2 3=%3
set %pclVALS%[%pclN%]=%1
set /A pclN+=1
shift /1

goto loop

exit /B 0

parseXxY2.bat

rem Parses %4, default %1 and %2. Returns %3_X and %3_Y.
@rem
@rem %1 and %2 can be expressions such as "600-1".
@rem
@rem %4 is one of these formats:
@rem   {blank}
@rem   .
@rem   {number}
@rem   {number}x
@rem   x{number}
@rem   {number}x{number}
@rem
@rem Each number can be suffixed with %, c or p or C or P.
@rem
@rem Updated:
@rem   4-October-2022 for IM v7.
@rem   20-August-2023 Put %1 and %2 in parentheses so they can be expressions.
@rem

@set pxxy=%4
@set pxxyFirst=%pxxy:~0,1%
@rem echo pxxyFirst=%pxxyFirst%

@if "%pxxyFirst%"=="x" set pxxy=%1%pxxy%

@if "%pxxy%"=="." set pxxy=
@if "%pxxy%"=="" set pxxy=%1x%2

@for /F "usebackq tokens=1-2 delims=xX" %%X in ('%pxxy%') do @(
  @rem echo %%X,%%Y
  @set pxxyX=%%X
  @set pxxyY=%%Y
)
@if "%pxxyY%"=="" set pxxyY=%2


set CH_LAST=%pxxyX:~-1%

if "%CH_LAST%"=="^%" set CH_LAST=c

if /I "%CH_LAST%"=="c" (
  for /F "usebackq" %%L in (`%IMG7%magick identify ^
    -precision 19 ^
    -format "pxxyX=%%[fx:(%1)*%pxxyX:~0,-1%/100]" ^
    xc:`) do set %%L

) else if /I "%CH_LAST%"=="p" (
  for /F "usebackq" %%L in (`%IMG7%magick identify ^
    -precision 19 ^
    -format "pxxyX=%%[fx:(%1)*%pxxyX:~0,-1%]" ^
    xc:`) do set %%L
)


set CH_LAST=%pxxyY:~-1%

if "%CH_LAST%"=="^%" set CH_LAST=c

if /I "%CH_LAST%"=="c" (
  for /F "usebackq" %%L in (`%IMG7%magick identify ^
    -precision 19 ^
    -format "pxxyY=%%[fx:(%2)*%pxxyY:~0,-1%/100]" ^
    xc:`) do set %%L

) else if /I "%CH_LAST%"=="p" (
  for /F "usebackq" %%L in (`%IMG7%magick identify ^
    -precision 19 ^
    -format "pxxyY=%%[fx:(%2)*%pxxyY:~0,-1%]" ^
    xc:`) do set %%L
)


@rem echo pxxyX=%pxxyX% pxxyY=%pxxyY%

set %3_X=%pxxyX%
set %3_Y=%pxxyY%

propOf.bat

rem Given %1 is a number,
rem %2 is a number possibly suffixed with % or c or p or C or P,
rem sets variable %3 to result.
@rem All can be floating-point.
@rem
@rem Eg if %1 is 300
@rem then %2 might be 60 or 20% or 20c or 0.2p, and the result is 60.
@rem
@rem See also propOf.bat
@rem
@rem Updated:
@rem   17-September-2022
@rem

setlocal

set VAR_S=%2
set OUTV=%VAR_S%
set CH_LAST=%VAR_S:~-1%

if "%CH_LAST%"=="^%" set CH_LAST=c

if /I "%CH_LAST%"=="c" (
  for /F "usebackq" %%L in (`%IMG7%magick identify ^
    -precision 16 ^
    -format "OUTV=%%[fx:%1*%VAR_S:~0,-1%/100]" ^
    xc:`) do set %%L

) else if /I "%CH_LAST%"=="p" (
  for /F "usebackq" %%L in (`%IMG7%magick identify ^
    -precision 16 ^
    -format "OUTV=%%[fx:%1*%VAR_S:~0,-1%]" ^
    xc:`) do set %%L
)

echo OUTV=%OUTV%

@endlocal & set %3=%OUTV%

propOfProp.bat

rem Like propOf.bat but result is proportion of %1.

rem Given %1 is a number,
rem %2 is a number possibly suffixed with % or c or p or C or P,
rem sets variable %3 to result.
@rem All can be floating-point.
@rem
@rem Eg if %1 is 300
@rem then %2 might be 60 or 20% or 20c or 0.2p, and the result is 0.2.
@rem
@rem Updated:
@rem   4-October-2022 for IM v7.
@rem

setlocal

set VAR_S=%2
set OUTV=%VAR_S%
set CH_LAST=%VAR_S:~-1%

if "%CH_LAST%"=="^%" set CH_LAST=c

if /I "%CH_LAST%"=="c" (
  for /F "usebackq" %%L in (`%IMG7%magick identify ^
    -precision 16 ^
    -format "OUTV=%%[fx:%VAR_S:~0,-1%/100]" ^
    xc:`) do set %%L

) else if /I "%CH_LAST%"=="p" (
  set OUTV=%VAR_S:~0,-1%
) else (
  for /F "usebackq" %%L in (`%IMG7%magick identify ^
    -precision 16 ^
    -format "OUTV=%%[fx:%VAR_S%/%1]" ^
    xc:`) do set %%L
)

echo OUTV=%OUTV%

@endlocal & set %3=%OUTV%

mskdSrt.bat

rem %1 input image to be distorted
rem %2 input grayscale mask, white for full effect
rem %3 output file
rem %4 up to 7 quoted comma-separated numbers:
rem     X,Y centre of effect
rem     ScaleX,ScaleY
rem     Angle
rem     dX,dY

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

@setlocal

rem @call echoOffSave

call %PICTBAT%setInOut %1 ms

set INMSK=%2

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

set CSNUMS=%~4
if "%CSNUMS%"=="." set CSNUMS=
if "%CSNUMS%"=="" set CSNUMS=0.5p,0.5p

set WW=
for /F "usebackq" %%L in (`%IMG7%magick identify ^
  -format "WW=%%w\nHH=%%h\nW_2=%%[fx:w/2]\nH_2=%%[fx:h/2]\n" ^
  %INFILE%`) do set %%L

if "%WW%"=="" (
  echo %0: Can't read INFILE [%INFILE%]
  exit /B 1
)

call parseCommaList "%CSNUMS%" ms_argc ms_argv

if "%ms_argv[0]%"=="" set %ms_argv[0]=%W_2%
if "%ms_argv[1]%"=="" set %ms_argv[1]=%H_2%
if "%ms_argv[2]%"=="" set %ms_argv[2]=1
if "%ms_argv[3]%"=="" set %ms_argv[3]=1
if "%ms_argv[4]%"=="" set %ms_argv[4]=0
if "%ms_argv[5]%"=="" set %ms_argv[5]=0
if "%ms_argv[6]%"=="" set %ms_argv[6]=0

if ERRORLEVEL 1 exit /B 1
call propOf %WW% %ms_argv[0]% ms_argv[0]
if ERRORLEVEL 1 exit /B 1
call propOf %HH% %ms_argv[1]% ms_argv[1]
if ERRORLEVEL 1 exit /B 1
call propOf %WW% %ms_argv[5]% ms_argv[5]
if ERRORLEVEL 1 exit /B 1
call propOf %HH% %ms_argv[6]% ms_argv[6]
if ERRORLEVEL 1 exit /B 1

set ms_

set SSFACT=2

set ms_argv[5a]=%%[fx:!ms_argv[0]!*%SSFACT%+!ms_argv[5]!*%SSFACT%]
set ms_argv[6a]=%%[fx:!ms_argv[1]!*%SSFACT%+!ms_argv[6]!*%SSFACT%]

for %%I in (0,1,5,6) do (
  set ms_argv[%%I]=%%[fx:!ms_argv[%%I]!*%SSFACT%]
)


set ms_


%IMG7%magick ^
  %INFILE% ^
  -resize 200%% ^
  -set option:MYSIZE %%[fx:w]x%%[fx:h] ^
  ( +clone ^
    -sparse-color bilinear ^
0,0,#008,^
0,%%[fx:h-1],#0f8,^
%%[fx:w-1],0,#f08,^
%%[fx:w-1],%%[fx:h-1],#ff8 ^
    +write mpr:IDENT ^
    +delete ^
  ) ^
  ( mpr:IDENT ^
    ( +clone ^
      -distort SRT %ms_argv[0]%,%ms_argv[1]%,%ms_argv[2]%,%ms_argv[3]%,%ms_argv[4]%,%ms_argv[5a]%,%ms_argv[6a]% ^
    ) ^
    ( %INMSK% -resize 200%% ) ^
    -compose Over -composite ^
  ) ^
  -compose Distort -composite ^
  -resize 50%% ^
  %OUTFILE%

call echoRestore

@endlocal

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

%IMG7%magick -version
Version: ImageMagick 7.1.1-15 Q16-HDRI x64 a0a5f3d:20230730 https://imagemagick.org
Copyright: (C) 1999 ImageMagick Studio LLC
License: https://imagemagick.org/script/license.php
Features: Cipher DPC HDRI OpenCL OpenMP(2.0) 
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 (193532217)

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 dispmsksrt.h1. To re-create this web page, execute "procH1 dispmsksrt".


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 10-July-2019.

Page created 29-Sep-2023 01:50:33.

Copyright © 2023 Alan Gibson.