I could create a less weight animated gif with same variables(colors, dither, etc) using the following function:
convert -delay 4 -loop 0 *.png -coalesce -matte -alpha remove -depth 8 -layers optimizeFrame -colors 128 animated.gif
But there is a Photoshop function called "Includes transparency based on color opacity" that loose a lot of weight, and I can't find an Image Magick equivalent function.
Thanks!
Found it, I have to del -coalesce
convert -delay 4 -loop 0 *.png -matte -alpha remove -depth 8 -layers optimizeFrame -colors 128 animated.gif
Related
Given an animated gif over a solid background color
I'd like to trim away the padding. Concretely, I'd like to crop the image to the maximum extent of the foreground object over all frames:
I can't seem to find the right combination of -alpha, -background to achieve this with a single convert command. For example, if I issue
convert -dispose 2 input.gif -trim -layers TrimBounds fail.gif
I get random "background" colors for frames whose individual trimmed extents are smaller than the maximum extent over all frames:
I can achieve the correct output with a long string of commands:
convert input.gif -trim -layers TrimBounds out-%03d.miff
mogrify -background "rgb(20%,30%,80%)" -layers flatten out-*.miff
convert out-*.miff output.gif
rm out-*.miff
This is slow, writes a bunch of temporary files, and requires me to know the background color ("rgb(20%,30%,80%)") explicitly.
Is there a simpler way to trim an animated gif?
This related question considers explicit cropping rather than automatic trimming.
Finally, this seems to work in ImageMagick with one line to get the background color and one line of processing. No temp files are needed.
bgcolor=`convert input.gif[0] -format "%[pixel:u.p{0,0}]" info:`
convert -dispose previous -delay 10 -background "$bgcolor" input.gif -trim -layers TrimBounds -coalesce -layers optimize -loop 0 output.gif
You can accomplish this sort of trimming using IM's "-distort" with a defined viewport.
convert oHBWq.gif -coalesce +repage -background none \
\( -clone 0--1 -trim -flatten -trim \) \
-set option:distort:viewport %[fx:u[-1].w]x%[fx:u[-1].h]+%[fx:u[-1].page.x]+%[fx:u[-1].page.y] \
-delete -1 -distort SRT 0 +repage output.gif
That clones the input frames, trims them individually, and flattens them keeping their original alignment. Then it trims that flattened one again to get rid of the excess transparent background. The result will be the right size and have the correct page offsets for the finished images. You don't have to know the background color.
Now you can easily get those dimensions and offsets into a distort viewport setting and do a no-op distort. Delete the cloned flattened one that was used to get the measurements, "+repage" the rest, and finish with whatever other GIF settings you need.
This is an interesting question. At the moment, I do not see how to improve it so that extra file(s) are not needed. But I will consider it further. But I can clean your code up a bit and make it easier for you and make the output.gif look correct.
bgcolor=`convert oHBWq.gif[0] -format "%[pixel:u.p{0,0}]" info:`
convert oHBWq.gif -trim -layers TrimBounds out-%03d.miff
mogrify -background "$bgcolor" -layers flatten out-*.miff
convert -dispose previous -delay 10 out-*.miff -loop 0 output.gif
rm out-*.miff
This does the same thing as above, but only requires saving 1 multi-frame miff file. The subshell loop processing does similar to your mogrify.
bgcolor=`convert oHBWq.gif[0] -format "%[pixel:u.p{0,0}]" info:`
num=`convert oHBWq.gif -format "%n\n" info: | head -n 1`
convert oHBWq.gif -trim -layers TrimBounds tmp.miff
(for ((i=0; i<num; i++)); do
convert tmp.miff[$i] -background "$bgcolor" -layers flatten miff:-
done ) |\
convert -dispose previous -delay 10 - -loop 0 output2.gif
rm tmp.miff
This also works without having to save any temp files, but is has to repeat the -trim -layers trim bounds for each loop iteration.
bgcolor=`convert oHBWq.gif[0] -format "%[pixel:u.p{0,0}]" info:`
num=`convert oHBWq.gif -format "%n\n" info: | head -n 1`
echo "num=$num"
(for ((i=0; i<num; i++)); do
convert oHBWq.gif -trim -layers TrimBounds miff:- |\
convert -[$i] -background "$bgcolor" -layers flatten miff:-
done ) |\
convert -dispose previous -delay 10 - -loop 0 output3.gif
This is close but for one frame:
bgcolor=`convert oHBWq.gif[0] -format "%[pixel:u.p{0,0}]" info:`
convert -dispose previous -delay 10 oHBWq.gif -trim -layers TrimBounds -background "$bgcolor" -layers optimize -loop 0 output5.gif
I am trying to stitch together a bunch of .png's which contain some alpha (transparency) but which have a uniformly white background. The png's look fine individually, but in the resulting .gif some frames acquire a patchy background that appears to have the same RGBA color as some of the points being animated.
I have tried the following commands
convert -delay 1 im*.png anim.gif
convert -delay 1 -alpha set im*.png anim.gif
convert -delay 1 -alpha set -dispose background im*.png anim.gif
convert -delay 1 -alpha set -dispose previous im*.png anim.gif
convert -delay 1 -alpha set -dispose previous -background white im*.png anim.gif
pretty much just trying additional flags to see if anything happens to fix the glitch, but I get the same behavior in every case. Anyone have a fix?
Ah, this question led me to the right answer --
convert -delay 1 -layers Optimize im*.png anim.gif
works!
I want to add watermark images to GIF animations with ImageMagick.
The following doesn't work: it just gives produces a weird single image with crazy colors, and the transparent-watermark.png doesn't seem to be there at all.
composite -compose Dst_Over background-gif.gif transparent-watermark.png final.gif
How can this be accomplished? It's similar to annotating but with an image instead of text.
convert background-animation.gif -coalesce -gravity NorthEast -draw 'image over 0,0 0,0 "transparent-watermark.png"' -layers Optimize final.gif
I've had same problem with
convert -delay 4 -loop 0 *.png animated.gif
And fix it adding -alpha remove
convert -delay 4 -loop 0 *.png -alpha remove animated.gif
Try -alpha remove or -background white(other cases) to fix it.
I just changed all of my images to RGBA4444 using TexturePacker for spritesheets and ImageMagick for individual images.
Is it possible to do FloydSteinbergAlpha dithing with ImageMagick? I could only find FloydSteinberg dithering (i.e., without the alpha).
My options are -depth 4 -dither FloydSteinberg
You would apply -dither when dropping color count, along with pixel depth (see Quantization Colors).
convert source.png -colors 64 -dither None out.png
convert source.png -colors 64 -dither FloydSteinberg out.png
convert source.png -colors 64 -dither Riemersma out.png
For pixel depth of 4, we can assume
convert source.png -depth 4 -colors 16 -dither None out.png
convert source.png -depth 4 -colors 16 -dither FloydSteinberg out.png
convert source.png -depth 4 -colors 16 -dither Riemersma out.png
Edit
To include alpha in the dithering, set the -quantize to transparent
convert source.png \
-quantize transparent \
-dither FloydSteinberg \
-depth 4 -colors 16 \
out.png
I want to make an animated gif from those .png image:
I do it with this command:
convert -layers OptimizePlus -delay 25x100 ps1-*.png -loop 0 ps1.gif
It made an animated gif successfully, however, the output has very low quality and smaller than input images:
After some search, I got -quality
convert -layers OptimizePlus -delay 25x100 -quality 99 ps1-*.png -loop 0 ps1.gif
But it seems like imagemagick just ignore the parameter.
The problem is that your source PNGs have an alpha channel which is not supported by GIFs. So you have to remove transparency from your source images first. Since you're dealing with multiple source images, you can't use the -flatten method. With newer ImageMagick versions the following should work:
convert -background white -alpha remove -layers OptimizePlus -delay 25x100 ps1-*.png -loop 0 ps1.gif
If your version of ImageMagick is older than 6.7.5, you can try:
convert -bordercolor white -border 0 -layers OptimizePlus -delay 25x100 ps1-*.png -loop 0 ps1.gif
I got the following result with the latter command: