Creating Random Seamless Pattern using Imagemagick - imagemagick

Using imagemagick I am trying to create a similar image like this tile pattern:
OUTPÙT
From this image:
SOURCE
I can do simple tile by using:
convert table.png -write mpr:tile +delete -size 3000x3000 tile:mpr:tile table.jpg
However, is there any way to achieve the above result using imagemagick

Using ImageMagick you'll need to do some duplicating, rotating, and appending to get that result. Here's a simple IMv7 command that creates the tile with four tables...
magick table.jpg ( +clone -rotate 90 ) +append ( +clone -rotate 180 ) -append tabletile.png
That reads in the image of the single table, makes a clone inside the parentheses and rotates it 90 degrees.
After the parentheses it appends that rotated clone horizontally to the original input image using "+append".
Then inside parentheses again it makes a clone of that appended result and rotates it 180 degrees.
Outside that parentheses it appends those two pieces vertically with "-append".
Finish by writing the result to the output file.
If you're using IMv6 use "convert" instead of "magick".
If you're running that command on a *nix OS you'll probably need to escape those parentheses with backslashes "\(...\)".

Related

Compose multiple regions of an image into a target

I'm trying to use ImageMagick to compose different pieces of a rendered PDF into a target. E.g., I want to have ImageMagick render the PDF at 300dpi, then create a 300x400 pixel output image, then take from the PDF the area 10x20+30+40 and place it in the target (300x400 pixel image) at 12,34. Then take another (and a third and fourth) chunk at different coordinates with different sizes and place them at different places.
I cannot seem to figure out how to do this in one go, and doing it in multiple runs always re-renders the PDF and takes awfully long. Is this even possible?
Here's an idea of how you can approach this. It uses the MPR or "Memory Program Register" that Fred suggested in the comments. It is basically a named chunk of memory that I write into at the start and which I recall later when I need it.
Here is a rather wonderful start image from the Prokudin-Gorskii collection:
The code resizes the image and saves a copy in the MPR. Then, takes a copy of the MPR, crops out a head, resizes it and composites the resized result onto the resized original at a different location and then repeats the process for another head.
magick Prokudin.png -resize 300x400\! -write MPR:orig \
\( MPR:orig -crop 50x50+180+84 -resize 140x140 \) -geometry +10+240 -compose src-over -composite \
\( MPR:orig -crop 40x40+154+184 \) -geometry +40+100 -compose src-over -composite \
result.png
If you have trouble understanding it, try running it with the second or third line omitted so it just does one head ;-)
Hopefully it covers all the aspects of your question and you can adapt it to your PDF.

ImageMagick: get biggest square out of image

I do have thousands of images in different sizes; now I would like to get the biggest square out of it that's possible without transparent/black background. Of course, the ratio should be kept, if it's e.g. a landscape image all height should be in the destination image but the left and right should be cropped; for portrait images, the other way round.
How's that possible?
I think you mean this. If you start with a landscape image bean.jpg:
magick bean.jpg -gravity center -extent "%[fx:h<w?h:w]x%[fx:h<w?h:w]" result.jpg
If you start with a portrait image, scooby.jpg:
magick scooby.jpg -gravity center -extent "%[fx:h<w?h:w]x%[fx:h<w?h:w]" result2.jpg
The part inside the double-quotes is the interesting part. It is basically setting the extent of the image, like:
-extent 100x100
where 100 is the width and the height. Rather than that though, I am using a calculated expression which tests whether the height (h) is less than the width (w) using a ternary operator. That results in taking whatever is smaller out of the current height and width as the new height and width, So there are really two calculated expressions in there, with an x between them, similar to 100x100.
Note that this method requires ImageMagick v7 or better - i.e. it uses the magick command rather than v6's convert command. If you have v6, you need to use more steps. First, get the width and the height of the image, then choose the smaller of the two and then issue a convert command with the gravity and extent both set. In bash:
# Get width and height
read w h < <(identify -format "%w %h" scooby.jpg)
# Check them
echo $w,$h
272,391
# Set `n` to lesser of width and height
n=$w
[ $h -lt $n ] && n=$h
# Now do actual crop
convert scooby.jpg -gravity center -extent "${n}x${n}" result.jpg
If you have thousands to do, I would suggest using GNU Parallel if you are on macOS or Linux. If you are on Windows, sorry, you'll need a loop and be unable to easily use all your CPU cores.
I have not tested the following, so only try it out on a small, COPIED, sample of a few files:
# Create output directory
mkdir output
# Crop all JPEG files, in parallel, storing result in output directory
parallel --dry-run magick {} -gravity center -extent "%[fx:h<w?h:w]x%[fx:h<w?h:w]" output/{} ::: *.jpg
If the commands look good, remove the --dry-run part to do it for real.
If you're using ImageMagick v7, Mark Setchell has provided a simple method above (or below). If you're using IMv6, you can crop the largest center square from any image using a command lke this...
convert input.png -set option:distort:viewport "%[fx:min(w,h)]x%[fx:min(w,h)]" \
-distort affine "%[fx:w>h?(w-h)/2:0],%[fx:w<h?(h-w)/2:0] 0,0" output.png
That sets the output viewport size to the largest square you can crop from the input image. Then it adjusts the position of the input image so it is centered within that square viewport.
This command should work from a command prompt or script on most *nix systems. If you're using Windows, replace that continued line backslash "\" with a caret "^". If you're using a BAT script in Windows you'll also have to make all the single percent signs "%" into doubles "%%".
You can also simply change "convert" to "magick" to run this command using IMv7.
I find this easier to remember:
convert in.png -gravity Center -extent 1:1 out.png

