【问题标题】:Resizing Animated GIF images with ruby?用 ruby​​ 调整动画 GIF 图像的大小?
【发布时间】:2014-02-20 14:32:57
【问题描述】:

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

我错过了什么?

【问题讨论】:

  • 您能否举一个变大的示例图像。我最好的猜测是,您从低颜色计数开始,但重新调整大小会为某些像素创建合并颜色,这将在新图像中变得抖动(降低 RLE 效率)或需要原始调色板更大。
  • 这里是示例文件 源文件 - dl.dropboxusercontent.com/u/47897449/s_image.gif (602 x 429) 目标文件 - dl.dropboxusercontent.com/u/47897449/t_image.gif (301 x 214) 抱歉,我不是这方面的专家。但是,如果您可以指出某些内容或详细说明我该怎么做。
  • 与Ruby无关
  • @Michael Szyndel:它确实与 Ruby 相关,因为它是用 Ruby 编码的,并且解决方案在 Ruby 中可用。我不想撤消您的编辑 - 但现在您可以看到问题和答案仅包含 Ruby 代码,您同意 Ruby 标记现在合适吗?至少这会使自动语法突出显示比我进入并标记两个代码片段更容易
  • 另一方面,我必须同意这就像说“如何在 rails 中求和记录”只是 mysql/postgres/etc。问题。再次添加标签。

标签: ruby image-processing rmagick


【解决方案1】:

您链接的图像由 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 }

【讨论】:

  • 使用 CompareClearLayer,动画不起作用,但我使用了 OptimizeLayer,它对我有用。
  • @Narenda Rajput:我一定是在测试时感到困惑,我已经调整了答案,谢谢。它有效,文件大小更小,但结果对我的设置有点失望。从逻辑上讲,应该可以获得更小的文件大小,但我不确定还有什么应该改变来实现这一点
  • @Narenda Rajput:删除.remap,它会微妙地改变颜色,无法优化帧。
  • 如果您需要.remap,然后执行list = list.optimize_layers( Magick::OptimizeLayer ).remap - 即您恢复优化后
猜你喜欢
  • 2015-06-16
  • 2010-10-07
  • 1970-01-01
  • 2018-04-18
  • 2013-02-09
  • 2011-08-09
  • 2011-08-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多