Is it possible to add DataUrl Image in RBPDF?

268 views Asked by At

I am making pdf file from DataUrl Image in ruby on rails.

I have selected RBPDF to produce pdf file in server side.

But in this code I have following error

 @pdf.Image(object["src"] , object["left"], object["top"], object["width"], object["height"])

Here object["src"] is DataUrl Image.

RuntimeError (RBPDF error: Missing image file: data:image/jpeg;base64,/9j/4REORXhp...

Is it impossible to add RBPDF image from DataUrl image?

Adding files dynamically is not effective I think.

1

There are 1 answers

3
aristotll On BEST ANSWER

You may monkey patch the origin method.

I use the data_uri gem to parse the image data.

require 'data_uri'
require 'rmagick'
module Rbpdf
  alias_method :old_getimagesize, :getimagesize
# @param [String]  date_url
  def getimagesize(date_url)
    if date_url.start_with? 'data:'
      uri = URI::Data.new date_url
      image_from_blob = Magick::Image.from_blob(uri.data)
      origin_process_image(image_from_blob[0])
    else
      old_getimagesize date_url
    end
  end

# this method is extracted without comments from the origin implementation of getimagesize 
  def origin_process_image(image)
    out = Hash.new
    out[0] = image.columns
    out[1] = image.rows

    case image.mime_type
      when "image/gif"
        out[2] = "GIF"
      when "image/jpeg"
        out[2] = "JPEG"
      when "image/png"
        out[2] = "PNG"
      when "    image/vnd.wap.wbmp"
        out[2] = "WBMP"
      when "image/x-xpixmap"
        out[2] = "XPM"
    end
    out[3] = "height=\"#{image.rows}\" width=\"#{image.columns}\""
    out['mime'] = image.mime_type

    case image.colorspace.to_s.downcase
      when 'cmykcolorspace'
        out['channels'] = 4
      when 'rgbcolorspace', 'srgbcolorspace' # Mac OS X : sRGBColorspace
        if image.image_type.to_s == 'GrayscaleType' and image.class_type.to_s == 'PseudoClass'
          out['channels'] = 0
        else
          out['channels'] = 3
        end
      when 'graycolorspace'
        out['channels'] = 0
    end

    out['bits'] = image.channel_depth

    out
  end
end