CarrierWave and correct file extension depending on its contents

前端 未结 2 1389
野性不改
野性不改 2021-01-19 04:51

How can I make CarrierWave add correct extension to filename depending on its contents? For example, if I upload file \"logo\" (PNG file without extension) CarrierWave shoul

2条回答
  •  逝去的感伤
    2021-01-19 05:10

    The problem is in determining the correct content in the first place. Carrierwave uses the MimeType gem which determines its mime-type from the extension. Since, in your case the extension is incorrect you need an alternate way of getting the correct mime-type. This is the best solution I was able to come up with, but it depends on the ability to read the image file using the RMagick gem.

    I ran into this same problem and had to override the default set_content_type method for my uploader. This assumes you have Rmagick gem in your Gemfile, so that you can get the correct mime-type from reading the image, as opposed to making a best guess.

    Note: This is particularly useful if the image is being used by Prawn which supports only JPG and PNG images.

    Uploader Class:

    process :set_content_type
    
    def set_content_type #Note we are overriding the default set_content_type_method for this uploader
      real_content_type = Magick::Image::read(file.path).first.mime_type
      if file.respond_to?(:content_type=)
        file.content_type = real_content_type
      else
        file.instance_variable_set(:@content_type, real_content_type)
      end
    end
    

    Image Model:

    class Image < ActiveRecord::Base
      mount_uploader :image, ImageUploader
    
      validates_presence_of :image
      validate :validate_content_type_correctly
    
      before_validation :update_image_attributes
    
    private
      def update_image_attributes
        if image.present? && image_changed?
          self.content_type = image.file.content_type
        end
      end
    
      def validate_content_type_correctly
        if not ['image/png', 'image/jpg'].include?(content_type)
          errors.add_to_base "Image format is not a valid JPEG or PNG."
          return false
        else
          return true
        end
      end
    end
    

    In your case you can add an additional method that changes the extension based on this correct mime-type (content_type).

提交回复
热议问题