prawnpdf/prawn

Add webp support?

xicubed opened this issue · 2 comments

Over on asciidoctor/asciidoctorj-pdf#70 (comment) it looks like they use prawnpdf so adding webp support was an issue.

Image support in Prawn is extendable, see Prawn::ImageHandler.

As mentioned in the linked issue, there is prawn-gmagick which can be used as an example on how to implement such support (in case that gem doesn't work with the latest Prawn versions anymore).

Since webp is not natively supported by the PDF file format, this has to be implemented as an extension to Prawn.

Here's a workaround which works for me. Instead of decoding the webp, it converts the webp to png on the fly and gives it to the built-in png handler.

require 'prawn'
require 'open3'

module Prawn
  module Images
    class Webp < Image
      def self.can_render?(image_blob)
        image_blob[8..11].unpack('C*') == 'WEBP'.bytes &&
          system('which dwebp')
      end

      def initialize(data)
        @png_handler = PNG.new to_png(data)
      end

      def method_missing(name, *args)
        png_handler.send name, *args
      end

      private

      attr_reader :png_handler

      def to_png(data)
        png_data, _ = Open3.capture2 "dwebp -quiet -o - -- -",
          stdin_data: data, binmode: true
        png_data
      end
    end
  end
end

Prawn.image_handler.register Prawn::Images::Webp