[Feature] Updating ActiveStorage to use the ImageProcessing gem

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

[Feature] Updating ActiveStorage to use the ImageProcessing gem

Janko Marohnić
Hello everyone,

ActiveStorage performs image processing on-the-fly, and for that it currently uses raw MiniMagick. As we can see from CarrierWave and Refile, for common image resizing it's not enough to just use simple ImageMagick options, certain resizers like "resize_to_fill" require a combination of ImageMagick options to achieve the desired effect.

To avoid reimplementing this functionality, I propose that ActiveStorage uses the ImageProcessing gem, as a layer on top of MiniMagick. The ImageProcessing gem has been developing for almost 3 years now, and it's gotten pretty good. It was primarily written to be used with Shrine, but I deliberately made it generic so that other file attachment libraries can use it as well and avoid reimplementing the same functionality.

Some features that are added on top of MiniMagick:
But probably the biggest features of the ImageProcessing gem is that it also ships with the libvips backend. Libvips is an alternative to ImageMagick. The advantage of using libvips is that in most cases it's multiple times faster than ImageMagick. This is a big deal.

The ImageProcessing gem provides a uniform API regardless of which backend is used, just the operations/options specific to ImageMagick and libvips differ of course. That means the potential ActiveStorage integration would work for both ImageMagick and libvips, allowing the user to swap backends with just a single line of code.

So, my question is: would you be open to accepting a pull request that replaces MiniMagick with ImageProcessing?

Kind regards,
Janko

--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/rubyonrails-core.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: [Feature] Updating ActiveStorage to use the ImageProcessing gem

DHH-2
I like that an idea as an optional upgrade. The Rails 5.2 ship has already sailed, so we'll want to make sure that any optional upgrade honors the existing transformation API. But I could see making the Variation#transform call a strategy that's configurable. And it'll just start with what we have now, but can be upgraded/replaced with this solution.

On Wednesday, April 4, 2018 at 5:18:25 PM UTC-7, Janko Marohnić wrote:
Hello everyone,

ActiveStorage performs image processing on-the-fly, and for that it currently uses raw MiniMagick. As we can see from <a href="https://github.com/carrierwaveuploader/carrierwave/blob/master/lib/carrierwave/processing/mini_magick.rb" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fcarrierwaveuploader%2Fcarrierwave%2Fblob%2Fmaster%2Flib%2Fcarrierwave%2Fprocessing%2Fmini_magick.rb\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFkswQ_2Fw65CfQp75rzuUVP3E7KA&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fcarrierwaveuploader%2Fcarrierwave%2Fblob%2Fmaster%2Flib%2Fcarrierwave%2Fprocessing%2Fmini_magick.rb\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFkswQ_2Fw65CfQp75rzuUVP3E7KA&#39;;return true;">CarrierWave and <a href="https://github.com/refile/refile-mini_magick" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Frefile%2Frefile-mini_magick\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFr8s3qkc98Mj--QKmp5-Pc1Vex6A&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Frefile%2Frefile-mini_magick\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFr8s3qkc98Mj--QKmp5-Pc1Vex6A&#39;;return true;">Refile, for common image resizing it's not enough to just use simple ImageMagick options, certain resizers like "resize_to_fill" require a combination of ImageMagick options to achieve the desired effect.

To avoid reimplementing this functionality, I propose that ActiveStorage uses the <a href="https://github.com/janko-m/image_processing" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fjanko-m%2Fimage_processing\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGljihnUhuVBVG3c07js3rsV3-PnA&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fjanko-m%2Fimage_processing\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGljihnUhuVBVG3c07js3rsV3-PnA&#39;;return true;">ImageProcessing gem, as a layer on top of MiniMagick. The ImageProcessing gem has been developing for almost 3 years now, and it's gotten pretty good. It was primarily written to be used with <a href="https://github.com/shrinerb/shrine" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fshrinerb%2Fshrine\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNF8LQm1BqB91FP5b935EulwtNn7Nw&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fshrinerb%2Fshrine\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNF8LQm1BqB91FP5b935EulwtNn7Nw&#39;;return true;">Shrine, but I deliberately made it generic so that other file attachment libraries can use it as well and avoid reimplementing the same functionality.

