-
Notifications
You must be signed in to change notification settings - Fork 62
Optimizing Image Cropping and Writing Performance with Ruby Vips #406
-
Hi,
I’m working on a project that uses Ruby Vips to crop and adjust images for printing. However, I’ve encountered performance issues, specifically with the speed of writing the cropped image to a file. The writing process is quite slow, and I’d like to know how I can optimize this further to speed up the entire operation, as I need to transmit the processed image as quickly as possible.
Here’s the relevant code I’m using for cropping the image:
class ImageCropVips def self.crop(image_path) img = Vips::Image.new_from_file(image_path) bbox = Trimer.find_trim(img) dpi = (img.xres > 0 ? img.xres : 11.81) * 25.4 puts "\n VIPS bbox: #{bbox}, dpi: #{dpi} \n" if bbox tmp = Tempfile.new(["tmp", '.png']) img.crop(*bbox).write_to_file(tmp.path, Q: 100) else nil end end end class Trimer def self.find_trim(image) return [0, 0, image.width, image.height] if image.bands < 4 alpha_channel = image.extract_band(3) _, first_row = alpha_channel.profile left = first_row.min _, first_row = alpha_channel.fliphor.profile right = image.width - first_row.min first_column, = alpha_channel.profile top = first_column.min first_column, = alpha_channel.flipver.profile bottom = image.height - first_column.min width = right - left height = bottom - top [left, top, width, height] end end
The trimming works fine, but the file writing step (write_to_file
) takes a significant amount of time. Do you have any suggestions for speeding up the writing process or improving overall performance? Any insights would be greatly appreciated!
Thank you!
Beta Was this translation helpful? Give feedback.
All reactions
Replies: 1 comment 5 replies
-
Hi @JohnAnon9771,
find_trim
is built into libvips, and you can use [n]
for band extract. You can probably write (untested):
img = Vips::Image.new_from_file(image_path) bbox = img[3].find_trim img.crop(*bbox).write_to_file("x.png")
How large are these files? PNG is a very slow format, so if the images are large, write will take a long time. Are there any other formats you could use? webp or tiff would probably be quicker.
Beta Was this translation helpful? Give feedback.
All reactions
-
Yes, they are 4200x4800 png images, with an average size of 10mb. Unfortunately, I can only use png, as the image will be sent to a printer that only accepts png.
Beta Was this translation helpful? Give feedback.
All reactions
-
Ah, shame. Yes, it'll be slow:
$ time vips crop wtc.jpg x.png 0 0 4200 4800
real 0m1.755s
user 0m1.883s
sys 0m0.191s
So 1.75s just for a 4800 x 4200 PNG write on this Ubuntu 24.04 PC. PNG write is single-threaded, sadly.
Most PNG write time is spent in libz, so it might be worth experimenting with other versions. It's such a critical library that many people have attempted faster implementations, for example libz-ng:
https://github.com/zlib-ng/zlib-ng
You can also disable PNG zip compression. This makes it a lot quicker, though files will be larger:
$ time vips crop wtc.jpg x.png[compression=0] 0 0 4200 4800
real 0m0.434s
user 0m0.328s
sys 0m0.279s
$ ls -l x.png x0.png
-rw-r--r-- 1 john john 60584302 Oct 18 14:03 x0.png
-rw-r--r-- 1 john john 46732001 Oct 18 14:03 x.png
600k vs. 470k.
Beta Was this translation helpful? Give feedback.
All reactions
-
Or tiff with zlib compression:
$ time vips crop wtc.jpg x.tif[tile,compression=deflate] 0 0 4200 4800
real 0m1.009s
user 0m1.128s
sys 0m0.194s
$ ls -l x.tif
-rw-r--r-- 1 john john 37114608 Oct 18 14:07 x.tif
Almost twice as fast as PNG, with much better compression. PNG really is a poorly designed format.
Beta Was this translation helpful? Give feedback.
All reactions
-
Thank you very much for the super detailed answer! I'll try to do it without compression, it really did increase the speed a lot. One question: does zlib-ng work automatically with libvips? How can I use it?
Beta Was this translation helpful? Give feedback.
All reactions
-
You might need to rebuild libpng, or libspng. You'd have to experiment.
Beta Was this translation helpful? Give feedback.
All reactions
-
👍 1