wicked_pdf too much images = broken PDF - ruby-on-rails

wicked_pdf (or wkhtmltopdf) behaves strange in production mode. It took a bit time to track down the problem, but seemingly the reason that my PDF is broken are too much images or too large file sizes.
When i try to use a 300dpi pic (4 MB), it´s broken. When i decrease to 72 dpi, it works… sometimes. When i use just a thumbnail, it works always.
I made a test: One coversheet with a small test image works. Two coversheets also, … up to 30 sheets it works. When i attach cover sheet 31, my pdf is broken, always.
In development everything is fine, 300dpi images, 5 MB, 50 MB, no problem.
Does anybody know about this problem? And how to fix it? :-)
PS: when i do wkhtmltopdf via command line it shows no images at all, so it´s hard to test if wkhtmltopdf or wicked_pdf is the issue. I really don´t like generating PDFs!

wkthmltopdf does a best-effort to gather up and render all the resources in a pdf just like the webkit browser that powers it. If it isn't able to retrieve and render them all in time, it can sometimes output an unfinished pdf.
There are a few things we can check or do to optimize this process.
Make sure all your assets (images, javascript, css) are correctly rendered with a full path like 'http://images/foo.jpg', not a relative one like '/foo.jpg'.
This causes wkhtmltopdf to reach out over the web to get these assets, and sometimes that isn't quick enough, so if you can, try to use filesystem resource links like 'file:///projects/foo/images/foo.jpg'. The wicked_pdf_image and other related helpers attempt to do this for you, but depending on what version of Rails you are on, the result may be a little different.
Wkhtmltopdf uses a lot of memory and cpu (especially with big images), make sure your production server isn't starved for it.
The git master version of wicked_pdf has an optimization to use tempfiles instead of I/O streaming. Point your Gemfile at that git://github.com/mileszs/wicked_pdf.git and see if that improves things for you. A new version of the gem will likely be published in the next few days (I do a lot of the maintenance and release management for wicked_pdf).
Please report back. I'm interested to know if any or all of the above improve the situation.

Related

Extremely slow Rails webpacker compile times with hundreds of thousands of assets

I'm working on a project that includes pictures for a google maps overlay and consequently contains around 750k image assets. This project uses rails 6 and webpacker, and after copying in all the files to the correct directory the webpage load times increase to the point of hours. The assets are located in /app/assets/images/.
So far I've tried using rails assets:precompile, which after a night of compiling didn't finish.
An odd thing is this only happens after a server restart. If I copy in the files while the server is running then everything behaves and performs fine.
What can I do to fix this? Am I fundamentally misunderstanding where the images should go and how webpacker should fit in?
Thanks
Ultimately wound up not including the files in development. In production we use apache, and that serves the large number of files without any problem.

Creating PDF from photos on a Facebook Rails app

I'm creating a Facebook app using Rails and hosted on Heroku and I'm having a bit of trouble finding the ideal way to solve a problem. I want the user to be able to move their photos around on the screen, position them, and then download that as either a PDF or a PNG file to be emailed or printed. I have the app getting the user's facebook photos and they can drag them on to a HTML5 Canvas element to position them. Taking this canvas, however, and converting it into something printable is where I'm hitting a dead end.
Basically I have a few ideas I have tried:
Convert the Canvas to a PNG using toDataURL() - Would work perfectly but since the photos are external, the canvas is "dirty" and will throw up a security issue. I've thought about trying to copy the pixels of each image to a pixel array but I've heard this may not work either due to security issues. Since the app is dealing with people's facebook images I really don't want to store them on the app's server.
Use PDFKit/wkhtmltopdf to create a PDF using Rails - I've tried this, but since the app is a Sinatra app (I think), it's confusing me a lot. It's throwing errors with the to_pdf call saying 'Command Failed'. I've tried adding a config.middleware.use line but I'm not 100% sure where to put it and everywhere seems to be failing saying "config" is an undefined variable. Also installing wkhtmltopdf seems to fail on Heroku once I test it outside localhost.
Use Prawn to create a PDF using Rails - I've tried prawn but it seems to have a similar problem to PDFKit and I get confused about what goes where on a Sinatra app. I'm sure I read as well that people were having problems with it too.
Have I missed any obvious solutions to this, or is there something I'm not thinking of? All I want to do is create some kind of easily printable file with positioning intact that can be easily downloaded and printed by the user but I've come across so many problems that I don't know where to go next and I'm going round in circles.
If anyone had any advice for me about how I could get around this problem I'd really appreciate it.
if prawn is giving you grief just use one of the jquery plugins to print your div content. You could even configure a pdf printer and print the document instead of hard copy if you so wish/need images in pdf format.
I use http://archive.plugins.jquery.com/project/jqPrint plugin in one of my projects and it works like a charm.
It sounds like many of your issues relate to the necessary PDF binaries not being accessible on Heroku. In following with the twelve factor approach to dependency isolation Heroku purposely provides a very bare system.
If you need to run a custom binary on Heroku I'd suggest looking at a tool called Vulcan which can compile a binary that's compatible with the Heroku runtime.