Some features that are added on top of MiniMagick:
  • resizing macros:
    • <a href="https://github.com/janko-m/image_processing/blob/master/doc/minimagick.md#resize_to_limit" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fjanko-m%2Fimage_processing%2Fblob%2Fmaster%2Fdoc%2Fminimagick.md%23resize_to_limit\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGhZ33zKAHAQqxemkt7x0aug0Vs4g&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fjanko-m%2Fimage_processing%2Fblob%2Fmaster%2Fdoc%2Fminimagick.md%23resize_to_limit\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGhZ33zKAHAQqxemkt7x0aug0Vs4g&#39;;return true;">#resize_to_limit
    • <a href="https://github.com/janko-m/image_processing/blob/master/doc/minimagick.md#resize_to_fit" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fjanko-m%2Fimage_processing%2Fblob%2Fmaster%2Fdoc%2Fminimagick.md%23resize_to_fit\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGsf3ZE4fuJbuYbQvpd7sP47YNYmQ&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fjanko-m%2Fimage_processing%2Fblob%2Fmaster%2Fdoc%2Fminimagick.md%23resize_to_fit\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGsf3ZE4fuJbuYbQvpd7sP47YNYmQ&#39;;return true;">#resize_to_fit
    • <a href="https://github.com/janko-m/image_processing/blob/master/doc/minimagick.md#resize_to_fill" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fjanko-m%2Fimage_processing%2Fblob%2Fmaster%2Fdoc%2Fminimagick.md%23resize_to_fill\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEByQ8O_VrBoR4q7zfhujufuGTj3A&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fjanko-m%2Fimage_processing%2Fblob%2Fmaster%2Fdoc%2Fminimagick.md%23resize_to_fill\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEByQ8O_VrBoR4q7zfhujufuGTj3A&#39;;return true;">#resize_to_fill
    • <a href="https://github.com/janko-m/image_processing/blob/master/doc/minimagick.md#resize_and_pad" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fjanko-m%2Fimage_processing%2Fblob%2Fmaster%2Fdoc%2Fminimagick.md%23resize_and_pad\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNG3NStWRozx5wCWuXqkNtB3aTb-fw&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fjanko-m%2Fimage_processing%2Fblob%2Fmaster%2Fdoc%2Fminimagick.md%23resize_and_pad\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNG3NStWRozx5wCWuXqkNtB3aTb-fw&#39;;return true;">#resize_and_pad
  • <a href="https://www.imagemagick.org/script/command-line-options.php#auto-orient" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fwww.imagemagick.org%2Fscript%2Fcommand-line-options.php%23auto-orient\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHQjjUWazKYe0EBmvXSgIMSwhGHhQ&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fwww.imagemagick.org%2Fscript%2Fcommand-line-options.php%23auto-orient\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHQjjUWazKYe0EBmvXSgIMSwhGHhQ&#39;;return true;">automatic orientation
  • <a href="https://github.com/janko-m/image_processing/blob/master/doc/minimagick.md#sharpening" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fjanko-m%2Fimage_processing%2Fblob%2Fmaster%2Fdoc%2Fminimagick.md%23sharpening\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNExW9KToANIG2fIriBAkah05rWBHw&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fjanko-m%2Fimage_processing%2Fblob%2Fmaster%2Fdoc%2Fminimagick.md%23sharpening\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNExW9KToANIG2fIriBAkah05rWBHw&#39;;return true;">automatic thumbnail sharpening
  • avoids the complex MiniMagick::Image class
But probably the biggest features of the ImageProcessing gem is that it also ships with the <a href="http://jcupitt.github.io/libvips/" target="_blank" rel="nofollow" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fjcupitt.github.io%2Flibvips%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNExbLS9c2pfUw_WmDNrlx4eSKpeOw&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fjcupitt.github.io%2Flibvips%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNExbLS9c2pfUw_WmDNrlx4eSKpeOw&#39;;return true;">libvips backend. Libvips is an alternative to ImageMagick. The advantage of using libvips is that in most cases it's multiple times faster than ImageMagick. This is a big deal.

The ImageProcessing gem provides a uniform API regardless of which backend is used, just the operations/options specific to ImageMagick and libvips differ of course. That means the potential ActiveStorage integration would work for both ImageMagick and libvips, allowing the user to swap backends with just a single line of code.

So, my question is: would you be open to accepting a pull request that replaces MiniMagick with ImageProcessing?

Kind regards,
Janko

--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/rubyonrails-core.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: [Feature] Updating ActiveStorage to use the ImageProcessing gem

