使用ruby调整动画GIF图像的大小?

Nar*_*put 4 ruby rmagick image-processing

我正在尝试将GIF图像调整为不同大小.我在ruby中使用RMagick库.但是对于一些gif图像来说,即使我缩小GIF,文件大小也会增加.我正在以相同的宽高比调整图像图像的大小.这是我的代码.

require 'rmagick'
path = "/path/to/file/"
s_image = "image.gif" # image is 320*320
t_image = "t.gif"
file_name = path+s_image
file = File.new(file_name)
list = Magick::ImageList.new.from_blob file.read
list = list.coalesce.remap
list.each do |x|
  x.resize_to_fill!(256,256)
end
File.open("#{path+t_image}", 'wb') { |f| f.write list.to_blob }
Run Code Online (Sandbox Code Playgroud)

我错过了什么?

Nei*_*ter 7

您链接的图像由35帧组成.它也已经过优化,因此在第一帧之后,每帧只包含不同的像素.大多数像素是透明的,因为移动很少.这是GIF动画的常见情况 - 如果没有太多的变化或相机移动,它们可以相对有效(在文件大小方面).

另外,每个帧大小是包含所有变化像素所需的最小矩形,因此它在帧与帧之间变化.

如果您在例如GIMP中加载原始图像,并且检查各个图层,则可以清楚地看到这一点.

如果您对转换后的图像执行此操作,还可以看到您的代码完整地渲染每个帧,以便准确地重新调整大小.作为其副作用,它会增加文件大小.将图像x,y缩小到一半应该意味着输出文件大小约为原始文件的1/4.但是,将每个帧从几个像素差异转换为全帧会大大增加该大小.由于有35个框架,这可以弥补较小的宽度和高度.

幸运的是,ImageMagick(和Ruby中的Rmagick绑定)包括一个功能,用于将GIF重新优化回图层,只有差异存储为可见像素.您需要添加对此optimize_layers方法的调用,以允许您的代码具有较小的文件大小.此外,为了获得最佳文件大小,您需要停止使用.remap,这会改变像素值,使优化器无法工作.

require 'rmagick'
path = "/path/to/file/"
s_image = "s_image.gif" # image is 320*320
t_image = "t_image.gif"
file_name = path+s_image
file = File.new(file_name)
list = Magick::ImageList.new.from_blob file.read

# This renders out each GIF frame in full, prior to re-sizing
# Note I have removed the .remap because it alters pixel values
# between frames, making it hard to optimise
list = list.coalesce

list.each do |x|
  x.resize_to_fill!(256,256)
end

# Re-optimize the GIF frames
list = list.optimize_layers( Magick::OptimizeLayer )

File.open("#{path+t_image}", 'wb') { |f| f.write list.to_blob }
Run Code Online (Sandbox Code Playgroud)