3

First of all, everything works just fine in my dev environment and worked fine in production until I updated my Rails app to Rails 5.2.2 and Ruby to 2.5.3 (both were only a couple of minor versions off). I updated a number of other gems but neither the wicked pdf or wkhtmltopdf-binary were updated. I'm unsure about their dependencies. On production (using Heroku) wicked_pdf is not rendering images from outside of my domain.

Here are the gems I am using:

gem 'wicked_pdf' #version 1.1.0
gem 'wkhtmltopdf-binary' #version 0.12.4

The following code works in development but not in production:

<%= image_tag @invoice.job.customer.account.logo.url, width: 220 %>
<%= image_tag @invoice.job.customer.account.logo_url, width: 220 %>
<%= wicked_pdf_image_tag @invoice.job.customer.account.logo_url, width: 220 %>
<img  src="<%= @invoice.job.customer.account.logo_url %>" width="220">

Displaying a local image works on production:

 <%= image_tag "logo.png" width: 220 %>

I assume this has something to do with Heroku because I've read about problems with wkhtmltopdf-binary and Heroku but have had no luck from the attempts I've made.

Cannon Moyer
  • 3,014
  • 3
  • 31
  • 75

1 Answers1

1

So I had to use a different function and made a helper out of it. The embed_remote_image method is probably the most interesting to you and how I used it in my larger helper (which determines if it's the front or back image of an item, and if missing shows the custom missing image).

  # PDF image include - dont' need link logic, needed for https images
  # per https://github.com/mileszs/wicked_pdf/issues/36#issuecomment-91027880
  require 'open-uri'
  def embed_remote_image(url, content_type)
    asset = open(url, "r:UTF-8") { |f| f.read }
    base64 = Base64.encode64(asset.to_s).gsub(/\s+/, "")
    "data:#{content_type};base64,#{Rack::Utils.escape(base64)}"
  end

  def issue_image_pdf_display(issue, graphic, size, sizeinpx, issuer = nil, nolink = false, chapter_issue = false)
    if !graphic.blank?
      if graphic == issue.imageback
        image_tag(embed_remote_image(issue.imageback_url(size), 'image/png'))
      else
        image_tag(embed_remote_image(issue.image_url(size), 'image/png'))
      end
    else
      missing_image_display(issue, size, sizeinpx)
    end
  end

You also need the buildpack. https://github.com/dscout/wkhtmltopdf-buildpack.git

John Athayde
  • 580
  • 2
  • 13
  • 1
    Well done! This is really interesting and similar to the solution we came up with. Yours might be more robust, though. We have a PR with wicked_pdf to add a helper for encoding base64 image data from image URLs. Check it out here and feel free to comment and contribute: https://github.com/mileszs/wicked_pdf/pull/947 – Joshua Pinter Oct 22 '20 at 15:01
  • @JoshuaPinter that's much cleaner. I came back to this as I started getting "SSL_CTX_load_verify_file: system lib" errors with both my original code and swapping in your method for embed_remote_image. Are you seeing similar issues with Ruby 3.2? – John Athayde Apr 11 '23 at 23:51
  • 1
    I don't think we've run into that, but it could be dependent on a lot of factors. – Joshua Pinter Apr 12 '23 at 18:31