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

时间:2014-02-20 14:32:57

标签: ruby image-processing rmagick

我正在尝试将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 }

我错过了什么?

1 个答案:

答案 0 :(得分: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 }