Janko Marohnić
Thanks for sharing your thoughts. I was hoping that ImageProcessing would be able to replace the mini_magick gem, as that would allow removing a lot of code. Having the option for ImageProcessing to be an optional upgrade would mean the Rails team would still have to keep and maintain the pure-MiniMagick code, which would be less than ideal as there is no advantage in using pure MiniMagick. Note that switching to ImageProcessing should still retain 100% compatibility with the current ActiveStorage API, from what I've observed.

If Rails 5.2 ship really has sailed, then I don't see a way how we'll be able to replace the MiniMagick code later on without breaking backwards compatibility, as at the moment MiniMagick is an optional dependency. Only if we make ImageProcessing a runtime dependency instead of optional, but ImageProcessing pulls in both mini_magick and ruby-vips gems (though it does not require them).

On Thursday, April 5, 2018 at 5:52:29 PM UTC+2, DHH wrote:
I like that an idea as an optional upgrade. The Rails 5.2 ship has already sailed, so we'll want to make sure that any optional upgrade honors the existing transformation API. But I could see making the Variation#transform call a strategy that's configurable. And it'll just start with what we have now, but can be upgraded/replaced with this solution.

On Wednesday, April 4, 2018 at 5:18:25 PM UTC-7, Janko Marohnić wrote:
Hello everyone,

ActiveStorage performs image processing on-the-fly, and for that it currently uses raw MiniMagick. As we can see from <a href="https://github.com/carrierwaveuploader/carrierwave/blob/master/lib/carrierwave/processing/mini_magick.rb" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fcarrierwaveuploader%2Fcarrierwave%2Fblob%2Fmaster%2Flib%2Fcarrierwave%2Fprocessing%2Fmini_magick.rb\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFkswQ_2Fw65CfQp75rzuUVP3E7KA&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fcarrierwaveuploader%2Fcarrierwave%2Fblob%2Fmaster%2Flib%2Fcarrierwave%2Fprocessing%2Fmini_magick.rb\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFkswQ_2Fw65CfQp75rzuUVP3E7KA&#39;;return true;">CarrierWave and <a href="https://github.com/refile/refile-mini_magick" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Frefile%2Frefile-mini_magick\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFr8s3qkc98Mj--QKmp5-Pc1Vex6A&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Frefile%2Frefile-mini_magick\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFr8s3qkc98Mj--QKmp5-Pc1Vex6A&#39;;return true;">Refile, for common image resizing it's not enough to just use simple ImageMagick options, certain resizers like "resize_to_fill" require a combination of ImageMagick options to achieve the desired effect.

To avoid reimplementing this functionality, I propose that ActiveStorage uses the <a href="https://github.com/janko-m/image_processing" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fjanko-m%2Fimage_processing\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGljihnUhuVBVG3c07js3rsV3-PnA&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fjanko-m%2Fimage_processing\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGljihnUhuVBVG3c07js3rsV3-PnA&#39;;return true;">ImageProcessing gem, as a layer on top of MiniMagick. The ImageProcessing gem has been developing for almost 3 years now, and it's gotten pretty good. It was primarily written to be used with <a href="https://github.com/shrinerb/shrine" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fshrinerb%2Fshrine\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNF8LQm1BqB91FP5b935EulwtNn7Nw&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fshrinerb%2Fshrine\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNF8LQm1BqB91FP5b935EulwtNn7Nw&#39;;return true;">Shrine, but I deliberately made it generic so that other file attachment libraries can use it as well and avoid reimplementing the same functionality.

