Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Optimizing Image Cropping and Writing Performance with Ruby Vips #406

Unanswered
JohnAnon9771 asked this question in Q&A
Discussion options

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!

You must be logged in to vote

Replies: 1 comment 5 replies

Comment options

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.

You must be logged in to vote
5 replies
Comment options

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.

Comment options

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.

Comment options

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.

Comment options

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?

Comment options

You might need to rebuild libpng, or libspng. You'd have to experiment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Category
Q&A
Labels
None yet

AltStyle によって変換されたページ (->オリジナル) /