Get image dimensions using Refile

2019-04-07 13:41发布

问题:

Using the Refile gem to handle file uploading in Rails, what is the best way to determine image height and width during / after it has been uploaded? There is no built in support for this AFAIK, and I can't figure out how to do it using MiniMagick.

回答1:

@russellb's comment almost got me there, but wasn't quite correct. If you have a Refile::File called @file, you need to:

fileIO = @file.to_io.to_io
mm = MiniMagick::Image.open(fileIO)
mm.width # image width
mm.height # image height

Yes, that's two calls to #to_io >...< The first to_io gives you a Tempfile, which isn't what MiniMagick wants. Hope this helps someone!

-- update --

Additional wrinkle: this will fail if the file is very small (<~20kb, from: ruby-forum.com/topic/106583) because you won't get a tempfile from to_io, but a StringIO. You need to fork your code if you get a StringIO and do:

mm = MiniMagick::Image.read(fileio.read)

So my full code is now:

# usually this is a Tempfile; but if the image is small, it will be 
# a StringIO instead >:[
fileio = file.to_io

if fileio.is_a?(StringIO)
  mm = MiniMagick::Image.read(fileio.read)
else
  file = fileio.to_io
  mm = MiniMagick::Image.open(file)
end


回答2:

Refile attachments have a to_io method (see Refile::File docs) which returns an IO object that you can pass to MiniMagick.

Assuming you have an Image model with a file attachment (id stored in a file_id string column) and width and height columns you can use the following callback:

class Image < ActiveRecord::Base

  attachment :file

  before_save :set_dimensions, if: :file_id_changed?

  def set_dimensions
    image = MiniMagick::Image.open(file.to_io)
    self.width = image.width
    self.height = image.height
  end

end

Hope that helps.



回答3:

You can use MiniMagick to do this (but need to be using the latest version).

image = MiniMagick::Image.open('my_image.jpg')
image.height #=> 300
image.width  #=> 1300

This is all pretty well documented in the README.md for the gem: https://github.com/minimagick/minimagick