split image horizontally into two unequal parts? - imagemagick

I have the following image:
I would like to use ImageMagick to split it horizontally into two unequal parts of 40-60% (L-R). How do I do this?

You can do that as follows in ImageMagick 6. Read the image into MPR memory and delete the original. Then use the MPR copy to crop 40% once with gravity west and crop 60% again with gravity east (that is 40% from the left side and then 60% from the right side). Write those images and then exit with no output, i.e., null:
Unix Syntax:
convert red_rect.png +repage -write mpr:img +delete \
\( mpr:img -gravity west -crop 40x100%+0+0 +repage +write left.png \) \
\( mpr:img -gravity east -crop 60x100%+0+0 +repage +write right.png \) \
null:
For Windows,
convert red_rect.png +repage -write mpr:img +delete ^
( mpr:img -gravity west -crop 40x100%+0+0 +repage +write left.png ) ^
( mpr:img -gravity east -crop 60x100%+0+0 +repage +write right.png ) ^
null:
(In .bat file, double the % to %%)
(For ImageMagick 7, change convert to magick)
Left:
Right:

Just for fun, a slightly different version:
load image
make clone, crop left side and save, delete clone
revert to original, crop right side and save
magick GhLiu.png +repage \( +clone -crop 40x100%+0+0 +repage +write left.png +delete \) -gravity east -crop 60x100%+0+0 +repage right.png

Related

How to colorize an image with multiply to add transparency to the colour with Image Magick

I would like to colorize an image with two colours, red on the left half and green on the right half but the colorize function just adds a coloured overlay to the image rather than multiplying it on. So I would like my image to look like this but it is currently looking like this. Here is the original image
My code at the moment is this:
convert normal.png \
\( -clone 0 -crop 50x100% -fill red -colorize 60% \) \
\( -clone 0 -crop 50x100%+64 -fill green -colorize 60% \) \
-delete 0 -background none -flatten result.png
I have tried adding -compose multiply -composite to the code but I just get this which has the right effect but I cannot get it to the position that I want, heres the code for that:
convert normal.png \
\( -clone 0 -crop 50x100% -fill red -colorize 70% \) \
\( -clone 0 -crop 50x100%+64 -fill green -colorize 70% \) \
-background none -compose multiply -composite result.png
One simple approach would be to assemble the red-green overlay inside parentheses, then do a multiply composite over the input image.
magick lena_circ.png -size %wx%h \
\( xc:red xc:green +append -scale 50x100% \) \
-compose multiply -channel rgb -composite result.png
That command give me this result...

Image Magick blend 2 cropped/resize images together in the middle

Hey all I have this code below that takes 2 images and merges them together with it fading in the center:
convert testingl.jpg -gravity West ^
testingr.jpg -gravity East ^
blend_mask.png -extent 1080x440 -gravity center -composite bothBlended.jpg
The above produces this:
Using this mask:
Taken from these 2 images (lowered res to fit on here):
testingl.jpg (original size 1224 x 1632)
testingr.jpg (original size 828 x 1792)
This code works great as-is. Does what I need it to do but with one exception - I am wanting to get more of each image into it. Like resize the image, crop from the center the image then take that and blend it. I need to keep the same 1080 x 440 overall size.
Do that with both would look something like this:
UPDATE 1
When running #fmw42's code:
convert ^
( testingl.jpg -resize 1080x440^ -gravity West -extent 1080x440 ) ^
( testingr.jpg -resize 1080x440^ -gravity East -extent 1080x440 ) ^
blend_mask.png -composite abc.jpg
I get this:
Your ImageMagick command does not generate your proposed output image. I think it is missing a resize and parentheses.
In Unix syntax, I need the following to get your output.
convert \
\( testingl.png -resize 1080x440^ -gravity West -extent 1080x440 \) \
\( testingr.png -resize 1080x440^ -gravity East -extent 1080x440 \) \
blend_mask.png -composite bothBlended1.jpg
or perhaps you want
convert \
\( testingl.png -resize 1080x440^ -gravity West -extent 1080x440 \) \
\( testingr.png -resize 1080x440! -gravity East -extent 1080x440 \) \
blend_mask.png -composite bothBlended2.jpg

ImageMagick, set relative size in chain of convert operators