Asset managing with Rails 3 (on Heroku) (Jammit, AssetHat, Rack PageSpeed)

I am interested in the pros and cons of the different tools for managing assets in Rails 3.0.x (especially on Heroku).
There are already some older questions regarding this topic, but in the meanwhile there are some new tools available.
I am especially interested in these tools:
Jammit
AssetHat
Rack PageSpeed
Jammit seems to can do everything that AssetHat can do and is also longer available. So where does AssetHat fit in?
Rack PageSpeed seems to do everything on the fly by directly working on the server response. Did you experience any performance issues by doing that? Would you recommend it over the other two solutions?
Hey there, I'm the author of AssetHat. Minification and concatenation are among the easiest performance boosts to implement; these features are common to Jammit, AssetHat, and rack-pagespeed. Rails has supported concatenation for a long time now (though it's done at runtime, rather than during deployment), and it's no surprise that Rails 3.1 supports both minification and concatenation during deployment.
The remaining features are what make each of these asset managers interesting. For example, Jammit is useful if you want to embed images and font files directly into your stylesheets. rack-pagespeed is also handy if you want to keep all your optimizations in a completely separate layer.
Inlining assets into CSS is great for static pages where stylesheets change infrequently. However, if your site is under active development, and the stylesheet changes even a tiny bit, the user's browser has to re-download the whole thing—including inline images and fonts that probably didn't change. It depends on the nature of your project.
If your assets are too big to inline or concatenate, AssetHat helps optimize for CDNs and parallel loading:
It takes great advantage of CDNs, whether it's Google's CDN, cdnjs (which uses Amazon's servers), or another CDN of your choosing. For example, just add <%= include_js :jquery %> to your layout (and a version number in a config file) to load jQuery from Google's CDN. If you're in dev mode and have a local copy of jQuery, that loads instead—easy offline dev.
AssetHat can rewrite stylesheets' image URLs to use your CDN instead. This reads from your config.action_controller.asset_host setting, and is done at deploy time. Your original CSS is left untouched.
If you have several JS files to load, it's sometimes faster to load them in parallel than to concatenate them (i.e., force them to load serially). You can switch on LABjs mode easily: <%= include_js 'big-file-1', ..., 'big-file-n', :loader => :lab_js %>. If you don't have a copy of LABjs locally, or if you're in production, LABjs loads from Amazon's servers via cdnjs.
By using CDNs like Google's or Amazon's, your users can load more assets in parallel (because there are more hostnames), enjoy greater speed, and sometimes, not even need to download assets at all (e.g., if they already loaded Google's copy of jQuery via someone else's website).
I've used AssetHat on Heroku by setting my deploy script to simply run rake asset_hat:minify (to minify and concatenate CSS/JS), commit those changes to my repository, then do the actual deployment.
In case you haven't seen these already, you might be interested in:
a longer walkthrough of AssetHat's features
the official website
the technical readme
the extensive docs
If you need help setting it up, or have any other questions, feel free to message me on GitHub (rondevera) or Twitter (#ronalddevera).
Jammit won't work out of the box on Heroku as far as I know. One option seems to be to use the Heroku Jammit plugin to manage your assets - https://github.com/chebyte/heroku-jammit.
Alternatively, Jammit can be configured to output to /tmp: http://geekninja.blogspot.com/2011/04/making-jammit-jam-with-heroku.html
Rails 3.1 will include Sprockets to handle asset packaging, I think that's worth considering.
I am currently using jammit on heroku, together with amazon s3, and it works like a charm :)
I can't say much about the others tools because I have not used them.
Which one did you pick, in the end?
Fernando.

CSS Sprite generator for Ruby on Rails project

I'm currently working on a large, highly trafficked Ruby on Rails website and in order to get our page load times down, we are looking at spriting our background images. There seem to be a lot of tools out there but many are in the early stages of dev and many don't support some of the features we need.
Features which are important to us:
x or y repeating
automation with our rake build
transparency
generates sprite image and css automatically
mature
easy to maintain
open source
If it was written in Ruby, that would be a bonus but is not essential as long as it can integrate with a rake/cap setup.
Are there any css sprite tools out there which fit most(all?) of these criteria?
Rather than spriting images, why not use data-uri? Jammit can generate CSS files with small images compiled in as data-uri objects. This is actually even more performant than sprite sheets, because it means that you only have one HTTP connection for the stylesheet, rather than one for the stylesheet and one for the sprite sheet.
To use it, you just have your small images (icons, repeating backgrounds, etc) referenced with /embed/ in the path somewhere, and it'll generate data-uri, MHTML, and plain versions of your stylesheets for serving to various browsers.
Jammit also does compilation of multiple stylesheets (and Javascripts) into one file (per type), and can make use of some Javascript templating stuff too, if you want to get super-optimized with your AJAX responses.
Downsides are that a) if you reference an image more than once, it gets compiled in for each reference, and b) changing an image results in clients needing to re-download your whole stylesheet. However, since those assets generally change fairly rarely, it can be a solution that results in far faster page loads without adding any additional overhead to your development process.
To mitigate both of those, you could have a separate stylesheet that is just for image references, so you'd have one stylesheet for normal layouts, and then another that all your data-uri resources get compiled into. This would result in two HTTP requests, but it means that you could change your CSS or your embedded images without forcing a re-download of the whole other half of your styling.
One big negative about Chris's suggestion to use data-uri via Jammit, is that it doesn't support IE6/7.
There's this new gem called active_assets that gives you full sprite integration with your rails stack. Check it out at github. The gem let's you define your sprites including the list of images to include in the sprite and then generates the sprite and the corresponding stylesheet. The readme at the above link has all the info.