Some features that are added on top of MiniMagick:
  • resizing macros:
    • <a href="https://github.com/janko-m/image_processing/blob/master/doc/minimagick.md#resize_to_limit" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fjanko-m%2Fimage_processing%2Fblob%2Fmaster%2Fdoc%2Fminimagick.md%23resize_to_limit\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGhZ33zKAHAQqxemkt7x0aug0Vs4g&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fjanko-m%2Fimage_processing%2Fblob%2Fmaster%2Fdoc%2Fminimagick.md%23resize_to_limit\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGhZ33zKAHAQqxemkt7x0aug0Vs4g&#39;;return true;">#resize_to_limit
    • <a href="https://github.com/janko-m/image_processing/blob/master/doc/minimagick.md#resize_to_fit" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fjanko-m%2Fimage_processing%2Fblob%2Fmaster%2Fdoc%2Fminimagick.md%23resize_to_fit\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGsf3ZE4fuJbuYbQvpd7sP47YNYmQ&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fjanko-m%2Fimage_processing%2Fblob%2Fmaster%2Fdoc%2Fminimagick.md%23resize_to_fit\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGsf3ZE4fuJbuYbQvpd7sP47YNYmQ&#39;;return true;">#resize_to_fit
    • <a href="https://github.com/janko-m/image_processing/blob/master/doc/minimagick.md#resize_to_fill" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fjanko-m%2Fimage_processing%2Fblob%2Fmaster%2Fdoc%2Fminimagick.md%23resize_to_fill\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEByQ8O_VrBoR4q7zfhujufuGTj3A&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fjanko-m%2Fimage_processing%2Fblob%2Fmaster%2Fdoc%2Fminimagick.md%23resize_to_fill\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEByQ8O_VrBoR4q7zfhujufuGTj3A&#39;;return true;">#resize_to_fill
    • <a href="https://github.com/janko-m/image_processing/blob/master/doc/minimagick.md#resize_and_pad" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fjanko-m%2Fimage_processing%2Fblob%2Fmaster%2Fdoc%2Fminimagick.md%23resize_and_pad\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNG3NStWRozx5wCWuXqkNtB3aTb-fw&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fjanko-m%2Fimage_processing%2Fblob%2Fmaster%2Fdoc%2Fminimagick.md%23resize_and_pad\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNG3NStWRozx5wCWuXqkNtB3aTb-fw&#39;;return true;">#resize_and_pad
  • <a href="https://www.imagemagick.org/script/command-line-options.php#auto-orient" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fwww.imagemagick.org%2Fscript%2Fcommand-line-options.php%23auto-orient\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHQjjUWazKYe0EBmvXSgIMSwhGHhQ&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fwww.imagemagick.org%2Fscript%2Fcommand-line-options.php%23auto-orient\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHQjjUWazKYe0EBmvXSgIMSwhGHhQ&#39;;return true;">automatic orientation
  • <a href="https://github.com/janko-m/image_processing/blob/master/doc/minimagick.md#sharpening" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fjanko-m%2Fimage_processing%2Fblob%2Fmaster%2Fdoc%2Fminimagick.md%23sharpening\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNExW9KToANIG2fIriBAkah05rWBHw&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fjanko-m%2Fimage_processing%2Fblob%2Fmaster%2Fdoc%2Fminimagick.md%23sharpening\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNExW9KToANIG2fIriBAkah05rWBHw&#39;;return true;">automatic thumbnail sharpening
  • avoids the complex MiniMagick::Image class
But probably the biggest features of the ImageProcessing gem is that it also ships with the <a href="http://jcupitt.github.io/libvips/" rel="nofollow" target="_blank" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fjcupitt.github.io%2Flibvips%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNExbLS9c2pfUw_WmDNrlx4eSKpeOw&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fjcupitt.github.io%2Flibvips%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNExbLS9c2pfUw_WmDNrlx4eSKpeOw&#39;;return true;">libvips backend. Libvips is an alternative to ImageMagick. The advantage of using libvips is that in most cases it's multiple times faster than ImageMagick. This is a big deal.

The ImageProcessing gem provides a uniform API regardless of which backend is used, just the operations/options specific to ImageMagick and libvips differ of course. That means the potential ActiveStorage integration would work for both ImageMagick and libvips, allowing the user to swap backends with just a single line of code.

So, my question is: would you be open to accepting a pull request that replaces MiniMagick with ImageProcessing?

Kind regards,
Janko

--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/rubyonrails-core.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: [Feature] Updating ActiveStorage to use the ImageProcessing gem

DHH-2
5.2 ship has indeed sailed. We're very close to a final release after months of RC'ing. I don't think it's a big issue maintaining the 8 lines of code that's related to using MiniMagick for transformations: https://github.com/rails/rails/blob/master/activestorage/app/models/active_storage/variation.rb#L59-L67. We have to weigh that against taking on another dependency. On that note alone, I don't think the trade is worth it. But I do like the idea of having easier access to common transformations. And it also sounds nice to have a faster way of doing the transformations.

Happy to see us target a refactoring for Rails 6.0 on this 👍