ImageMagick: Distort and Overlay

I have several pictures of a landscape.
Using the ImageMagick CLI on OSX, I would like to distort and overlay them properly.
I have looked for distortion coordinates between several of the pictures and a reference picture. I fail to understand the diference between -distort and +distort and how it plays with +repage. When I use -distort, the output has the desired offset but it's incomplete (it needs to be bigger). When I use +distort, I get the full image but it's missing the offset.
Reading the documentation I understand that I could do without the offset if I did the overlay composition in the same command before the offset information is lost but what's happening is that the distort is being applied to both the reference and the distorted images.
This is the result of using -distort:
This is the result of using +distort:
The offset of the -distort result would work once I apply it as an overlay (here using the composite in a separate command, but it's missing a big chunk of the picture.
When I tried to consolidate it in a single command this is the result I get:
This is the command I'm currently using:
convert base.jpg overlay.jpg
-matte -virtual-pixel transparent -distort Perspective '961,1695 1856,2461 2279,1520 3185,2303 3564,2173 4441,2970 1547,2817 2441,3594'
-compose blend -define compose:args=50,100 -composite result.jpg
I understand I could use parenthesis there but I fail to see where should I put them.
Thanks!
Update: this is the result of the overlay when using +distort either in two steps or in a single step as recommended by Mark.
The solution was to use -flatten instead of -composite.
convert base.jpg \( b.jpg -matte -virtual-pixel transparent +distort Perspective '961,1695 1856,2461 2279,1520 3185,2303 3564,2173 4441,2970 1547,2817 2441,3594' \) -compose blend -define compose:args=100,50 -flatten result.jpg
Turns out that -composite ignores the image offsets whereas -flatten works with layers and uses the offset information.
The suggestion came from this thread: http://www.imagemagick.org/discourse-server/viewtopic.php?t=20157
This is the documentation to flatten (link broken in the discussion above): http://www.imagemagick.org/Usage/layers/#flatten
Not sure I understand the issues, but would suggest you try this (untested):
convert base.jpg \
\( overlay.jpg -matte -virtual-pixel transparent -distort Perspective '961,1695 1856,2461 2279,1520 3185,2303 3564,2173 4441,2970 1547,2817 2441,3594' \) \
-define compose:args=50,100 -compose blend -composite result.jpg
That would mean that the perspective distortion is only applied to the overlay, not the base. So, in the code above, the first line only processes the base image, the second line only processes the overlay, and the final line blends the two.

Rotate individual letters of the same word in ImageMagick

I'm generating CAPTCHAs for training data and I have a pretty good ImageMagick script going already.
However, one thing I really want is for individual letters of the word to be slightly rotated, see for example this reCAPTCHA:
Is there an easy (or hard) way to accomplish this effect?
I think you need this:
#!/bin/bash
word="theId"
for (( i=0 ; i<${#word} ; i++ )) ; do
rotation=$(((RANDOM%10)*4)) # Generate random rotation for each letter
convert -background none -virtual-pixel none -pointsize 72 label:"${word:i:1}" +distort SRT $rotation miff:-
done | convert -background none - +append result.png
Basically I am creating and rotating one letter at a time and writing them to a MIFF stream, one after the other, and at the end, I am using +append to join together everything I see on the input stream.
If you want to scrunch the letters closer together (TM) you can add -trim +repage just before miff:-

Add an image on top of existing one with ImageMagick command line

i would like to add a series of images to existing one, using imagemagick command line.
i have this image: http://tinypic.com/r/313386r/6 and
i would like to add this to this one: http://tinypic.com/r/k0jbqs/6
to get more or less this effect: http://tinypic.com/r/wtja74/6 .
as you see, this is not only adding an image. i found http://www.imagemagick.org/Usage/compose/ where i could see some examples, but what i need is to fill each 'block'.
i have exact position where each block starts and ends, also i have a scale parameter to scale it down.
i think i could use
composite -geometry +31+105 toadd.gif source.gif newfile.jpg
but this is only one image added, and i need it scaled down.
i was wondering if i can create some kind of rectangles and fill them with my image.
any idea how it can be solved?
Convert would be better as you can keep adding images with composite or layers.
Here is a very rough example and I would probably start off with a longer section of wall so you could crop it when resizing. There is still going to be quite a bit of user input to fix the locations as I pressume you do not always have the same amount of walls at the same length.
I would write some code to input details into a form as it would be easier than altering the code each time.
convert k0jbqs.jpg \
( 313386r.png -thumbnail x25 ) -gravity west -geometry +0+30 -composite \
( 313386r.png -thumbnail x25 ) -gravity center -geometry +80+30 -composite \
( 313386r.png -thumbnail x25 ) -gravity east -geometry +0+30 -composite \
output.png
You would need to take the line breaks out I just added those to make the code readable.
NOTES: Thumbnail resizes the brick image; you can forget the gravity and just use -geometry and the numbers are the positions from the top left corner and -composite puts the new image over the previous image.

Resources