Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Palleted PNG w. transparency unsupported #783

Closed
mfly opened this issue Oct 9, 2014 · 21 comments
Closed

Palleted PNG w. transparency unsupported #783

mfly opened this issue Oct 9, 2014 · 21 comments

Comments

@mfly
Copy link

mfly commented Oct 9, 2014

I was creating some PDF files with PNG images and some of them came out with transparency issues. After some tests I narrowed the issue to palleted PNG files. Unfortunately, most of images I use are palleted so it was a real problem.

Quick look at the code reveals that transparency is completely broken for palleted files:
https://github.com/prawnpdf/prawn/blob/master/lib/prawn/images/png.rb#L211

Then I created a test script and a set of test images (https://dl.dropboxusercontent.com/u/20390548/prawn-png.tar.bz2). As expected, everything seems to work, except the palleted PNG with transparency.

Maybe it would be a better idea to use some external library than to try implement PNG handling inside prawn?

Suggested workaround for issues with transparency in PNG files is to use an external tool to convert files into rgba/grayscale mode before using them with prawn.

For me, the best solution is flattening the files with white background and converting it to 8-bit-per-channel RGB with the following command:

convert #{file} -background white -flatten -define png:color-type=2 -define png:bit-depth=8 #{out_file}
@practicingruby
Copy link
Member

@mfly: Thanks for the detailed bug report!

We have a policy of no external runtime dependencies, so using a third-party gem dependency is not an option for us.

It seems like for now we should think about raising a NotImplementedError for palleted PNGs w. transparency, and then look towards fixing the problem.

@practicingruby
Copy link
Member

@mfly: I forgot to mention that while Prawn itself cannot use external dependencies, that our entire image system is replaceable. You might give https://github.com/packetmonkey/prawn-gmagick a try and see if it fixes your problem.

@mfly
Copy link
Author

mfly commented Oct 10, 2014

@sandal Thanks for instant reaction :)
Throwing exception is a good start 👍. I will definitely give prawn-gmagick a try! Maybe in a week or two I will try to implement the missing feature in prawn's code.

@practicingruby
Copy link
Member

@mfly: Thanks! It'd certainly be welcome.

@cheba you may also want to take a look at this ticket since you have rummaged around in the PNG code before.

@practicingruby practicingruby changed the title Palleted PNG handling is buggy Palleted PNG w. transparency unsupported Oct 10, 2014
@edborden
Copy link

edborden commented Mar 9, 2015

@mfly What does the convert method refer to in your workaround? It doesn't look like it's part of Prawn, or I can't find mention of it.

@practicingruby
Copy link
Member

@edborden: The convert utility is provided by ImageMagick, and is run on the command line. It's not part of Prawn.

@Siyfion
Copy link

Siyfion commented Oct 7, 2015

I know it's been a while since this was last discussed, but what is the currently recommended work-around for this? Does prawn-fast-png fix this issue? or prawn-gmagick? Is it ever going to be supported natively in Prawn?

@Fryie
Copy link

Fryie commented Oct 15, 2015

While I understand the "no external runtime dependency" stance, it makes little sense IMHO to provide a broken image handling implementation instead. Architecturally it would be more sound to either remove the default PNG image handling or to at least raise a warning when using it.

@practicingruby
Copy link
Member

@Fryie: I agree, and already mentioned this in the current thread.

It seems like for now we should think about raising a NotImplementedError for palleted PNGs w. transparency, and then look towards fixing the problem.

@practicingruby
Copy link
Member

@packetmonkey I marked this as a bug... because as @Fryie said... broken behavior without a warning is pretty much a defect. Consider fixing in a future release. 😄

@Siyfion
Copy link

Siyfion commented Oct 15, 2015

Just to chime in, I can confirm that adding the prawn-gmagick plugin fixes this issue for me.

@Fryie
Copy link

Fryie commented Oct 15, 2015

Maybe a section in the README explaining that the image engine can be replaced would be helpful too. :)

@packetmonkey
Copy link
Contributor

I ran this test script with prawn 2.0.2 and we are now throwing an exception for transparent palleted PNG files added in 8ebe282

 ~/Code/prawn-png $ ruby prawn_test.rb