On Thursday, April 5, 2018 at 9:07:34 AM UTC-7, Janko Marohnić wrote:
Thanks for sharing your thoughts. I was hoping that ImageProcessing would be able to replace the mini_magick gem, as that would allow removing a lot of code. Having the option for ImageProcessing to be an optional upgrade would mean the Rails team would still have to keep and maintain the pure-MiniMagick code, which would be less than ideal as there is no advantage in using pure MiniMagick. Note that switching to ImageProcessing should still retain 100% compatibility with the current ActiveStorage API, from what I've observed.

If Rails 5.2 ship really has sailed, then I don't see a way how we'll be able to replace the MiniMagick code later on without breaking backwards compatibility, as at the moment MiniMagick is an optional dependency. Only if we make ImageProcessing a runtime dependency instead of optional, but ImageProcessing pulls in both mini_magick and ruby-vips gems (though it does not require them).

On Thursday, April 5, 2018 at 5:52:29 PM UTC+2, DHH wrote:
I like that an idea as an optional upgrade. The Rails 5.2 ship has already sailed, so we'll want to make sure that any optional upgrade honors the existing transformation API. But I could see making the Variation#transform call a strategy that's configurable. And it'll just start with what we have now, but can be upgraded/replaced with this solution.

On Wednesday, April 4, 2018 at 5:18:25 PM UTC-7, Janko Marohnić wrote:
Hello everyone,

ActiveStorage performs image processing on-the-fly, and for that it currently uses raw MiniMagick. As we can see from <a href="https://github.com/carrierwaveuploader/carrierwave/blob/master/lib/carrierwave/processing/mini_magick.rb" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fcarrierwaveuploader%2Fcarrierwave%2Fblob%2Fmaster%2Flib%2Fcarrierwave%2Fprocessing%2Fmini_magick.rb\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFkswQ_2Fw65CfQp75rzuUVP3E7KA&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fcarrierwaveuploader%2Fcarrierwave%2Fblob%2Fmaster%2Flib%2Fcarrierwave%2Fprocessing%2Fmini_magick.rb\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFkswQ_2Fw65CfQp75rzuUVP3E7KA&#39;;return true;">CarrierWave and <a href="https://github.com/refile/refile-mini_magick" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Frefile%2Frefile-mini_magick\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFr8s3qkc98Mj--QKmp5-Pc1Vex6A&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Frefile%2Frefile-mini_magick\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFr8s3qkc98Mj--QKmp5-Pc1Vex6A&#39;;return true;">Refile, for common image resizing it's not enough to just use simple ImageMagick options, certain resizers like "resize_to_fill" require a combination of ImageMagick options to achieve the desired effect.

To avoid reimplementing this functionality, I propose that ActiveStorage uses the <a href="https://github.com/janko-m/image_processing" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fjanko-m%2Fimage_processing\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGljihnUhuVBVG3c07js3rsV3-PnA&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fjanko-m%2Fimage_processing\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGljihnUhuVBVG3c07js3rsV3-PnA&#39;;return true;">ImageProcessing gem, as a layer on top of MiniMagick. The ImageProcessing gem has been developing for almost 3 years now, and it's gotten pretty good. It was primarily written to be used with <a href="https://github.com/shrinerb/shrine" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fshrinerb%2Fshrine\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNF8LQm1BqB91FP5b935EulwtNn7Nw&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fshrinerb%2Fshrine\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNF8LQm1BqB91FP5b935EulwtNn7Nw&#39;;return true;">Shrine, but I deliberately made it generic so that other file attachment libraries can use it as well and avoid reimplementing the same functionality.

