Rails + Carrierwave + MiniMagick: 如何保存gif动画?

Rails + Carrierwave + MiniMagick: How to preserve gif animation?

当我通过 Carrierwave 和 MiniMagick 上传 gif 图片时,动画被删除了。我尝试了很多解决方案...

这个上传有一个好奇的东西。如果我输入图像类型,它是 returns "image/png",但我发送了一个 gif。我也尝试过其他文件。

文件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

如果我把原来的版本改成:

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

def get_image_type
    puts @file.content_type
end

在控制台中 (rails 秒),它 returns "image/png"。我正在尝试应用 this solution,但没有用,我怀疑问题出在错误的 content_type。

我的环境

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

问题出在 DropzoneJS 上。所有上传的文件都将在本地调整大小。当 GIF 由 DropzoneJS 调整大小时,它将被展平并转换为 PNG。

然后,Carrierwave 向服务器发送了一个带有 GIF 扩展名的 PNG 文件。

我最终的 DropzoneJS 设置(有效)是:

$('.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){
            ...
        });
    }
});

我这里的独特问题是:

如果我发送多个首先处理 GIF 的文件,则不会调整下一个文件的大小。如果处理的第一个文件不是 GIF,接下来的文件将被调整大小并且 GIF 将不起作用。