9-slice scaling with imagemagick? - image-processing

Given an input image of dimensions 120x120 pixels,
I'd like to use imagemagick to perform
9-slice scaling.
keep the image within the box bounded by
top-left coordinate (10,10)
and bottom right coordinate (110,110) unscaled,
This centre section is 100x100 pixels.
The left side scale by a given factor,
say 3, so this would go from 10x100 pixels to 30x100 pixels
The right side scale by a given factor,
say 2, so this would go from 10x100 pixels to 20x100 pixels
The top and bottom side both scale by a given factor,
say 1.5, so these would go from 100x10 to 100x15 each.
The four corners would scale to fit the new dimensions of the new top, right, bottom, and left sides.
Something similar to
(except in my case the centre element, "5", doesn't need to change)
How can I perform this operation using imagemagick?
(Suggestions for any other CLI tool available on Linux also welcome!)

Using ImageMagick you can approach this as a series of isolated cropping and resizing operations. Here's an example command...
magick input.png -write mpr:img0 +delete ^
( mpr:img0 -gravity west -crop 10x+0+0 -resize 300x100% ) ^
( mpr:img0 -shave 10x0 ) ^
( mpr:img0 -gravity east -crop 10x+0+0 -resize 200x100% ) ^
+append +repage -write mpr:img0 +delete ^
( mpr:img0 -gravity north -crop x10+0+0 -resize 100x150% ) ^
( mpr:img0 -shave 0x10 ) ^
( mpr:img0 -gravity south -crop x10+0+0 -resize 100x150% ) ^
-append +repage result.png
This command will take a 10 pixel wide strip from the left and right sides, widen the left by 300% and the right by 200%, and re-append them to the center.
Then it follows by taking a 10 pixel high strip from the top and bottom, resizing both their heights to 150%, and re-appending them to the center section.
The corners get properly scaled because they go through both the horizontal and vertical resizing operations.
The command uses IMv7 in Windows CLI syntax. For a Windows BAT script you need to double the percent signs "%%".
To make it work on a *nix system change the continued-line carets "^" to backslashes "\" and escape the parentheses with backslashes "\(...\)".
To use it with IMv6 change "magick" to "convert".

Here is one way to do that in ImageMagick 6 (Unix syntax).
Input:
convert logo.png -write mpr:img +delete \
\( \
\( mpr:img -gravity northwest -crop 10x10+0+0 +repage -resize 300x150%! \) \
\( mpr:img -gravity north -crop 100x10+0+0 +repage -resize 100x150%! \) \
\( mpr:img -gravity northeast -crop 10x10+0+0 +repage -resize 200x150%! \) \
+append \
\) \
\( \
\( mpr:img -gravity west -crop 10x100+0+0 +repage -resize 300x100%! \) \
\( mpr:img -gravity center -crop 100x100+0+0 +repage \) \
\( mpr:img -gravity east -crop 10x100+0+0 +repage -resize 200x100%! \) \
+append \
\) \
\( \
\( mpr:img -gravity southwest -crop 10x10+0+0 +repage -resize 300x150%! \) \
\( mpr:img -gravity south -crop 100x10+0+0 +repage -resize 100x150%! \) \
\( mpr:img -gravity southeast -crop 10x10+0+0 +repage -resize 200x150%! \) \
+append \
\) \
-append \
logo_result.png
Result:
If using ImageMagick 7, then change convert to magick.
If on Windows, change the line endings \ to ^ and remove the \ from the ( and ). If in .bat file, double the % to %%.

Related

magick command gives unable to open image error

I am trying to run below command from my command prompt and it gives me following error:
magick billadd1.jpg -type TrueColorAlpha billadd2.jpg -type TrueColorAlpha \( -clone 0,1 -compose difference -composite -morphology dilate disk:10 \) \( -clone 0 -fill yellow -colorize 100 -channel a -evaluate set 50% +channel \) \( -clone 0,3,2 -compose over -composite +write 1.jpg \) \( -clone 1,3,2 -compose over -composite +write 2.jpg \) null:
magick: unable to open image '\(': No such file or directory # error/blob.c/OpenBlob/3537.
magick: no decode delegate for this image format `' # error/constitute.c/ReadImage/562.
Also, how to run this command from java using im4java?
Note i am using imagemagick veriosn7
The Windows syntax is different from Unix/Linux syntax. Your command is currently in Unix/Linux syntax:
magick billadd1.jpg -type TrueColorAlpha billadd2.jpg -type TrueColorAlpha \
\( -clone 0,1 -compose difference -composite -morphology dilate disk:10 \) \
\( -clone 0 -fill yellow -colorize 100 -channel a -evaluate set 50% +channel \) \
\( -clone 0,3,2 -compose over -composite +write 1.jpg \) \
\( -clone 1,3,2 -compose over -composite +write 2.jpg \) null:
Which, when converted to Windows, probably becomes:
magick billadd1.jpg -type TrueColorAlpha billadd2.jpg -type TrueColorAlpha ^
( -clone 0,1 -compose difference -composite -morphology dilate disk:10 ) ^
( -clone 0 -fill yellow -colorize 100 -channel a -evaluate set 50%% +channel ) ^
( -clone 0,3,2 -compose over -composite +write 1.jpg ) ^
( -clone 1,3,2 -compose over -composite +write 2.jpg ) null:
So, the rules are something like this to go from Linux to Windows:
remove backslashes before parentheses
change backslash line-continuation character to caret (^)
double up any percent signs
change any single quotes to double-quotes
There are some more detailed notes here.

Convert Magick Command to Magick.Net Code

I want to convert command below to Magick.Net Code.
convert sunset_lake.png \
\( -background none -pointsize 24 -fill white label:"TESTING" -rotate 20 -write mpr:tile +delete \) \
\( +clone -tile mpr:tile -draw "color 0,0 reset" \) \
-compose over -composite sunset_lake_tile_text.png
I am not sure what is the corresponding code for -write mpr:tile +delete and mpr:tile -draw "color 0,0 reset".
Any help would be appreciated.

How to create watermark like shutterstock with imagemagick

I want to create image watermark like Shutterstock. I have tried but not able to replicate it. I tried with the following command. The issue is for me is i not able to add diagonal random text to image as Shutterstock does. I have tried many options with no luck.
infile="zoom.jpg"
ww=$(convert -ping "$infile" -format "%[fx:w-1]" info:)
hh=$(convert -ping "$infile" -format "%[fx:h-1]" info:)
convert "$infile" \
-fill "graya(100%,0.75)" \
-draw "line 0,0 $ww,$hh line $ww,0 0,$hh" -alpha off \
-fill "graya(50%,0.25)" \
tile_aqua_500_text_x_text.jpg
composite -dissolve 35 -gravity center logo.png tile_aqua_500_text_x_text.jpg tile_aqua_500_text_x_text.jpg
convert -background none -size 220x320 xc:none -font DejaVu-Sans-Bold -pointsize 30 \
-gravity North -draw "rotate -22 fill grey text 20,10 'knot9'" \
-gravity West -draw "rotate -27 fill grey text 5,15 '89898989'" \
miff:- |\
composite -dissolve 70 -tile - tile_aqua_500_text_x_text.jpg tile_aqua_500_text_x_text.jpg
width=`identify -format %w tile_aqua_500_text_x_text.jpg`; \
convert -background '#0008' -fill white -gravity center -size ${width}x30 -pointsize 10 -font DejaVu-Sans-Bold\
caption:"\nThis image is Copyrighted by Knot9 \n www.knot9.com | Image Id: 89898989\n" \
tile_aqua_500_text_x_text.jpg +swap -gravity south -composite tile_aqua_500_text_x_text.jpg
My Output is
Requirement is
In ImageMagick, you can do the following. Create a small text image on a transparent background using label:. Rotate it. Pad it to control the spacing. Tile it out to fill the image. Then composite the tiled out image over your background image.
Image:
convert lena.png \
\( -size 100x -background none -fill white -gravity center \
label:"watermark" -trim -rotate -30 \
-bordercolor none -border 10 \
-write mpr:wm +delete \
+clone -fill mpr:wm -draw 'color 0,0 reset' \) \
-compose over -composite \
lena_watermark.png
If using ImageMagick 7, then change convert to magick
See https://imagemagick.org/Usage/canvas/#tile_memory for tiling

Misalignment of a position after resizing an image with ImageMagick

I want to resize several images and overlay them on a background image by using Imagemagick.
I wrote following code.
convert -size 500x1000 xc:white \
-page +100+200 \( aaa.jpg -resize 50x \) \
-page +200+300 \( bbb.jpg -resize 50x \) \
..............
-layers flatten flatten_img.jpg"
I wanted to put the "aaa.jpg" on (100,200),
and the "bbb.jpg" on (200,300),
but the position of them were misaligned.
For example, the "aaa.jpg" was positioned on (33,66).
If I didn't resize them before doing "-page",
that is,
convert -size 500x1000 xc:white \
-page +100+200 aaa.jpg \
-page +200+300 bbb.jpg \
......
-layers flatten flatten_img.jpg"
the position of them were right.
How Can I put them in the right places ?
Thank you in advance.
I can solve the problem.
convert -size 500x1000 xc:white \
\( aaa.jpg -resize 50x50 -repage +50+100 \) \
\( bbb.jpg -resize 100x100 -repage +100+200 \) \
-layers flatten final.jpg

How to use the first image sequence in a multiple cropping process in ImageMagick

I want resize, crop and concatenate really many images.
I don't want to write the intermediate results to disk, just the final result only.
My script is :
montage -mode concatenate \
\( test.jpg -thumbnail "150x100>" -background white -gravity center -extent 150x100 -page 150x100+0+0 \) \
\( -clone 0 -crop 23x16+80+0 -background white -extent 23x16 \) \
\( -clone 0 -crop 23x16+16+87 -background white -extent 23x16 \) \
...
-delete 0 -quality 100% thumb.jpg
I got always the following error:
montage.im6: geometry does not contain image `test.jpg' # warning/transform.c/CropImage/574.
I tried to use the "repage" and "page" parameters, but I was unsuccessful with them.
Any idea?
Update
Mark asked for examples. So I try to write down the different steps which I would like to merge in one single step:
convert logo: test.jpg
convert test.jpg -thumbnail "150x100>" -background white -gravity center -extent 150x100 -page 150x100+0+0 test.resized.jpg
montage -mode concatenate test.resized.jpg \
\( -clone 0 -crop 23x16+80+20 -background white -extent 23x16 \) \
\( -clone 0 -crop 23x16+92+74 -background white -extent 23x16 \) \
\( -clone 0 -crop 23x16+100+80 -background white -extent 23x16 \) \
-delete 0 -quality 100% result.thumb.jpg
And the results:
you can see here the expected result.
http://phspring.nl/stackoverflow28101334.jpg
I must admit this one has me mystified! I cannot get it to work how you tried, or how I would want to do it at all. I found that I can only make it work if I add a +repage but if I do that it forgets the -extent, so I keep ending up with 2 commands. I also find that +clone refuses to work in place of -clone 0 for this example, which also mystifies me.
The only way I can make it work, and avoid the intermediate file is to stream the output of the first convert to the second one.
convert logo: -resize "150x100>" -background white -gravity center -extent 150x100 JPG:- | \
convert JPG:- \
\( -clone 0 -crop 23x16+80+20 \) \
\( -clone 0 -crop 23x16+92+74 \) \
\( -clone 0 -crop 23x16+100+80 \) \
-delete 0 +append out.jpg

Resources