Merging two transparent gifs as layers - animation

I've found this page on the imagemagick forum: Merging 2 gifs, one is animated and transparent which links to the imagemagick docs on Animation Modification; specifically, the example here:
convert canvas_prev.gif -coalesce \
-gravity NorthEast -draw 'image over 5,5 0,0 "rose:"' \
-layers Optimize draw_over.gif
Here's my attempt. I have these two gifs (i might be feeling a little morbid). The white in the first is actually transparent.
when I run
convert eyes.gif -coalesce -draw ' image over 0,0 0,0 "trump.gif" ' combine.gif
I get this:
which is not the complete effect I desire. The trump animation is no longer playing at all.
I want to see something more like this (this is created in Phaser JS, but this gives me no way to export the result as a new image other than manually recording a screencast):

One way to do it, yet not sure if it's the best, is as follows:
convert both animations into sprite-sheets of same dimensions
paste one image over the another
cut result into smaller frames and convert it into animated GIF
The commands should look like this:
montage -background none t.gif -tile x1# -geometry +0+0 tt.png
montage e.gif[0-16,0-9] -tile x1# -geometry +0+0 ee.png
magick convert -delay 10 -loop 0 ee.png tt.png -coalesce -flatten \
-crop 150x150 +repage output.gif
Tricky part is the second line with eyes image. It has only 17 frames while skull has 27. So the sprite sheet size must be adjusted.
I works, however I am not quite happy with this as solution requires manual entering of some parameters (frames selection and output image dimensions).

Related

How to use convert -crop to add more background to animated gif/enlarge image?

I'm trying to crop an animated gif usind convert -crop. In some cases it's necessary to add more background to the image to fit. With other image formats it's done with
convert original.gif -rotate 0 -crop 1519x759-237-61\! -background white -flatten edited.gif
For gifs I tried
convert original.gif -coalesce -rotate 0 -crop 1519x759-237-61\! +repage edited.gif
convert is clipping/trimming the background and just the "subject" of the image is shown.
Example is here: https://imgur.com/ls1ED0Z
Result is here: https://imgur.com/59678cD
Expected Result is https://imgur.com/vZGaD7r
I added the red border to show how big the image is. Someone with a great solution? :)
Jan
To do what you want in Imagemagick, you should be using -extent rather than -crop in order to extend the size of the output.
Try this. Adjust the size and offset and background color as desired.
convert original.gif -coalesce -rotate 0 +repage -background white -extent 1519x759-237-61! -bordercolor red -border 3 result.gif
I have added a red border around the image.
With IM you can choose to "-crop", which is most often used to reduce the viewport dimensions, or "-extent", which can also be used to enlarge the viewport. It looks like there are a couple other issues with achieving the result in your sample image, but for starters, try simply substituting your "-crop" with "-extent" like this...
convert original.gif -coalesce -rotate 0 -extent 1519x759-237-61 +repage edited.gif
That will put your input image in a viewport of 1519x759, and place its upper left corner at 237 pixels from the left and 61 pixels from the top. You shouldn't need the exclamation point "!" in any case.

Center text vertically but not horizontally in specified box imagemagick

I'm trying to generate image from text. Requirements are: text left aligned, vertically centered, big as possible, max. resolution 1920x1080.
This is what I have:
convert -background white -fill black \
-font "fonts/DejaVuSansMono.ttf" \
-size 1920x1080 label:'Text \nloooooooooooooooooooooooooong text\nand another' \
-gravity West image.png
It works pretty well, but it doesn't center it to vertically.
Looks like this:
https://imgur.com/rJLxJO2.png
But I would like it to look like this: https://imgur.com/IVrydty.png
I could use -size x1080 and put that image into center of a blank white image using second command, but that doesn't make sure it is not too wide.
Try setting the gravity before creating the label....
convert -background white -fill black -size 1920x1080 \
-gravity west \
label:'Text \nloooooooooooooooooooooooooong text\nand another' \
image.png
Edited to add: When a setting is supposed to affect a particular operation, in almost every case with ImageMagick the setting should come ahead of the operation. IM version 6 is somewhat forgiving in that regard, but as with your example, often the order of the command is important. IM version 7 is much more strict.

Insetting smaller image inside a larger one using ImageMagick

How would one go about insetting a smaller image inside a larger one?
I have two images as shown below:
Image 1:
Image 2:
The first image needs to go into the topleft corner of the second one. Its width is almost one tenth the width of the second one. I tried a number of things like compositing, and repage and merging layers, but I can't seem to get the hang of it yet. I am very new to imagemagick, so any help is appreciated.
Not certain what you mean exactly but this should give you an idea:
convert image1.png -bordercolor black -border 5 image2.png +swap -geometry +50+100 -composite result.png
I loaded the inset picture first and put a 5 pixel border around it, then loaded the background image, swapped them so the background was at the back and composited over the top.
I could, equally, have loaded the background image first, then loaded the inset image in some "aside-processing" and then composited the result on top:
convert image2.png \( image1.png -bordercolor black -border 5 \) -geometry +50+100 -composite result.png
I guess with the first method it looks kind of back-to-front and there is a +swap in there. With the second method, you have the "complexity" of the parentheses which make sure the border is only applied to the inset image and not the background image.

is there a way to use imagemagick or another graphics library to filter and image based on the pixels in another image

So I wrote a program to do this, but it takes forever to execute. I've noticed a lot of graphics libraries seem to execute stuff way faster than the things I code. Basically what I want to do is filter the pixels in the first image using the second one. If they don't match replace them with black. I just want to be able to see the wall in the image.
In ImageMagick, you can extract the unique (srgb) colors from your image2 after limiting the colors to 255. Then you can loop over each color and have it fill that color with white in the first image and all other colors with black. This makes a mask image, which can be multiplied with image1 to make your result. Adjust the fuzz value as desired.
colors=`convert image2.jpg -fuzz 10% +dither -colors 255 -unique-colors txt: | cut -d\ -f6`
list=""
for color in $colors; do
val="-fill white -opaque '$color'"
list="$list $val"
done
eval 'convert image1.png -fuzz 1% '$list' -fill black +opaque white mask.png'
convert image1.png mask.png -compose multiply -composite result.png

Making half an image transparent from the command line

I don't really know where to start with this one. I'm trying to do something that I thought would be relatively simple to accomplish with imagemagick, but I don't know the exact command to start with. I need to draw a line through an image, and then make everything above the line transparent in the image, and make everything below the line, the orignal image. What would be the best way to accomplish this using imagemagick?
So what I've come up with for now is to crop the image, and then resize it to the original size, but with a transparent background. The command I use is this, but it always comes out black. I'm not understanding why.
convert -background none -gravity south out.png -resize 400x200 -extent 400x400 result.png
Thanks for all of the help!
Here's a fairly easy way to do it. First, enable an alpha channel in case your image doesn't have one, then select the alpha channel for modification by the following -fx command. In there, if the current j is greater than half the height of the image, make the alpha layer opaque, else transparent. Easier than it sounds!
So, using this start image:
convert bean.jpg -alpha on -channel A -fx "j>h/2?1:0" result.gif
Or, the other way:
convert bean.jpg -alpha on -channel A -fx "j<h/2?1:0" result.gif
Or the other, other way:
convert bean.jpg -alpha on -channel A -fx "i<w/2?1:0" result.gif
Or, if you are feeling particularly silly on a Friday morning...
convert bean.jpg -alpha on -channel A -fx "hypot(i,j)/400-0.8" result.gif

Resources