使用Base64中的图像生成带有图像的PDF

时间:2013-02-26 03:57:03

标签: ruby-on-rails png base64 prawn

我想在一个pdf中保存多个png。我从API调用收到的PNG到Endicia Label Server,它给我一个Base64编码图像作为响应。

基于这个问题:

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

但我收到以下错误:

从ASCII-8BIT到UTF-8 的

“\ x89”

任何想法?

3 个答案:

答案 0 :(得分:6)

无需将图像数据写入临时文件,Prawn :: Document#图像可以接受StringIO。

尝试替换它:

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

有了这个:

require 'stringio'
.....
image_data = StringIO.new( Base64.decode64(@image) )
pdf.image(image_data)

答案 1 :(得分:1)

问题是,Api以UTF-8返回这个东西 - 所以我没有一个很好的选择。 无论如何,我发现这个解决方案正常工作

  file = Tempfile.new('labelimg', :encoding => 'utf-8')
  File.open(file, 'wb') do |f|
    f.write Base64.decode64(@image)
  end

答案 2 :(得分:0)

您无法将Base64转换为UTF-8。 将其保留为纯ASCII:

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

甚至更好 - 将其保留为二进制文件:

  file = Tempfile.new('labelimg')
  file.write Base64.decode64(@image)
  file.close

UTF-8是多字节格式,不能用于传输图片等二进制数据。