Ruby/Rails image processing libraries

Good friends of stackoverflow, I am here today for guidance regarding image processing/manipulation using Ruby in a Rails environment. I'm creating on-the-fly dynamic banner ads that will feature mostly (if not completely) text. It's fairly simple with just a line or two, but I'd like the option to adjust font, text color, text size, etc.
What libraries do you recommend for this sort of task?
I've read up in rMagick a little bit and I see a lot of complaints about memory issues and lack of text rendering features. I'm not seeing many alternative active projects.
Thanks!
Edit: I got a chance to mess around with RMagick and while it's library is full featured, it seriously lacks in the text department. One feature I'm unable to use is non-breaking spaces. I'm printing a phone number in my text and it really doesn't make sense to have the area code on a different line than the rest of the number.
I'm choosing RMagick as the best solution for now, because it's full-featured and actively developed, but it is by no means a good solution.
I wrote something like the following:
require 'rubygems'
require 'RMagick'
include Magick
image = Image.new(50, 50) {
self.background_color = "white"
}
text = Draw.new
text.annotate(image, 0,0,0,40, 'Named Colors') {
self.fill = 'black'
self.pointsize = 32
}
image.write("image.png")
Which should be easy enough to follow. Also have a look at the documentation. Whilst it's not quite laid out to perfection, it's pretty much all there.
Recently I have been experimenting with creating charts/graphs from data sets using Ruby. When I was unable to find any libraries or gems that really did what I wanted, I started tinkering around with SVG graphics and I found that they are actually fairly simple to create. The SVG format is simply plain-text XML. I built an SVG image in Inkscape, saved it to a plain SVG file, and my Ruby script uses that file as a template (I dynamically update a few line elements and several text labels and leave the structure of the file intact). SVG gives you all sorts of font options (like CSS or HTML).
These two tutorials give you a quick look at SVG and how you can build an image fairly quickly with any app or language that can write to a text file. Ruby can use plain old puts to build a SVG file, or you can let the 'builder' gem do the formatting for you.
You can farm out your image processing needs to the command-line version of ImageMagick instead of using the the rMagick Ruby bindings.
Are you limited to MRI Ruby? If there's any way you can get access to a jRuby instance (maybe on an EC2 stack for instance) you could make use of the wonderful Processing library. A project I worked on before did something similar with Processing via jRuby, it's really quite a potent combination.
You can use mini-magick to work with ImageMagick in Ruby.
The ImageScience library is made for people who hate rMagick's poor memory usage, etc. I use it as a backend processor for the attachment_fu plugin, which makes it easy to make an image model in Rails.
It may be worth having a look at the image_processing gem:
https://github.com/janko/image_processing
It makes use of either ImageMagick or VIPS (the latter being even more efficient).

Resources