使用 rmagick 和 Sinatra 生成动画旋转图像并在内存版本中显示

Generate animated rotating image and displaying in memory version using rmagick and Sinatra

我正在 Ruby 中编写一个简单的网络应用程序,使用 Sinatra 拍摄上传的图像,生成三个额外的旋转版本,然后将它们添加到 Magick::ImageList 以生成动画旋转原始图像的版本。我正在使用 rmagick 库来执行此操作。这是 sinatra 路由代码——我生成一个图像,然后将其传递给 HAML 模板:

post '/spin' do
  # The image being uploaded is a PNG
  img = Magick::Image.read(params['spinthis'][:tempfile].path)[0]

  spinned_image = MyRandomClassThatHandlesSpinning.spin(img)

  @result = Base64.encode64(spinned_image.to_blob)

  haml :result
end

MyRandomClassThatHandlesSpinning.spin(img)定义如下:

def self.spin(img)
  spinny_image = Magick::ImageList.new { |img| img.format = "GIF" }

  spinny_image << img
  spinny_image << img.rotate(90)
  spinny_image << img.rotate(180)
  spinny_image << img.rotate(270)

  spinny_image.delay = 1
  spinny_image.ticks_per_second = 5
  spinny_image.iterations = 0

  spinny_image
end

这是 HAML 模板:

!!!
%head
  %title GIF

%h1 GIF below!
%img(src="data:image/gif;base64,#{@result}")

由于某种原因,显示的图像不是动画,只是初始图像。

但是,如果在我的 self.spin 函数中,我将 spinny_image 写入文件,当我在 Chrome(或其他图像编辑器)中加载该文件时,它会显示所有旋转的帧。

有什么方法可以生成此 GIF 而无需先将其保存到磁盘?

我找到了一个解决方案 - 不确定它是否是最佳的,但它确实有效。我希望有人比我有更好的答案:)

我强制将我传递给 self.spinimg 设为 gif,这使图像具有动画效果。这是我的 self.spin 方法现在的样子:

def self.spin(img)
  spinny_image = Magick::ImageList.new
  img.format = "gif"

  spinny_image << img
  spinny_image << img.rotate(90)
  spinny_image << img.rotate(180)
  spinny_image << img.rotate(270)

  spinny_image
end