Carrierwave and mini_magick finding widths & height

后端 未结 4 1009
慢半拍i
慢半拍i 2021-02-06 12:30

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\

相关标签:
4条回答
  • 2021-02-06 12:35

    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 讨论(0)
  • 2021-02-06 12:42

    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.

    0 讨论(0)
  • 2021-02-06 12:48
    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
    
    0 讨论(0)
  • 2021-02-06 12:48

    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
    
    0 讨论(0)
提交回复
热议问题