image_processing icon indicating copy to clipboard operation
image_processing copied to clipboard

Basic image trim with background

Open AlecRust opened this issue 3 years ago • 1 comments

We use image_processing with ImageMagick currently, but I'm looking to switch to faster VIPS now it's default in Rails 7.

I'm struggling with a basic equivalent "trim" to remove excess pixels (white in this case) around a product image:

image

With ImageProcessing::MiniMagick these options passed to the image variant work to trim it:

{
  fuzz: '1%',
  trim: true
}

The equivalent in VIPS looks to be find_trim but this doesn't work when I pass it to ImageProcessing::Vips:

{
  find_trim: true
}

# OR

{
  find_trim: {
    threshold: 10
  }
}

I initially created this issue at https://github.com/libvips/ruby-vips/issues/327 but it seems maybe things like this trim function would need to be added as a feature to image_processing in order to work in a similar way?

AlecRust avatar Jan 14 '22 16:01 AlecRust

This was the one thing keeping me from migrating away from Paperclip to ActiveStorage.

Being not familiar with the code and abstraction layers of ActiveStorage, libvips and image_processing I found it very hard and time consuming to implement this simple feature. However, here is a solution for anyone who comes across this:

Create this file:

# lib/image_processing/vips/processing.rb

require "image_processing"

module ImageProcessing
  module Vips
    module Processing
      extend ActiveSupport::Concern

      included do
        def crop_whitespace
          coordinates = image.find_trim(threshold: 7, background: 0)
          image.crop(*coordinates)
        end
      end
    end
  end
end

Load it from an initializer:

# config/initializers/image_processing.rb

Rails.configuration.after_initialize do
  ImageProcessing::Vips::Processor.include(ImageProcessing::Vips::Processing)
end

And finally, this is how you use in your model with ActiveStorage named variants (Rails 7 required):

has_one_attached :logo do |blob| 
  blob.variant :small, crop_whitespace: true, resize_to_fit: [110, 55], saver: { quality: 82 }
end

If the maintainers feel this should become part of the gem's functionality, let me know if I should create a pull request.

nikolasgd avatar May 04 '22 21:05 nikolasgd