[Awesome Ruby Gem] Use imgkit gem to generate images on the backend which renders HTML using Webkit

IMGKit

Create JPGs using plain old HTML+CSS. Uses wkhtmltoimage - http://github.com/antialize/wkhtmltopdf on the backend which renders HTML using Webkit.

Heavily based on PDFKit - https://github.com/jdpace/pdfkit/.

Installation

imkit

You can install it as a gem:

1
$ gem install imgkit

or add it into a Gemfile (Bundler):

1
2
3
4
5
# Gemfile

# csquared/IMGKit: Uses wkhtmltoimage to create JPGs and PNGs from HTML
# https://github.com/csquared/IMGKit
gem 'imgkit', '1.6.2'

Then, run bundle install.

1
$ bundle install

wkhtmltoimage

You can install it as a gem:

1
$ gem install wkhtmltoimage-binary

or add it into a Gemfile (Bundler):

1
2
3
4
5
# Gemfile

# nicholasklick/wkhtmltoimage-binary: Ruby gem containing easily installable access to wkhtmltoimage application
# https://github.com/nicholasklick/wkhtmltoimage-binary
gem 'wkhtmltoimage-binary', '0.12.5'

Then, run bundle install.

1
$ bundle install

Install by hand: wkhtmltopdf - http://wkhtmltopdf.org/downloads.html

Use installer:

1
2
sudo imgkit --install-wkhtmltoimage install latest version into /usr/local/bin
# (overwrite defaults with e.g. ARCHITECTURE=amd64 TO=/home/foo/bin)

Usages

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# IMGKit.new takes the HTML and any options for wkhtmltoimage
# run `wkhtmltoimage --extended-help` for a full list of options
kit = IMGKit.new(html, :quality => 50)
kit.stylesheets << '/path/to/css/file'
kit.javascripts << '/path/to/js/file'

# Get the image BLOB
img = kit.to_img

# New in 1.3!
img = kit.to_img(:jpg) #default
img = kit.to_img(:jpeg)
img = kit.to_img(:png)

# Save the image to a file
file = kit.to_file('/path/to/save/file.jpg')
file = kit.to_file('/path/to/save/file.png')

# IMGKit.new can optionally accept a URL or a File.
# Stylesheets nor Javascripts can not be added when source is provided as a URL of File.
kit = IMGKit.new('http://google.com')
kit = IMGKit.new(File.new('/path/to/html'))

# Add any kind of option through meta tags
IMGKit.new('<html><head><meta name="imgkit-quality" content="75"...

# Format shortcuts - New in 1.3!
IMGKit.new("hello").to_jpg
IMGKit.new("hello").to_jpeg
IMGKit.new("hello").to_png

Note: Ruby’s buffered I/O means that if you want to write the string data to a file or tempfile make sure to call #flush to ensure the contents don’t get stuck in the buffer.


Configuration

wkhtmltoimage binary location

If you’re on Windows or you installed wkhtmltoimage by hand to a location other than /usr/local/bin you will need to tell IMGKit where the binary is. You can configure IMGKit like so:

1
2
3
4
5
# config/initializers/imgkit.rb

IMGKit.configure do |config|
config.wkhtmltoimage = '/path/to/wkhtmltoimage'
end

Default image format

May be set to one of IMGKit::KNOWN_FORMATS = [:jpg, :jpeg, :png]

1
config.default_format = :png

Prefix for tag options (see Usage) :

May be changed from its default (imgkit-):

1
config.meta_tag_prefix = 'imgkit-option'

Additional default options

Any flag accepted by wkhtmltoimage may be set thus:

1
2
3
config.default_options = {
:quality => 60
}

For a flag which takes no parameters, use true for the value:

1
'no-images' => true

For flags with multiple parameters, use an array:

1
:cookie => ['my_session', '123BADBEEF456']

Overriding options

When initializing an IMGKit options may be may be set for the life time of the IMGKit object:

1
IMGKit.new('http://example.com/form', :post => ['my_field', 'my_unique_value'])

Rails

Mime Types

register a .jpg mime type in:

1
2
3
#config/initializers/mime_type.rb

Mime::Type.register "image/jpeg", :jpg

register a .png mime type in:

1
2
3
#config/initializers/mime_type.rb

Mime::Type.register "image/png", :png

Controller Actions

You can respond in a controller with:

1
2
3
4
5
@kit = IMGKit.new(render_to_string)

format.jpg do
send_data(@kit.to_jpg, :type => "image/jpeg", :disposition => 'inline')
end
  • or -
1
2
3
format.png do
send_data(@kit.to_png, :type => "image/png", :disposition => 'inline')
end
  • or -
1
2
3
4
respond_to do |format|
send_data(@kit.to_img(format.to_sym),
:type => "image/#{format}", :disposition => 'inline')
end

This allows you to take advantage of rails page caching so you only generate the image when you need to.

–user-style-sheet workaround

To overcome the lack of support for --user-style-sheet option by wkhtmltoimage 0.10.0 rc2 as reported

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
require 'imgkit'
require 'restclient'
require 'stringio'

url = 'http://domain/path/to/stylesheet.css'
css = StringIO.new( RestClient.get(url) )

kit = IMGKit.new(<<EOD)
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>coolest converter</title>
</head>
<body>
<div class="cool">image kit</div>
</body>
</html>
EOD

kit.stylesheets << css

CarrierWave Workaround

Contributed by @ticktricktrack

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class MyClass < ActiveRecord::Base
mount_uploader :snapshot, SnapshotUploader

after_create :take_snapshot

# private

def take_snapshot
file = Tempfile.new(["template_#{self.id.to_s}", '.jpg'], 'tmp', :encoding => 'ascii-8bit')
file.write(IMGKit.new(self.html_body, quality: 50, width: 600).to_jpg)
file.flush
self.snapshot = file
self.save
file.unlink
end
end

References

[1] csquared/IMGKit: Uses wkhtmltoimage to create JPGs and PNGs from HTML - https://github.com/csquared/IMGKit

[2] imgkit | RubyGems.org | your community gem host - https://rubygems.org/gems/imgkit/

[3] wkhtmltopdf/wkhtmltopdf: Convert HTML to PDF using Webkit (QtWebKit) - http://github.com/antialize/wkhtmltopdf

[4] jdpace/PDFKit: PDFKit has moved to https://github.com/pdfkit/PDFKit - https://github.com/jdpace/pdfkit/

[5] nicholasklick/wkhtmltoimage-binary: Ruby gem containing easily installable access to wkhtmltoimage application - https://github.com/nicholasklick/wkhtmltoimage-binary

[6] wkhtmltoimage-binary | RubyGems.org | your community gem host - https://rubygems.org/gems/wkhtmltoimage-binary

[7] wkhtmltopdf - https://wkhtmltopdf.org/