Some features that are added on top of MiniMagick:
  • resizing macros:
    • <a href="https://github.com/janko-m/image_processing/blob/master/doc/minimagick.md#resize_to_limit" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fjanko-m%2Fimage_processing%2Fblob%2Fmaster%2Fdoc%2Fminimagick.md%23resize_to_limit\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGhZ33zKAHAQqxemkt7x0aug0Vs4g&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fjanko-m%2Fimage_processing%2Fblob%2Fmaster%2Fdoc%2Fminimagick.md%23resize_to_limit\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGhZ33zKAHAQqxemkt7x0aug0Vs4g&#39;;return true;">#resize_to_limit
    • <a href="https://github.com/janko-m/image_processing/blob/master/doc/minimagick.md#resize_to_fit" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fjanko-m%2Fimage_processing%2Fblob%2Fmaster%2Fdoc%2Fminimagick.md%23resize_to_fit\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGsf3ZE4fuJbuYbQvpd7sP47YNYmQ&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fjanko-m%2Fimage_processing%2Fblob%2Fmaster%2Fdoc%2Fminimagick.md%23resize_to_fit\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGsf3ZE4fuJbuYbQvpd7sP47YNYmQ&#39;;return true;">#resize_to_fit
    • <a href="https://github.com/janko-m/image_processing/blob/master/doc/minimagick.md#resize_to_fill" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fjanko-m%2Fimage_processing%2Fblob%2Fmaster%2Fdoc%2Fminimagick.md%23resize_to_fill\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEByQ8O_VrBoR4q7zfhujufuGTj3A&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fjanko-m%2Fimage_processing%2Fblob%2Fmaster%2Fdoc%2Fminimagick.md%23resize_to_fill\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEByQ8O_VrBoR4q7zfhujufuGTj3A&#39;;return true;">#resize_to_fill
    • <a href="https://github.com/janko-m/image_processing/blob/master/doc/minimagick.md#resize_and_pad" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fjanko-m%2Fimage_processing%2Fblob%2Fmaster%2Fdoc%2Fminimagick.md%23resize_and_pad\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNG3NStWRozx5wCWuXqkNtB3aTb-fw&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fjanko-m%2Fimage_processing%2Fblob%2Fmaster%2Fdoc%2Fminimagick.md%23resize_and_pad\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNG3NStWRozx5wCWuXqkNtB3aTb-fw&#39;;return true;">#resize_and_pad
  • <a href="https://www.imagemagick.org/script/command-line-options.php#auto-orient" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fwww.imagemagick.org%2Fscript%2Fcommand-line-options.php%23auto-orient\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHQjjUWazKYe0EBmvXSgIMSwhGHhQ&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fwww.imagemagick.org%2Fscript%2Fcommand-line-options.php%23auto-orient\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHQjjUWazKYe0EBmvXSgIMSwhGHhQ&#39;;return true;">automatic orientation
  • <a href="https://github.com/janko-m/image_processing/blob/master/doc/minimagick.md#sharpening" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fjanko-m%2Fimage_processing%2Fblob%2Fmaster%2Fdoc%2Fminimagick.md%23sharpening\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNExW9KToANIG2fIriBAkah05rWBHw&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fjanko-m%2Fimage_processing%2Fblob%2Fmaster%2Fdoc%2Fminimagick.md%23sharpening\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNExW9KToANIG2fIriBAkah05rWBHw&#39;;return true;">automatic thumbnail sharpening
  • avoids the complex MiniMagick::Image class
But probably the biggest features of the ImageProcessing gem is that it also ships with the <a href="http://jcupitt.github.io/libvips/" rel="nofollow" target="_blank" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fjcupitt.github.io%2Flibvips%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNExbLS9c2pfUw_WmDNrlx4eSKpeOw&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fjcupitt.github.io%2Flibvips%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNExbLS9c2pfUw_WmDNrlx4eSKpeOw&#39;;return true;">libvips backend. Libvips is an alternative to ImageMagick. The advantage of using libvips is that in most cases it's multiple times faster than ImageMagick. This is a big deal.

The ImageProcessing gem provides a uniform API regardless of which backend is used, just the operations/options specific to ImageMagick and libvips differ of course. That means the potential ActiveStorage integration would work for both ImageMagick and libvips, allowing the user to swap backends with just a single line of code.

So, my question is: would you be open to accepting a pull request that replaces MiniMagick with ImageProcessing?

Kind regards,
Janko

--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/rubyonrails-core.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: [Feature] Updating ActiveStorage to use the ImageProcessing gem

Janko Marohnić
It's great to hear that you're interested! Btw, here is the PR: https://github.com/rails/rails/pull/32471

Once Rails 5.2 is released, we can discuss plans of getting this in for Rails 6.0.

On Friday, April 6, 2018 at 7:34:21 PM UTC+2, DHH wrote:
5.2 ship has indeed sailed. We're very close to a final release after months of RC'ing. I don't think it's a big issue maintaining the 8 lines of code that's related to using MiniMagick for transformations: <a href="https://github.com/rails/rails/blob/master/activestorage/app/models/active_storage/variation.rb#L59-L67" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Frails%2Frails%2Fblob%2Fmaster%2Factivestorage%2Fapp%2Fmodels%2Factive_storage%2Fvariation.rb%23L59-L67\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNE5Sjpl1fX-i9StNxJN1F4nfz3qxA&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Frails%2Frails%2Fblob%2Fmaster%2Factivestorage%2Fapp%2Fmodels%2Factive_storage%2Fvariation.rb%23L59-L67\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNE5Sjpl1fX-i9StNxJN1F4nfz3qxA&#39;;return true;">https://github.com/rails/rails/blob/master/activestorage/app/models/active_storage/variation.rb#L59-L67. We have to weigh that against taking on another dependency. On that note alone, I don't think the trade is worth it. But I do like the idea of having easier access to common transformations. And it also sounds nice to have a faster way of doing the transformations.

