After a bit of investigation I decided to use Carrierwave and mini_magick on my new rail3 app.
I\'ve set it up and it works perfectly. However I have a one question. I\
I think the best way is to store the image dimensions in the model (database).
In my case, the model name is attachment. Then I created a migration:
rails g migration add_dimensions_to_attachments image_width:integer image_height:integer
After that, run the migration:
rake db:migrate
In my Image Uploader file app/uploaders/image_uploader.rb, I have:
class ImageUploader < CarrierWave::Uploader::Base
include CarrierWave::MiniMagick
process :store_dimensions
private
def store_dimensions
if file && model
model.image_width, model.image_height = ::MiniMagick::Image.open(file.file)[:dimensions]
end
end
end
With this, the image dimensions is saved in the upload step.
To get the dimensions, I simply run attachment.image_width or attachment.image_height
See the reference here.
Disadvantage of calculating Image height / width using RMagick or MiniMagick in run time:
FYI You can also calculate the Image
Height,Widthafter the Image is fully loaded by using theloadevent associated with the<img>tag with the help of jQuery.
For Example:
$(document).ready(function(){
var $image = $('.fixed-frame img');
$image.load(function(){
rePositionLogo($image);
});
if($image.prop('complete')){
rePositionLogo($image);
}
});
function rePositionLogo($image){
var height = $image.height();
var width = $image.width();
if (width > height) {
$image.parents('.header').addClass('landscape');
var marginTop = (105 - $image.height())/2;
$image.css('margin-top', marginTop + 'px')
}else{
$image.parents('.header').addClass('portrait');
}
}
Be careful, because load() will not trigger when an image is already loaded. This can happens easily when an image is in the user's browser cache.
You can check if an image is already loaded using $('#myImage').prop('complete'), which returns true when an image is loaded.
class Attachment
mount_uploader :file, FileUploader
def image
@image ||= MiniMagick::Image.open(file.path)
end
end
And use it like this:
Attachment.first.image['width'] # => 400
Attachment.first.image['height'] # => 300
Just for record, I have used a similar solution, however using files with Mongo GridFS, here it goes:
def image
@image ||= MiniMagick::Image.read(Mongo::GridFileSystem.new(Mongoid.database).open(file.path, 'r'))
end