shrinerb / shrine

File Attachment toolkit for Ruby applications

Home Page:https://shrinerb.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Unable to upload GIFs

doutatsu opened this issue · comments

I was working in my development environment, with a simple avatar uploading configuration, as follows:

# frozen_string_literal: true

require 'image_processing/mini_magick'

class AvatarUploader < Shrine
  Attacher.promote_block { promote } # promote synchronously
  Attacher.destroy_block { destroy } # destroy synchronously

  Attacher.validate do
    validate_mime_type_exclusion %w[image/gif] unless record.premium_active?
  end

  Attacher.derivatives do |image|
    magick = ImageProcessing::MiniMagick.source(image)
    jpeg = magick.loader(page: 0).convert('jpeg').saver(interlace: 'JPEG', quality: 90)
    webp = magick.convert('webp').saver(quality: 90)

    derivatives = {
      webp: {
        small: webp.resize_to_limit(160, 160).call,
        large: webp.resize_to_limit(300, 300).call
      },
      jpeg: {
        small: jpeg.resize_to_limit(160, 160).call,
        large: jpeg.resize_to_limit(300, 300).call
      }
    }

    unless file.jpg?
      derivatives[:webp][:original] = webp.quality(90).call
      derivatives[:jpeg][:original] = jpeg.call
    end

    if file.type?(:gif)
      derivatives[:gif] = {
        small: magick.saver(quality: 90).resize_to_limit(160, 160).call,
        large: magick.saver(quality: 90).resize_to_limit(300, 300).call
      }
    end

    derivatives
  end
end

But after deploying to Production on Heroku, I am suddenly getting this error:

Source format is multi-layer, but destination format is single-layer. If you care only about the first layer, add .loader(page: 0) to your pipeline. If you want to process each layer, see https://github.com/janko/image_processing/wiki/Splitting-a-PDF-into-multiple-images or use .saver(allow_splitting: true). (ImageProcessing::Error)

Why is it not working on Heroku, but locally there are no issues? (I am using M2 Mac). Is there some dependency I am missing on Heroku to allow for GIF manipulation?

Seems to be a problem with ImageProcessing::MiniMagick not Shrine, which only provides the tooling, the actual processing is done by you within the derivatives block. Have you opened an issue there?

Seems like for the webp output you also need to add loader(page: 0), you added it only for jpeg. I'm assuming that's where the error is coming from, since you didn't post a backtrace.

I'm not sure why you'd be getting this error only on Heroku and not locally, but the production result is expected to me. Maybe WEBP locally supports multiple layers but on Heroku it doesn't? I'm not familiar with the WEBP format that much.

Anyway, yeah, it's not an issue in Shrine, but in ImageProcessing gem or rather in the difference in your ImageMagick installations.

Page 0 would make it a static image, not animated, which is what I am trying to do here. Perhaps the magick version on Heroku machine is outdated or something, I'll see if I can dig more into this