Closed mokolabs closed 6 years ago
And, btw, if cmd blocks are no longer supported for the minimagick implementation (which would be a bummer), is there another way that I can save progressive JPEGs with 85% quality and support for mild sharpening?
Oh, I think I now see the answer in the README. Sorry... I looked there, but somehow missed it before.
I would use #method_missing or #append, right?
The new API looks awesome.
Thank you ❤️
How can I do this with the new API?
First, note that the MiniMagick
module still hasn't been converted to the new API, though I have the implementation finished locally and will push it out probably tomorrow.
The chainable API will automatically delegate any undefined methods to the internal convert
command (just like the new Vips
module is delegating any undefined methods to the internal Vips::Image
object), so the equivalent of
resize_to_fill(image, 1024, 1024) do |cmd|
cmd.interlace('plane')
cmd.quality 85
cmd.sharpen "0x1.0"
end
would with the new API be
ImageProcessing::MiniMagick
.interlace("plane")
.quality(85)
.sharpen("0x1.0")
.resize_to_fill(1024, 1024)
.call(image)
And yes, that's the #method_missing
section.
My bad, it seems that I already pushed out the code to master
😃. I will then probably release it some time tomorrow.
Thanks for the quick reply.
While I have you... I'm working on a new app that's using Shrine and minimagick-based image_processing, but I have been experimenting with vips support.
In ruby-vips, you can do this:
file = Vips::Image.new_from_file("apple.jpg")
processed = ImageProcessing::Vips
.source(file)
.autorot
.resize_to_limit(1024, 1024)
.sharpen(sigma: 1, x1: 1.5, y2: 15, y3: 15, m1: 0.4, m2: 0.8)
.call(save: false)
processed.write_to_file("apple2.jpg", Q: 85, interlace: true)
Can we set those same quality and interlacing options using vips image_processing?
Actually, I guess I'm already doing it with your code.
But, to slightly refactor my question, in the context of generating versions and using the processing plugin for Shrine, can I use #write_to_file when I generate versions in the process :store block?
Will it just work? Or do I need to tweak things a bit?
@mokolabs You can use the Vips::Image#write_to_file
when generating versions in Shrine, as it doesn't care how the processing has been done, it only cares that you return a list of IO
objects at the end of the process block:
# ... processing ...
File.open("apple2.jpg", "rb") # file object to return at the end of the processing block
Btw, I plan to extend the new API to accept path strings as source and destination, after which you'll be able to do:
ImageProcessing::Vips
.source("apple.jpg")
.autorot
.resize_to_limit(1024, 1024)
.sharpen(sigma: 1, x1: 1.5, y2: 15, y3: 15, m1: 0.4, m2: 0.8)
.saver(Q: 85, interlace: true)
.call(destination: "apple2.jpg")
The autorotation also won't be necessary, as I just pushed a change which makes it automatic (but still opt-outable).
Awesome.
Yeah, that code came from a test script where I was comparing minimagick with vips.
So, for the app using Shrine, I don't need to save the file to a different destination, but looks like that #saver method call is what I needed.
I'm seeing a 6X speed increase with the vips code in the Shrine app. Wow!
Thanks!
@mokolabs Yeah, libvips has really impressive speed! I also like that it has automatic caching, so when you're generating versions you don't need to generate the next version from the previous version for performance, you can generate all versions from the original image, and that will have roughly the same performance in total. This is not the case with ImageMagick, where there is a big performance difference between the two ways.
While I have you, I noticed that both vips-process
and carrierwave-vips
gems are applying sharpening by default, just like you're doing above. I don't know what does it do exactly, but do you think this is something that the image_processing gem should do automatically?
Yeah, I think that would be nice.
In general, I've always sharpened resized images -- either via ImageMagick or even manually in Photoshop using unsharp mask.
The sharpen settings for libvips were originally designed for print, though, so they have a different nomenclature than what you might see in typically screen applications.
This is what I'm using right now, but it's not perfect:
.sharpen(sigma: 1.5, x1: 1.5, y2: 15, y3: 15, m1: 0.4, m2: 0.8)
But it looks like carrier wave is using a sharpen mask. Maybe that would yield better results?
@mokolabs If you'll have time, do send a PR for this.
Ideally both MiniMagick and Vips module should share the same mask, though I'm not sure if the definitions map one-to-one. I was thinking we could add a new :sharpen
option to the #resize_*
methods, which would enable overriding the default sharpen mask, or skipping sharpening altogether if false
is passed in.
I'll close this ticket, as the original question has been addressed.
@janko-m Yeah, a :sharpen
option sounds nice.
I'll see if I can get a carrier-wave-style sharpen mask working first.
One tweak to my earlier suggestion: we should only enable sharpening for JPEGs by default. :)
Sharpening PNGs and GIFs may dramatically increase file sizes -- since these are lossless formats sharpening adds more information to images and that means bigger files.
Okay, here's a working version of a carrier-wave-style sharpen mask:
mask = Vips::Image.new_from_array [
[-1, -1, -1],
[-1, 24, -1],
[-1, -1, -1]], 16
ImageProcessing::Vips
.source(image)
.resize_to_fit(1024, 1024)
.saver(Q: quality, interlace: true)
.conv(mask)
.call
I don't really understanding the image mask values, but these settings produce a nice, subtle sharpening effect on resized images.
Here's a Wikipedia page on how these masks work in the abstract: https://en.wikipedia.org/wiki/Kernel_(image_processing)
Hey, Janko. The new API looks awesome.
Quick question, tho. I'm passing in custom image magick commands via the cmd block:
How can I do this with the new API?
Thanks!