Happy to see us target a refactoring for Rails 6.0 on this 👍


On Thursday, April 5, 2018 at 9:07:34 AM UTC-7, Janko Marohnić wrote:
Thanks for sharing your thoughts. I was hoping that ImageProcessing would be able to replace the mini_magick gem, as that would allow removing a lot of code. Having the option for ImageProcessing to be an optional upgrade would mean the Rails team would still have to keep and maintain the pure-MiniMagick code, which would be less than ideal as there is no advantage in using pure MiniMagick. Note that switching to ImageProcessing should still retain 100% compatibility with the current ActiveStorage API, from what I've observed.

If Rails 5.2 ship really has sailed, then I don't see a way how we'll be able to replace the MiniMagick code later on without breaking backwards compatibility, as at the moment MiniMagick is an optional dependency. Only if we make ImageProcessing a runtime dependency instead of optional, but ImageProcessing pulls in both mini_magick and ruby-vips gems (though it does not require them).

On Thursday, April 5, 2018 at 5:52:29 PM UTC+2, DHH wrote:
I like that an idea as an optional upgrade. The Rails 5.2 ship has already sailed, so we'll want to make sure that any optional upgrade honors the existing transformation API. But I could see making the Variation#transform call a strategy that's configurable. And it'll just start with what we have now, but can be upgraded/replaced with this solution.

On Wednesday, April 4, 2018 at 5:18:25 PM UTC-7, Janko Marohnić wrote:
Hello everyone,

ActiveStorage performs image processing on-the-fly, and for that it currently uses raw MiniMagick. As we can see from <a href="https://github.com/carrierwaveuploader/carrierwave/blob/master/lib/carrierwave/processing/mini_magick.rb" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fcarrierwaveuploader%2Fcarrierwave%2Fblob%2Fmaster%2Flib%2Fcarrierwave%2Fprocessing%2Fmini_magick.rb\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFkswQ_2Fw65CfQp75rzuUVP3E7KA&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fcarrierwaveuploader%2Fcarrierwave%2Fblob%2Fmaster%2Flib%2Fcarrierwave%2Fprocessing%2Fmini_magick.rb\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFkswQ_2Fw65CfQp75rzuUVP3E7KA&#39;;return true;">CarrierWave and <a href="https://github.com/refile/refile-mini_magick" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Frefile%2Frefile-mini_magick\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFr8s3qkc98Mj--QKmp5-Pc1Vex6A&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Frefile%2Frefile-mini_magick\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFr8s3qkc98Mj--QKmp5-Pc1Vex6A&#39;;return true;">Refile, for common image resizing it's not enough to just use simple ImageMagick options, certain resizers like "resize_to_fill" require a combination of ImageMagick options to achieve the desired effect.

To avoid reimplementing this functionality, I propose that ActiveStorage uses the <a href="https://github.com/janko-m/image_processing" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fjanko-m%2Fimage_processing\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGljihnUhuVBVG3c07js3rsV3-PnA&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fjanko-m%2Fimage_processing\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGljihnUhuVBVG3c07js3rsV3-PnA&#39;;return true;">ImageProcessing gem, as a layer on top of MiniMagick. The ImageProcessing gem has been developing for almost 3 years now, and it's gotten pretty good. It was primarily written to be used with <a href="https://github.com/shrinerb/shrine" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fshrinerb%2Fshrine\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNF8LQm1BqB91FP5b935EulwtNn7Nw&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fshrinerb%2Fshrine\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNF8LQm1BqB91FP5b935EulwtNn7Nw&#39;;return true;">Shrine, but I deliberately made it generic so that other file attachment libraries can use it as well and avoid reimplementing the same functionality.

