libvips/ruby-vips

The pngsave method is not recognizing the bitdepth option

demitrious-tom opened this issue · 5 comments

OS: WSL: Unbuntu 20.04

Hello,
I am attempting to use ruby-vips 2.1 in a rails 6.1.3 application using ruby 3.0.0 to take file that has been decoded from a base64 encoded string and use #pngsave to save that file as an 8-bit png, by passing in the bitdepth option with the value 8. I discovered this documentation https://www.rubydoc.info/gems/ruby-vips/Vips/Image#pngsave-instance_method which says that 8 is a valid option though after reading this comment #230 (comment) I was not sure if only 1, 2 and 4 bit were supported. In any case regardless of the integer value I pass, the error that I get when attempting to do this does not make much sense; "Vips::Error (unable to call pngsave: unknown option bitdepth)". This is the code:

File.open('design.png', 'wb') do |f|
  f.write(Base64.decode64(base_64_encoded_data))
end
im = Vips::Image.new_from_file('design.png')
im.pngsave('new_design.png', bitdepth: 4)

If I call the pngsave method with any other option it behaves as expected. I am a little embarrassed to admit I not sure how to check which version of libvips I installed a week ago with sudo apt-get install libvips on WSL Unbuntu after typing libvips -v, --version I was out of ideas :)

Hi @demitrious-tom,

The bitdepth option was added in libvips 8.10, so I guess you have one from before that.

Though I think you want a different option --- you want a palette-ized PNG, ie. one with a one-band 8-bit index, plus an RGB lookup table. That option was added back in 8.7, so you're probably OK.

Try:

im.pngsave('new_design.png', palette: true)

You can also load base64 directly into ruby-vips, in case you hadn't seen the option.

Sorry, I keep adding more things. You can get the version of the underlying libvips binary like this:

$ irb
irb(main):001:0> require 'vips'
=> true
irb(main):002:0> Vips::VERSION
=> "2.1.3"
irb(main):004:0> Vips::version_string
=> "8.12.0-Fri Sep 24 10:49:15 UTC 2021"
irb(main):005:0> Vips::version(0)
=> 8
irb(main):006:0> Vips::version(1)
=> 12
irb(main):007:0> Vips::version(2)
=> 0

Or check your package manager, of course.

Yup looks like you were right looks like I was running 8.9.1. From your description

Though I think you want a different option --- you want a palette-ized PNG, ie. one with a one-band 8-bit index, plus an RGB lookup table.

That does sound like what I was actually trying to do. That option you suggested did appear to work, or rather it didn't throw an error, though outside your responsibility as a maintainer is there some way I can confirm if the desired effect was achieved? Also I was wondering with regards to documentation is there somewhere I should be looking, because I didn't see an example or method name along the lines new_from_base64.

You need to create a custom source for base64. It's just a couple of lines:

https://www.libvips.org/2019/11/29/True-streaming-for-libvips.html

Those examples use py, but ruby is almost the same, though it uses blocks:

https://www.rubydoc.info/gems/ruby-vips/Vips/SourceCustom