Carrierwave and mini_magick finding widths & height
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'd like to be able to access the width and height, so I can form the html correctly. However, there is no default data from which to get this information. Because of the way it stores the data I'm I cannot think of any way that I can add it to the database.
Can anyone suggest any tips or ideas? Is it even possible?
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
Disadvantage of calculating Image height
/ width
using RMagick
or MiniMagick
in run time:
- Its CPU intensive
- It requires Internet to get image and calculate the dimensions.
- Its a slow process
FYI You can also calculate the Image
Height
,Width
after the Image is fully loaded by using theload
event 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.
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.
精彩评论