Crop and merge two images using ImageMagick - imagemagick

I am trying to use ImageMagick to place one image (Poseidon_map01.jpg in my code below) in the top-left corner of another (zzOcean Backdrop.png) then crop the resulting image down to 1280x720.
This is the command I currently have:
".\ImageMagick-7.0.8-12-portable-Q16-x64\magick.exe" ".\Raw\zzOcean Backdrop.png" ".\Raw\Poseidon_map01.jpg" -gravity northwest -composite -crop 1280x720>! +repage ".\1280x720\Poseidon_map01.jpg"
The problem is that this command is cutting the composited image into 1280x720 pieces then saving all of those pieces with the names Poseidon_map01-1.jpg to Poseidon_map01-48.jpg. Poseidon_map01-1.jpg is the top-left corner of the composited image and this is the piece that I want to keep. I want to discard the rest of the composite. Does anyone know what I have to change in my command to make this happen? Thanks.

In Imagemagick crop, if you do not include the +X+Y offsets, it will crop as many pieces as it can given the size you specify. That is called tiled cropping. So use -crop WxH+X+Y>!
See https://imagemagick.org/Usage/crop/#crop
".\ImageMagick-7.0.8-12-portable-Q16-x64\magick.exe" ".\Raw\zzOcean Backdrop.png" ".\Raw\Poseidon_map01.jpg" -gravity northwest -composite -crop 1280x720+0+0>! +repage ".\1280x720\Poseidon_map01.jpg"
I am not a windows user and syntax may vary some. You may need to escape the > or ! with ^ on windows or put double quotes around the whole crop set of arguments. Keep that in mind, if this does not work. See https://imagemagick.org/Usage/windows/

Related

How can I specify a background in Imagemagick mogrify based on the colour of an existing pixel?

