0
votes

When I upload gif images via Carrierwave and MiniMagick, the animation is removed. I tried a lot of solutions...

This upload has a curiosity thing. If I put the image type, it returns "image/png", but I sended a gif. I tried with other files too.

file app/uploaders/image_uploader.rb

class ImageUploader < CarrierWave::Uploader::Base

    include CarrierWave::MiniMagick

    storage :aws

    def store_dir
        "#{model.class.to_s.underscore}/#{mounted_as}/"
    end

    def fix_exif_rotation
        manipulate! do |img|
            img.tap(&:auto_orient)
        end
    end

    version :thumb do
        process resize_to_limit: [150, 100000]
        process :quality => 90
        process :fix_exif_rotation
    end

    version :original do
        process :quality => 90
        process :fix_exif_rotation
    end

    def extension_white_list
        %w(jpg jpeg gif png)
    end

    def filename
        "#{secure_token}.#{file.extension}" if original_filename.present?
    end

    private

    def secure_token
        var = :"@#{mounted_as}_secure_token"
        model.instance_variable_get(var) || model.instance_variable_set(var, SecureRandom.uuid)
    end

end

If I change the version original to:

version :original do
    process :get_image_type
    process :quality => 90
    process :fix_exif_rotation
end

def get_image_type
    puts @file.content_type
end

In console (rails s), it returns "image/png". I'm trying to apply this solution, but not works and I suspect the problem is with the wrong content_type.

My env

rails -v: Rails 4.2.1
ruby -v: ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-linux]
carrierwave-aws: 1.2.0
mini_magick: 4.8.0
OS: Ubuntu 16.04.5 LTS
1
Looks like gifs require extra processing. Have you came across this yet? gist.github.com/sunny/9b107f2be0d0dff4f3baRudyOnRails
@RudyOnRailsTks your comment! I tried this solution, but not works. The content_type "image/png" prevent the solution works. I'm using Dropzone JS, I'm suspecting the Dropzone is converting my gif in png. Today I will to test it.Diego Somar
I use Dropzone too. console.log the file inside whatever handler for the @vdropzone-sending event. I did a .gif file and I see type: "image/gif"RudyOnRails
@RudyOnRails Yes, the problem is with Dropzone. If has a resize/change quality, the image is converted do PNG. Without resize/quality, the GIF is processed correclty. Now, I have to figure out to work with JPGs/PNGs and GIFs. Tks your comment!Diego Somar
Ok, maybe you customized yours from default and it's doing something different than mine? I can upload gif's just fine and the animation is preserved. I would start by checking your rails log to look at the params of the image coming in...make sure it's image/gif. Perhaps the fix_exif_rotation process is messing with the layers of the gif?RudyOnRails

1 Answers

1
votes

The problem is with DropzoneJS. All uploaded files wi resized locally. When a GIF is resized by DropzoneJS, it will be flatted and converted to an PNG.

Then, Carrierwave sent to server an PNG file with GIF extension.

My final DropzoneJS settings (which works) is:

$('.dropzone').dropzone({
    paramName: 'attachment[image]',
    maxFilesize: 3,
    thumbnailWidth: 189,
    previewsContainer: '#sended-images',
    previewTemplate: $('#preview').html(),
    timeout: 360000,
    acceptedFiles: 'image/*,.jpg,.png,.jpeg,.gif',
    accept: function(file, done) {
        var mime_type = file.type;
        if ( mime_type != 'image/gif' ){
            this.options.resizeWidth = 1800;
            this.options.resizeQuality = 90;
            done();
        } else {
            this.options.resizeWidth = null;
            this.options.resizeQuality = null;
            done();
        }
        file.status = Dropzone.ADDED;
        done();
    },
    init:function(){
        this.on('success',function(f,d){
            ...
        });
        this.on('sending',function(f,x,d){
            ...
        });
        this.on('addedfile',function(f,x,d){
            ...
        });
        this.on('error', function(f, response) {
            ...
        });
        this.on("maxfilesexceeded", function(file){
            ...
        });
    }
});

My unique problem here is:

If I send multiples files which GIF is processed first, next files will not be resized. If the first file processed is not a GIF, next files will be resized and the GIFs will not work.