MiniMagick
| Language | Ruby |
|---|---|
| License | MIT (ImageMagick: ImageMagick License) |
| Repository | github.com/minimagick/minimagick |
| Documentation | README, ImageMagick animation basics |
| Depends on | ImageMagick 7 (magick) or 6 (convert, identify) |
| Read / write | yes / yes; animation, delays, loop count, disposal, frame optimization |
MiniMagick runs ImageMagick commands from Ruby. For GIF animations the important ImageMagick operations are -coalesce (expand partial frames to full frames before editing), -layers Optimize (shrink frames back to changed areas before saving), -delay (in 1/100 s), -loop (0 = forever) and -dispose. MiniMagick::Image#frames gives access to each frame.
Each call starts an ImageMagick process, and ImageMagick holds all frames in memory at full size, so long animations need a lot of RAM.
Installation#
Shell
# Debian / Ubuntu
sudo apt install imagemagick
# macOS
brew install imagemagick
bundle add mini_magick
Basic usage: inspect an animated GIF#
Ruby
require "mini_magick"
image = MiniMagick::Image.new("anim.gif")
puts "#{image.width} x #{image.height}"
puts "#{image.frames.count} frames"
# per-frame delay (1/100 s), size and offset on the canvas
puts image["%T %wx%h%X%Y\n"]
How to resize an animated GIF#
Ruby
MiniMagick.convert do |convert|
convert << "anim.gif"
convert.coalesce # full frames, so every frame resizes the same way
convert.resize "320x"
convert.layers "Optimize" # back to small difference frames
convert << "small.gif"
end
How to create an animated GIF from images#
Ruby
MiniMagick.convert do |convert|
convert.delay 20 # 0.2 s per frame
convert.loop 0 # forever
convert.dispose "Background"
convert << "f1.png" << "f2.png" << "f3.png"
convert.layers "Optimize"
convert << "anim.gif"
end
How to extract frames#
Ruby
image = MiniMagick::Image.open("anim.gif")
image.frames.each_with_index do |frame, i|
frame.write("frame-#{i}.png")
end
These are the raw frames; run coalesce first (as in the resize example, writing frame-%03d.png) to get full-canvas frames.
How to make a GIF smaller#
Ruby
MiniMagick.convert do |convert|
convert << "big.gif"
convert.coalesce
convert.fuzz "3%" # treat near-identical colors as equal
convert.colors 64
convert.layers "Optimize"
convert << "smaller.gif"
end
Tips#
- Use
MiniMagick::Image.new(notopen) for read-only access: it doesn’t copy the file. -delaybefore the input files sets the delay of frames being read. To change the speed of an existing GIF, use-setafter the input:convert << "anim.gif" << "-set" << "delay" << "5" << "fast.gif".- gifsicle is faster than ImageMagick for pure optimization and editing of existing GIFs.