I want to use mogrify to set the background colour of a large number of images to be whatever colour is at a specific pixel, to make them square.
The vast majority have a single colour in the image background, or are photos in front of a single colour (so with only slight variations from shadows, etc.).
(The specific purpose in this case is to make the images all the same size and square for StyleGAN2-ADA training, so I want to avoid big "letterbox" rectangles where possible as it would be seen by the discriminator as relevant to the image, where a more faded-in background that approximately matches would be more likely to be ignored. Specifically, I have thousands of pictures of single dolls and action figures from various sources, some of which are "trimmed out" to have a truly solid colour background, others of which are against solid colour tables/walls/etc, for instance, from eBay images and such.)
Since they do not all have the same colour in the image background (the colour in the image, as opposed to the 'background colour' setting as per ImageMagick's jargon), I need to sample a pixel and set the background, but I can't figure out how. I tried things based on methods used to set the whole image to one colour, to no avail.
I have tried:
mogrify -verbose -resize 1024x1024 -gravity center -background 'p{10,10}' -extent 1024x1024 -resize 256x256 *.jpg
and
mogrify -verbose -resize 1024x1024 -gravity center -background "%[pixel:p{10,10}]" -extent 1024x1024 -resize 256x256 *.jpg
and neither works. I can't find any other possibilities in the documentation.
EDITED TO ADD: While testing various commands I came across a way to modify your original command to make it work on ImageMagick versions as far back as IMv6.8.
mogrify -resize 1024x1024 -set background "%[pixel:p{10,10}]" \
-gravity center -extent 1024x1024 -resize 256x256 *.jpg
The significant difference is setting the background color in an unusual way. Instead of the normal option -background <color>, this command uses -set background <color>. Then it behaves as expected using that +10+10 color as the background in the "mogrify" command.
For ImageMagick v7 use magick mogrify instead of just mogrify.
The following was my original answer. The suggestion for IMv6 "convert" may be quite useful for some workflows, but the answer above seems to be the simplest, most direct route.
PREVIOUS ANSWER:
ImageMagick v6 won't do that inline parsing of the color, but there are ways to get the same result, usually with IM's "convert" in a "for" loop in your shell. I don't know which shell you're using so I don't know how you'd write a "for" loop, but running this command inside the loop on each image should give you the results you described...
convert $image -resize 1024x1024 ( +clone -crop 1x1+10+10 ) +swap \
-resize 1024x1024 -gravity center -composite -resize 256x256 $image
That reads in the image, resizes it, makes a clone inside the parentheses, and extracts that pixel at +10+10. After the parentheses that single pixel get resized to a 1024x1024 square. Then setting the gravity to "center" and compositing the input image over that colored square gives you the result you described.

Rotate and crop an image, while keeping its original size

I have a JPG image with a known size of 3072x2048. Now I want to rotate that image by any degrees (e.g. 45), while keeping its original size. Thus - using ImageMagick on the command line - I first want to rotate, then crop the image, like this:
convert -rotate 45 -gravity center -crop 3072x2048 +repage original.jpg rotated-45.jpg
By using -gravity center I specify to crop the center part of the image, which is what I want. This operation produces four output images:
rotated-45-0.jpg
rotated-45-1.jpg
rotated-45-2.jpg
rotated-45-3.jpg
The first image rotated-45-0.jpg is exactly the final image I want to get. The other three I don't need. I could delete them, but I think it would be nicer to not generate these "extra" images in the first place. So I thought I could do it with this command instead:
convert -rotate 45 -gravity center -crop 3072x2048+0+0 +repage original.jpg rotated-45.jpg
This only produces one output image, however, now the top-left corner of the image is being cropped. So apparently the -gravity center is not used any longer.
Any ideas what I am missing here?
Using ImageMagick you can rotate an image any number of degrees while keeping the original canvas dimensions using "-distort SRT"...
convert original.jpg -virtual-pixel black -distort SRT 45 rotated-45.jpg
Use "-virtual-pixel" to specify how you want to handle the parts that were outside the canvas before the rotation. In this example I used "black". You can use black, white, background, tile, mirror, or none.

crop / swap parts of image with magick mogrify

I am trying to crop and swap different parts of a big 800x800 image and re-create 800x800 image using imagemagick with this command.
magick mogrify titli.gif -crop 2x4# +repage -reverse -append -path converted titli.gif
my problem is "-append" creates tall image (400x1600) & "+append" creates wide image (3200x200)
How can I get a large image of original size 800x800 but with cropped and swapped (reversed) parts set in "mosaic or tiled" style...
If I understand the question, you shouldn't need "mogrify" to do that. Just "magick" should accomplish that task.
It looks like you'll have to crop the image into 8 pieces, reverse them, and "-append" them vertically as you've done.
Then after that, and in the same command, you'll need to crop that result in half vertically and "+append" those two pieces horizontally to get the 800x800 output.
This example command shows how it works...
magick in.png -crop 2x4# -reverse -append -crop 1x2# +append out.png
If you're doing any more operations within the same command you'll probably want to use "+repage" after the "+append" to reset the image geometry back to WxH+0+0.

Imagemagick crop into tiles and force all to have same size?

I want to crop an image into 2048x2048 slices like this:
convert big.jpg -crop 2048x2048 tile%04d.jpg
However, if the original is for example 5764x3888, the tiles end up like this:
2048x2048
2048x2048
1668x2048
2048x1840
2048x1840
1668x1840
How can I force each tile to be 2048x2048 and sit in the upper left corner?
I would prefer if I could do this in just a command line without a script, since I will do this on both Mac and Windows.
Or do I have to make the original image 6144x4096 first, so it's evenly divisible by 2048 and then crop it?
Thanks!
I would use this:
convert big.jpg -crop 2048x2048 -background blue -gravity northwest -extent 2048x2048 tile%04d.jpg
Obviously choose a different colour background to suit your needs, and choose a different -gravity to determine where the cropped image sits on its extended canvas.

How to apply tile to specifics cordinates and size?

This is what I want to do:
1- I have this image (transparent on the center)
2- I have this "pattern"
3- I want to apply this pattern to a specific X and Y and also specify the size of the repitition. The expected result should look something like this:
Do you know how I can accomplish that?
Thank you.
The easiest way is probably to create the textured rectangle then place it over the top of the circle using composite.
convert circle.png \( -size 88x61 tile:texture.png \) -geometry +50+63 -composite result.png
[edit] If you want the texture underneath, you could do this:
convert -size 200x200 xc:transparent
-page +50+63 -size 88x61 tile:texture.png
-page +0+0 circle.png
-layers flatten result.png
I think that's self explanatory but 88x61 is the size of the rectangle, 200x200 is the size of the circle image, +50+63 is the location you want it to be placed at, circle.png is the transparent circle image, and texture.png is the seamless pattern.
I tested this with your images and it worked, but the pattern you included doesn't seem to be the full seamless version so it didn't come out looking exactly like your expected result.

Resources