Some features that are added on top of MiniMagick:
  • resizing macros:
    • <a href="https://github.com/janko-m/image_processing/blob/master/doc/minimagick.md#resize_to_limit" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fjanko-m%2Fimage_processing%2Fblob%2Fmaster%2Fdoc%2Fminimagick.md%23resize_to_limit\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGhZ33zKAHAQqxemkt7x0aug0Vs4g&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fjanko-m%2Fimage_processing%2Fblob%2Fmaster%2Fdoc%2Fminimagick.md%23resize_to_limit\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGhZ33zKAHAQqxemkt7x0aug0Vs4g&#39;;return true;">#resize_to_limit
    • <a href="https://github.com/janko-m/image_processing/blob/master/doc/minimagick.md#resize_to_fit" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fjanko-m%2Fimage_processing%2Fblob%2Fmaster%2Fdoc%2Fminimagick.md%23resize_to_fit\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGsf3ZE4fuJbuYbQvpd7sP47YNYmQ&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fjanko-m%2Fimage_processing%2Fblob%2Fmaster%2Fdoc%2Fminimagick.md%23resize_to_fit\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGsf3ZE4fuJbuYbQvpd7sP47YNYmQ&#39;;return true;">#resize_to_fit
    • <a href="https://github.com/janko-m/image_processing/blob/master/doc/minimagick.md#resize_to_fill" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fjanko-m%2Fimage_processing%2Fblob%2Fmaster%2Fdoc%2Fminimagick.md%23resize_to_fill\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEByQ8O_VrBoR4q7zfhujufuGTj3A&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fjanko-m%2Fimage_processing%2Fblob%2Fmaster%2Fdoc%2Fminimagick.md%23resize_to_fill\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEByQ8O_VrBoR4q7zfhujufuGTj3A&#39;;return true;">#resize_to_fill
    • <a href="https://github.com/janko-m/image_processing/blob/master/doc/minimagick.md#resize_and_pad" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fjanko-m%2Fimage_processing%2Fblob%2Fmaster%2Fdoc%2Fminimagick.md%23resize_and_pad\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNG3NStWRozx5wCWuXqkNtB3aTb-fw&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fjanko-m%2Fimage_processing%2Fblob%2Fmaster%2Fdoc%2Fminimagick.md%23resize_and_pad\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNG3NStWRozx5wCWuXqkNtB3aTb-fw&#39;;return true;">#resize_and_pad
  • <a href="https://www.imagemagick.org/script/command-line-options.php#auto-orient" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fwww.imagemagick.org%2Fscript%2Fcommand-line-options.php%23auto-orient\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHQjjUWazKYe0EBmvXSgIMSwhGHhQ&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fwww.imagemagick.org%2Fscript%2Fcommand-line-options.php%23auto-orient\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHQjjUWazKYe0EBmvXSgIMSwhGHhQ&#39;;return true;">automatic orientation
  • <a href="https://github.com/janko-m/image_processing/blob/master/doc/minimagick.md#sharpening" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fjanko-m%2Fimage_processing%2Fblob%2Fmaster%2Fdoc%2Fminimagick.md%23sharpening\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNExW9KToANIG2fIriBAkah05rWBHw&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fjanko-m%2Fimage_processing%2Fblob%2Fmaster%2Fdoc%2Fminimagick.md%23sharpening\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNExW9KToANIG2fIriBAkah05rWBHw&#39;;return true;">automatic thumbnail sharpening
  • avoids the complex MiniMagick::Image class
But probably the biggest features of the ImageProcessing gem is that it also ships with the <a href="http://jcupitt.github.io/libvips/" rel="nofollow" target="_blank" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fjcupitt.github.io%2Flibvips%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNExbLS9c2pfUw_WmDNrlx4eSKpeOw&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fjcupitt.github.io%2Flibvips%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNExbLS9c2pfUw_WmDNrlx4eSKpeOw&#39;;return true;">libvips backend. Libvips is an alternative to ImageMagick. The advantage of using libvips is that in most cases it's multiple times faster than ImageMagick. This is a big deal.

The ImageProcessing gem provides a uniform API regardless of which backend is used, just the operations/options specific to ImageMagick and libvips differ of course. That means the potential ActiveStorage integration would work for both ImageMagick and libvips, allowing the user to swap backends with just a single line of code.

So, my question is: would you be open to accepting a pull request that replaces MiniMagick with ImageProcessing?

Kind regards,
Janko

--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/rubyonrails-core.
For more options, visit https://groups.google.com/d/optout.