/Users/evan/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/prawn-2.0.2/lib/prawn/images/png.rb:71:in `block in initialize': Pallete-based transparency in PNG is not currently supported. (Prawn::Errors::UnsupportedImageType)
See https://github.com/prawnpdf/prawn/issues/783
    from /Users/evan/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/prawn-2.0.2/lib/prawn/images/png.rb:45:in `loop'
    from /Users/evan/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/prawn-2.0.2/lib/prawn/images/png.rb:45:in `initialize'
    from /Users/evan/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/prawn-2.0.2/lib/prawn/images.rb:87:in `new'
    from /Users/evan/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/prawn-2.0.2/lib/prawn/images.rb:87:in `build_image_object'
    from /Users/evan/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/prawn-2.0.2/lib/prawn/images.rb:66:in `image'
    from prawn_test.rb:4:in `block (2 levels) in <main>'
    from /Users/evan/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/prawn-2.0.2/lib/prawn/document.rb:225:in `instance_eval'
    from /Users/evan/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/prawn-2.0.2/lib/prawn/document.rb:225:in `initialize'
    from /Users/evan/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/prawn-2.0.2/lib/prawn/document.rb:141:in `new'
    from /Users/evan/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/prawn-2.0.2/lib/prawn/document.rb:141:in `generate'
    from prawn_test.rb:3:in `block in <main>'
    from prawn_test.rb:2:in `each'
    from prawn_test.rb:2:in `<main>'
 ~/Code/prawn-png $

So we won't kick out known bad PDFs and I'm still open to a PR that will implement native palleted PNG transparency support.

Closing the issue.

@sublimecoder
Copy link

Looks like there is a fix for this. Can we get it merged in?

@pointlessone
Copy link
Member

@mfly @edborden @Siyfion @danielgrippi @sublimecoder @kriztynna Sorry for addressing so many people but I'm curious what is your use case?

I didn't even think that palette transparency in PNG is used so widely. I though it's just one of those rare edge cases that one or two users stumble upon but apparently many people use those palette PNGs all the time. So could you please share your use case and why you use palette transparency instead of, say, 8-bit alpha channel?

@mfly
Copy link
Author

mfly commented Dec 19, 2015

Our system uses prawn for PNG to PDF conversion. Images are provided by
users and we have little control over what color mode they use. Yet our
goal is to support as many formats as possible. Currently I use a simple
workaround using convert utility.
On Dec 19, 2015 10:12 AM, "Alexander Mankuta" notifications@github.com
wrote:

@mfly https://github.com/mfly @edborden https://github.com/edborden
@Siyfion https://github.com/Siyfion @danielgrippi
https://github.com/danielgrippi @sublimecoder
https://github.com/sublimecoder @kriztynna
https://github.com/kriztynna Sorry for addressing so many people but
I'm curious what is your use case?

I didn't even think that palette transparency in PNG is used so widely. I
though it's just one of those rare edge cases that one or two users stumble
upon but apparently many people use those palette PNGs all the time. So
could you please share your use case and why you use palette transparency
instead of, say, 8-bit alpha channel?


Reply to this email directly or view it on GitHub
#783 (comment).

@sublimecoder
Copy link

We use it in a similar fashion to @mfly. We create PDFs that contain user input and the pngs are not always under our control. The interesting thing is prawn 1.3.0 seems to be able to handle most of these pngs with out issue so we're just using 1.3 until the next release.

@pointlessone
Copy link
Member

@sublimecoder This is interesting. We used to have incomplete support for palette transparency. It only keeps color data but completely loses transparency. It won't complain but the output would be incorrect.

@sublimecoder
Copy link

@cheba hmm interesting so did it just flatten it or did it manipulate the image in another manner to strip the transparency?

@pointlessone
Copy link
Member

@sublimecoder Quick code inspection seem to show that only color would be kept and transparency data would simply be ignored.

In pseudo code it would look like the following transformation:

def pixel_color(r, g, b, a)
  [r, g, b, 1.0]
end

@kriztynna
Copy link
Member

Similar use case here, working with 3rd party PNGs that happen to use
palette transparency. @cheba's fix handles the issue perfectly, and was
already available by the time I ran into this issue, so I haven't had to
implement any workarounds (other than gem installing from the repo rather
than rubygems.org).

On Sat, Dec 19, 2015 at 4:12 AM Alexander Mankuta notifications@github.com
wrote:

@mfly https://github.com/mfly @edborden https://github.com/edborden
@Siyfion https://github.com/Siyfion @danielgrippi
https://github.com/danielgrippi @sublimecoder
https://github.com/sublimecoder @kriztynna
https://github.com/kriztynna Sorry for addressing so many people but
I'm curious what is your use case?

I didn't even think that palette transparency in PNG is used so widely. I
though it's just one of those rare edge cases that one or two users stumble
upon but apparently many people use those palette PNGs all the time. So
could you please share your use case and why you use palette transparency
instead of, say, 8-bit alpha channel?


Reply to this email directly or view it on GitHub
#783 (comment).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

9 participants