I'd need to set the size relative to the size already set. I'd need it because my flow involves defining primitives inside other ones. Eg
convert -size 200x100 xc:black \( -size 30x40% xc:red \) -gravity West -composite out.png
That 30x40% is not working this way, it becomes pixels 30x40. I can achieve this specific goal in the first example by using resize
convert -size 200x100 xc:black \( xc:red -resize 30x40% \) -gravity West -composite out.png
In this second version, xc:red inherits the size 200x100, so -resize works as expected. Though the size of further/inner primitives are not reduced to 60x40, it remains 200x100, so in the third example, the green rectangle has orientation landscape and not portrait
convert -size 200x150 xc:blue \
\( xc:red -resize 50x100% \
\( xc:green -resize 40% \) \
-gravity Center \
-composite \
\) \
-gravity West \
-composite \
out.png
So green area is 80x60 pixels, 40% of 200x150. I'd like to somehow reset the size to the size of xc:red after resize by the time I'm introducing xc:green.
I think you are trying to create canvases whereby each one is a percentage of the the size of the previous one. There may be an easier way, but you could save each canvas (and implicitly its size) in a MPR "Magick Persistent Register" (named lump of RAM) as you create it, then recall the latest one and overwrite it each time you want to do something relative to that:
convert -gravity west -size 200x100 xc:black -write MPR:S \
\( MPR:S -resize 30x40% -fill red -colorize 100 -write MPR:S \) -composite \
\( MPR:S -resize 50x50% -fill blue -colorize 100 -write MPR:S \) -composite \
\( MPR:S -resize 50x50% -fill lime -colorize 100 \) -composite result.png
Alternatively, you could let your bash/POSIX shell do it for you inside an "arithmetic expression":
W=200
H=100
convert -gravity west -size ${W}x${H} xc:black \
\( -size $((W=W*30/100))x$((H=H*40/100)) xc:red \) -composite \
\( -size $((W=W*50/100))x$((H=H*50/100)) xc:blue \) -composite \
result.png
Be aware that the shell only deals with integer maths, so it's not going to end well if you aim for 50% of 25 pixels...

Imagemagick: compose 2 images where 1 wraps the other

I want to make a wrapping image or gif that when composed with a different image will wrap it like the wrapping image.
For example combining these two images:
Would yield this image
I don't want an imagemagick command that does this specific movement of pixels because then it wouldn't be modular.
Here is one way in Imagemagick using the -roll function. But unfortunately it does not use percent. So I have to do a separate computation in IM 6 to convert percent to pixels. In IM 7 it could be done in one command apart from setting the pct overlap and split.
Here I cut the image into 3 sections (33% each, though different amounts could be used). And then roll the middle sections by 33% to the right with wrap around.
IM 6
pct=33
rollx=`convert palmtree.png -format "%[fx:round($pct*w/100)]" info:`
convert palmtree.png \( -clone 0 -gravity north -crop 100%x$pct%+0+0 +repage \) \( -clone 0 -gravity center -crop 100%x$pct%+0+0 +repage -roll +${rollx}+0 \) \( -clone 0 -gravity south -crop 100%x$pct%+0+0 +repage \) -delete 0 -append result.png
IM 7
pct=33
magick palmtree.png -set option:rollx "%[fx:round($pct*w/100)]" \( -clone 0 -gravity north -crop 100%x$pct%+0+0 +repage \) \( -clone 0 -gravity center -crop 100%x$pct%+0+0 +repage -roll +[rollx]+0 \) \( -clone 0 -gravity south -crop 100%x$pct%+0+0 +repage \) -delete 0 -append result.png
If you do not want 33% for all, then change the pct to whatever percent you want for each part and for the roll as desired. If you want to use multiple images, then replace each -clone with the actual image you want.

Crop 40/60 with ImageMagick

I know how to use -crop 50%x100% to split an image in half (50/50) but is there a way to crop into 40/60?
If I use
convert -crop 40%x100% in.jpg out.jpg
I end up getting:
out-0.jpg // 40%
out-1.jpg // 40%
out-2.jpg // remaining %
convert in.jpg -gravity west -crop 40%x100% +repage out1.jpg
convert in.jpg -gravity east -crop 60%x100% +repage out2.jpg
I'm sure there is a more complex way, but I would just do it in two commands.
You can do it in a single command like this:
convert in.jpg \
\( +clone -gravity east -crop 60x100% +repage +write east.jpg +delete \) \
-gravity west -crop 40x100% +repage west.jpg

Resources