Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to compress images before uploading to the cloud using ActiveStorage

To save space in the cloud how would you go about resizing and compressing an image preupload using activestorage?

like image 929
Joey Farina Avatar asked Jun 13 '18 18:06

Joey Farina


1 Answers

I tested this code below in development on local storage and it works, but anyway gives some problems that I will explain next.

On create this seems to work fine, even if I suppose there should be a cleaner way to do so.

class User < ApplicationRecord
  has_one_attached :avatar

  before_save :resize_avatar_image

  def resize_avatar_image
    filename = avatar.filename.to_s
    puts attachment_path = "#{Dir.tmpdir}/#{avatar.filename}"
    File.open(attachment_path, 'wb') do |file|
       file.write(avatar.download)
       file.close
    end
    image = MiniMagick::Image.open(attachment_path)
    # if image.width ...
    image.resize "40x40"
    image.write attachment_path
    avatar.attach(io: File.open(attachment_path), filename: filename, content_type: "image/jpg")
  end

end

Problems that I encountered that someone could overcome

  1. I was not able to apply variations on the fly without downloading to a temp file in order to process it with MiniMagick
  2. When updating (edit) the process is slow because of errors with purge and purge_later methods: [ActiveJob] [ActiveStorage::PurgeJob] [d6a930ee-32cd-45a7-bfb5-72929d79f9bb] Error performing ActiveStorage::PurgeJob (Job ID: d6a930ee-32cd-45a7-bfb5-72929d79f9bb) from Async(default) in 0.33ms: ArgumentError (wrong number of arguments (given 0, expected 1)); I could not find a workaround. Check if the old blob was deleted.
  3. The problem mentioned at point 2 seems to be related with .attach method;
  4. I tested only *.jpg and *.png
  5. Not tested in production nor for remote storage
like image 87
iGian Avatar answered Oct 18 '22 02:10

iGian