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.
Image Size Finder helps to find three different size details of your uploaded image. (1) Size of Image: To check Height and Width dimension of the uploaded images. Displays the size of the image in Pixel (px), Centimeter (cm) and Inches (in) scales.
The naturalWidth and naturalHeight are read-only properties, and they are used to find out the original width and height of an image. We may use the width and height elements of the img tag to change the height and width of an image shown on our webpage.
Get image size with JavaScript (modern browsers, IE9+ ) function getMeta(url){ var img = new Image(); img.addEventListener("load", function(){ alert( this.naturalWidth +' '+ this.naturalHeight ); }); img.src = url; }
9 1 Unless you need to obtain the dimensions synchronously. In that case you just have to insert the image to the document (using an absolute position somewhere outside the viewport) - then the dimensions are available right after calling document.appendChild(). – JustAndrei Apr 7 '15 at 10:51
@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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With