Hi!
I want to include a background image to all pages of a certain pdf.
This image is stored on an external source.
Therefore I use
This actually works if the pdf is not longer than a single page. As soon as i have multiple pages in this pdf i get the following error message and the pdf doesn't render:
image file is an unrecognised format
It works perfectly if I don't use open(image-url). But the image needs to be remote, so having the image somewhere in the "public" directory of my Rails App is not an option.
Here is my code
invoices_controller.rb
def show @invoice = Invoice.find(:id) respond_to do |format| format.html format.pdf do pdf = InvoicePdf.new(@invoice, view_context) send_data pdf.render, filename: "Invoice_#{@invoice.number}.pdf", type: "application/pdf" end end end
invoice_pdf.rb
class InvoicePdf < Prawn::Document def initialize(invoice, view) super(margin: [100, 30, 100, 30], page_size: "A4", background: open("#{invoice.background_url}")) #Content of PDF end
Edit: My prawn-gem version is "1.0.0.rc1". But it is also not working with any of the older ones.
I suspect that the problem is actually with the external image. The
code for :background is really simple -- it just grabs a canvas and
draws the image on the paper at every start_new_page.
If you use image() instead of the :background argument, does that make
things work?
Can you provide an example of one of the images you are trying to work
with? As long as you're using the API correctly, I don't see a reason
why it would make a difference whether you load the file from a
filesystem or across the network.
-be
As you've seen, Prawn doesn't support GIF images, only PNG and JPG. If
it's not too much trouble, you can shell out to ImageMagick (convert)
to convert to PNG before embedding.
-be
Jürgen,
Thank you for identifying the problem. This has been fixed on Prawn's
master branch with this commit:
https://github.com/prawnpdf/prawn/commit/d06f81b2f0e36f10f7b9f8f89824cbeca0648292
The issue was that Prawn would not rewind a passed-in IO object (such
as the one returned by open-uri) on subsequent calls to image(), so it
would try to start reading image data from the EOF and wouldn't be
able to find a PNG or JPG header.
Cheers,
Brad
Jack.
--
mathuin at gmail dot com
I'd want to see a benchmark proving that memoizing the image data
ourselves is a win over letting the OS / runtime manage the stream --
even after taking into account the increased memory overhead
memoization would cost.
It would seem to me that calling #rewind on the IO provided by
open-uri and re-reading the data is probably going to be about as fast
as trying to memoize the data ourselves. But if I'm wrong, I'd love to know.
Thanks,
-be