Bill R
Bill R

Reputation: 145

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

I'm writing a simple web app in Ruby using Sinatra to take an uploaded image, generate three additional rotated versions of it, then add them to a Magick::ImageList to generate an animated rotating version of the original image. I'm using the rmagick library to do this. Here's the sinatra route code - I generate an image then pass it on to a HAML template:

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) is defined below:

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

Here's the HAML template:

!!!
%head
  %title GIF

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

For some reason, the image displayed isn't animated, and is just the initial image.

However, if, in my self.spin function, I write spinny_image to a file, when I load that file up in Chrome (or other image editors), it shows all the rotated frames.

Is there any way I could generate this GIF without needing to save it to disk first?

Upvotes: 0

Views: 212

Answers (1)

Bill R
Bill R

Reputation: 145

I found a solution - not sure if it's optimal at all but it works. I hope someone out there has a better answer than me :)

I forced the img I passed into self.spin to be a gif, and that made it so the image animated. Here's what my self.spin method looks like now:

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

Upvotes: 0

Related Questions