How to create a golden ratio / fibonacci spiral with imagemagick - imagemagick

I'm looking for a way to create a golden spiral with imagemagick. Like this:
Using the script below I'm able to create the spiral beneath.
magick -size 640x4 xc:black
-background none -splice 0x1 -extent 0x36
-duplicate 8 +delete -append +repage
-distort affine "0,0 0,0 0,1 0,1 %[w],0 %[w],36"
-distort arc "360 0 %[h] 0" -shave 1 +repage
-background white -flatten spiral.png

Related

ImageMagick: How to create torn page effect for specifc edges?

The ImageMagick documentation provides guidance on how to create torn page effects (https://www.imagemagick.org/Usage/thumbnails/#torn). However, in their implementation, all edges are torn. Suppose I wish to tear off only the bottom or top part of the image. How can I achieve such a thing using ImageMagick?
Simply grow the top & sides by using -extent operator.
convert zelda.png -background pink -extent 148x138-10-10 extent.png
(Adding pink background for visibility on stack)
Apply the effect from the Usage documentation.
convert extent.png \( +clone -alpha extract -virtual-pixel black \
-spread 10 -blur 0x3 -threshold 50% -spread 1 -blur 0x.7 \) \
-alpha off -compose Copy_Opacity -composite torn.png
Then crop back to original image size.
convert torn.png -crop 128x129+10+10 output.png
Update
If you do not want to use geometry, you can use a combination of -border, -shave & -chop.
convert zelda.png -bordercolor pink -border 10x10 -gravity South -chop 0x10 extent.png
convert extent.png \( +clone -alpha extract -virtual-pixel black \
-spread 10 -blur 0x3 -threshold 50% -spread 1 -blur 0x.7 \) \
-alpha off -compose Copy_Opacity -composite torn.png
convert torn.png -shave 10x -chop 0x10 output.png
.. And of course, this all can be done with one command.
convert zelda.png -bordercolor pink -border 10x10 -gravity South -chop 0x10 \
\( +clone -alpha extract -virtual-pixel black -spread 10 -blur 0x3 -threshold 50% \
-spread 1 -blur 0x.7 \) -gravity Forget -alpha off -compose Copy_Opacity -composite \
-shave 10x -chop 0x10 output.png
There are several ways to create a torn edge effect using ImageMagick. Here is another example command using IM version 6 and *nix syntax. This should apply a torn effect to just the top edge of any input image while keeping the original dimensions of the image.
convert input.png -alpha set -background black -fill white \
\( +clone -colorize 100 -gravity south -chop 0x6 -splice 0x6 \
-spread 6 -paint 2 +transparent white -blur 0x0.5 \) \
-background none -compose dstin -composite torn.png
That creates a white mask inside the parentheses. Then a small amount of the "torn" edge is chopped off and a black strip is spliced on to replace it. The random-ish torn edge is created using "-spread" and "-paint" between the white and black areas of the mask. After that, outside the parentheses, that mask is used to apply the transparent torn area to the input image.
To apply the effect to the bottom edge, just change the "-gravity north" to "-gravity south".
To make the torn edge on the left or right, change the gravity setting to "west" or "east", and change the values of the "-chop" and "-splice" operations from "0x6" to "6x0".
This should work the same way using ImageMagick version 7 by changing the "convert" command to "magick".
To use it in Windows, remove the backslashes that escape the parentheses from "\(...\)" to "(...)", and change the continued line backslashes "\" to carets "^".

Imagemagick - move/offset images within a tiled montage?

Consider this example (Ubuntu 18.04, ImageMagick 6.9.7-4 Q16 x86_64 20170114):
convert -size 300x100 xc:red red.png
convert -size 100x100 xc:blue blue.png
montage red.png blue.png -frame 5 -geometry '+0+0' -tile 1x redblue.png
This gives the following image:
What I'd like to do, is move the blue square on arbitrary x position "within its tile"; say align left edge of blue square to where 25% of the red rectangle width would be, or at 50% - or even align right edge of blue square with right edge of red rectangle.
I have seen that -tile-offset exists (https://imagemagick.org/script/command-line-options.php#tile-offset), and I've tried it with this example, but it doesn't look like it does anything.
How can I move an image, part of a ImageMagick montage, within its tile?
EDIT: it looks like -tile-offset can only be specified for explicit tile images (not as in -tile 1x, but as in -tile red.png), and:
Tile smaller image over a background with offsets? - ImageMagick
-tile-offset must come before the tiling. It represents a single global offset, not the spacing for the tiling.
Here's an example:
convert -size 300x100 radial-gradient:\#400-\#FAA red.png
convert -size 500x500 xc: -tile-offset +100+40 +size -tile red.png -border 5 -geometry +5+5 -draw "color 0,0 reset" out.png
then out.png is this (click for full image):
... so to clarify - I'd like to know is its possible to move an image within a tile as obtained in montage tile 1x
As suggested in the comment:
convert -background none red.png \( -size 25x xc:none blue.png +append \) -append result.png
Or with 2 different offsets:
convert -background none red.png \
\( -size 25x xc:none blue.png +append \) \
\( -size 50x xc:none blue.png +append \) \
-append result.png
Not sure what your end-goal is, but you can also do this:
convert -gravity east -background none red.png blue.png red.png blue.png -append result.png
Or this:
convert -gravity center -background none red.png blue.png red.png blue.png -append result.png
In ImageMagick 6, another way is to extend the transparent background, then composite the blue image in the center of the bottom half of the extended image.
convert -size 300x100 xc:red -background none -extent 300x200 -size 100x100 xc:blue -geometry +100+100 -composite result.png

How to split an image with a grid and preserve transparency bounding box

I have some png images that I want to split it into parts, like by grid or size.
But each part should have the same bounding box (transparency) as original image.
Example:
Splitting image into 2 parts.
Original: 200 × 89
Output:
part_1.png, 200 × 89
part_2.png, 200 × 89
Can ImageMagick do this? Or any other app or method.
My actual goal is to split into 100+ slices images.
EDIT:
Another goal to have an indents for each slice. Say indent = 10px.
Example:
Input: 200 x 100
Output:
part_1.png, 200 x 100
part_2.png, 200 x 100
And just as example, to visually compare input and output: combined output images in Photoshop as layer added one onto another
200 x 100 :
Also this is showing input image added onto combined(so it's better to see what was cropped and how):
In ImageMagick, you can split an image into many parts with the -crop command. For your example above with two parts, you can do that with the following commands. ImageMagick will append -0, -1 ... to the output file names.
ImageMagick 6:
dim=`convert image.png -format "%wx%h" info:`
convert \( -size $dim xc:none \) null: \( image.png -crop 50x100% \) -layers composite result.png
ImageMagick 7:
magick \( image.png -set option:dim "%wx%h" -crop 50x100% \) null: \( -size "%[dim]" xc:none \) -reverse -layers composite result.png
The results are:
See
http://www.imagemagick.org/Usage/crop/#crop
http://www.imagemagick.org/Usage/crop/#crop_percent
http://www.imagemagick.org/Usage/crop/#crop_tile
http://www.imagemagick.org/Usage/crop/#crop_quad
http://www.imagemagick.org/Usage/crop/#crop_equal
http://www.imagemagick.org/script/command-line-options.php#layers
Note that -crop keeps the virtual canvas information if you do not add +repage afterwards. So to put the individual images back into their original placement, you have to composite them onto a transparent background the size of the input. That is done in one command using -layers composite using the null: separator.
Here is another way to add transparent areas between parts of a crop in ImageMagick. Crop the image into pieces, chop off the parts you want to remove, then pipe to montage to add the spacing back.
Input:
Here I make this into a 4x4 grid of images with 10 pixel spacing:
convert lena.png -crop 25%x25% +repage -gravity east -chop 10x0 -gravity south -chop 0x10 +repage miff:- | montage - -background none -tile 4x4 -geometry +5+5 result.png
To answer your new question, you can do that with a script loop. On a Unix-like platform, assuming your images do not have spaces, you can do the following:
cd path/to/current_folder
list=`ls *.png`
for img in $list; do
name=`convert $img -format "%t" info:`
dim=`convert $img -format "%wx%h" info:`
convert \( -size $dim xc:none \) null: \( $img -crop 50x100% \) -layers composite -scene 1 path/to/new_folder/${name}_%d.png
done
If you want leading 0s in the output, say 3, use path/to/new_folder/${name}_%03d.png.
Note that to start with 1 rather than 0, I have added -scene 1.
Sorry, I do not know how to script for Windows.
Please always provide your ImageMagick version and platform.
In ImageMagick, the best way to put transparent areas into your image is with a binary mask that is put into the alpha channel of your image.
convert input.png \( -size 200x89 xc:white -size 10x89 xc:black -gravity center -composite \) -alpha off -compose copy_opacity -composite result.png
You can add as many blank areas as you want by adding more white areas to the mask or by tiling out one region of black and one region of white to create the mask with regular spacing of black and white.
Edited to add this ImageMagick 6 example which splits the input image into 4 pieces, 25% of the original width and 100% of its height, then creates a transparent canvas for each piece the same dimensions of the input image, and locates the pieces at their original offsets on those canvases.
convert input.png -set option:distort:viewport %[w]x%[h] -crop 25x100% \
-virtual-pixel none -distort affine "0,0 %[fx:s.page.x],%[fx:s.page.y]" out%03d.png
The output file names will be numbered starting from zero like "out000.png", etc.
Original message...
Here's a simple command using ImageMagick 7 that can crop an image into any number of pieces, and output all the pieces at their original offsets on transparent backgrounds of the original input dimensions...
magick input.png -crop 100x1# -background none \
-extent "%[fx:s.page.width]x%[fx:s.page.height]-%[fx:s.page.x]-%[fx:s.page.y]" out%03d.png
That "-crop 100x1#" tells it to split the image into a grid 100 pieces wide by 1 piece high. You could just as well specify the crop sizes as percents or numbers of pixels.
Edited again to add:
This following command will split the input image into the individual pieces specified with the "-crop" operator, then shave 5 pixels from every side of each piece, then apply a 5 pixel transparent border to every side of each piece. It will still remember the original locations of the pieces within the input canvas, so the "-distort affine ..." can extend the canvases and place the pieces where they were in the input image.
convert input.png -set option:distort:viewport %[w]x%[h] \
-bordercolor none -background none -virtual-pixel none \
-crop 25x100% -shave 5x5 -border 5x5 \
-distort affine "0,0 %[fx:s.page.x],%[fx:s.page.y]" out%03d.png
To use this command with IM7 you need to change "convert" to "magick".
Given the changes of requirements provided by Kamikaze, here is one way to achieve the split with indent in ImageMagick, assuming I understand correctly.
dim=`convert image.png -format "%wx%h" info:`
convert \( -size $dim xc:none \) null: \( image.png -crop 50x100% -shave 5x5 \) -geometry +5+5 -layers composite result.png
To check, I flatten over a blue background:
convert result-0.png result-1.png -background blue -flatten result.png

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.

ImageMagick draw rectangle with special corners

Hi I would like to create a mask image with "special corners" I am calling them special because I don't really know how to call them in english here is what I would like to achieve:
what I am using now is
convert xc:black -size 300x300 -fill white -draw "roundrectangle 3,3,296,296,5,5"
but this gives me rounded corners. Thank you in advance for any suggestions.
Here's one way of doing it.
convert -size 300x300 xc:none \
-shave 10 -bordercolor black -border 10 \
-fill black -draw "polyline 0,0 30,0 0,30" \
\( +clone -flip \) -gravity north -composite \
\( +clone -flop \) -gravity south -composite -background white -flatten result.png
That says... "Draw a rectangle your full size and transparent, shave 10 pixels off all round and add a 10 pixel black border (easier than doing the maths and making a 280x280 and adding 10 on each side). Draw a triangle in the top-left. Copy the whole shape and flip it and draw it on top of the original. Copy the whole shape and flop it and draw it again on the original. Now make all the transparent areas white."
Here is another way - maybe a little easier. Draw the original square, then copy it, enlarge it by square-root(2) (i.e. 141%), thicken the borders, rotate 45 degrees and composite it onto itself. Kinda depends how your brain works!
magick -size 300x300 xc:none -shave 10 -bordercolor black -border 10 \
\( +clone -scale 142% -shave 30 -border 30 -rotate 45 \) \
-gravity center -composite -background white -flatten result.png
Here is a link to a page showing how to do what you want along with other effects https://www.imagemagick.org/Usage/thumbnails/#rounded
This is the code from the page:
convert thumbnail.gif -alpha set -compose DstOut \
\( -size 20x15 xc:none -draw "polygon 0,0 0,14 19,0" \
-write mpr:triangle +delete \) \
\( mpr:triangle \) -gravity northwest -composite \
\( mpr:triangle -flip \) -gravity southwest -composite \
\( mpr:triangle -flop \) -gravity northeast -composite \
\( mpr:triangle -rotate 180 \) -gravity southeast -composite \
corner_cutoff.png
You should check out the examples as there is another method you could use for smaller images.

Resources