Search code examples
imagemagickruby-on-rails-5carrierwaveminimagick

Cropping transparent pixels with carrierwave


Using Carrierwave on Ruby 5 with MiniMagick, is it possible to trim transparent pixels ?

Suppose a user uploads a 500x500 image but only the inner 250x250 pixels are indeed filled, the rest is transparent. Is there a processing command that would help detect and trim the image to 250x250 before additional processing ?

I found https://www.imagemagick.org/discourse-server/viewtopic.php?t=12127 and it seems there is a trim transparent command on Imagemagick but I'm not sure how to use it with the Ruby wrapper Minimagick ?


Solution

  • The MiniMagick::Image.trim is all that's needed. Without a pixel-iterator, it would be simplest to apply trim on a clone image, and act on the smallest result.

    require 'mini_magick'
    
    def trimed_image(path)
      image = MiniMagick::Image.open(path)
      test_image = image.clone
      test_image.trim
      if test_image.width < image.width || test_image.height < image.height
        test_image
      else
        image
      end
    end
    

    Test case with convert rose: -resize x100 rose.png

    rose = trimed_image("rose.png")
    rose.write("rose_output.png")
    

    No change expected.

    rose_output.png

    Test transparent image with convert -size 100x100 gradient: -background black -extent 200x200-50-50 -alpha copy trim.png

    trim = trimed_image("trim.png")
    trim.write("trim_output.png")
    

    Trim expected.

    trim_output.png