Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generating a PDF With Images from Base64 with Prawn

I am trying to save multiple pngs in one pdf. I'm receiving the PNGs from an API Call to the Endicia Label Server, which is giving me a Base64 Encoded Image as response.

Based on this Question:

How to convert base64 string to PNG using Prawn without saving on server in Rails

def batch_order_labels
  @orders = Spree::Order.ready_to_ship.limit(1)
  dt = Date.current.strftime("%d %b %Y ")
  title = "Labels - #{dt} - #{@orders.count} Orders"

  Prawn::Document.generate("#{title}.pdf") do |pdf|
    @orders.each do |order|
      label = order.generate_label
      if order.international?
        @image = label.response_body.scan(/<Image PartNumber=\"1\">([^<>]*)<\/Image>/imu).flatten.last
      else
        @image = label.image
      end

      file = Tempfile.new('labelimg', :encoding => 'utf-8')
      file.write Base64.decode64(@image)
      file.close


      pdf.image file
      pdf.start_new_page
    end
  end

  send_data("#{title}.pdf")
end

But I'm receiving following error:

"\x89" from ASCII-8BIT to UTF-8

Any Idea?

like image 923
Martin Lang Avatar asked Feb 26 '13 03:02

Martin Lang


People also ask

How do I get files from Base64?

How to convert Base64 to file. Paste your string in the “Base64” field. Press the “Decode Base64 to File” button. Click on the filename link to download the file.

What is Base64 image encoder?

Base64 encoding is a way to encode binary data in ASCII text. It's primarily used to store or transfer images, audio files, and other media online. It is also often used when there are limitations on the characters that can be used in a filename for various reasons.


2 Answers

There's no need to write the image data to a tempfile, Prawn::Document#image can accept a StringIO.

Try replacing this:

file = Tempfile.new('labelimg', :encoding => 'utf-8')
file.write Base64.decode64(@image)
file.close
pdf.image file

With this:

require 'stringio'
.....
image_data = StringIO.new( Base64.decode64(@image) )
pdf.image(image_data)
like image 198
James Healy Avatar answered Oct 03 '22 17:10

James Healy


The Problem is, that the Api is returning this thing in UTF-8 - So I dont have a great choice. Anyhow, I found this solution to be working

  file = Tempfile.new('labelimg', :encoding => 'utf-8')
  File.open(file, 'wb') do |f|
    f.write Base64.decode64(@image)
  end
like image 44
Martin Lang Avatar answered Oct 03 '22 17:10

Martin Lang