开发者

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 the load 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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