Create JPGs using plain old HTML+CSS. Uses wkhtmltoimage on the backend which renders HTML using Webkit.

Heavily based on PDFKit.



gem install imgkit


  1. Use installer: sudo imgkit --install-wkhtmltoimage install latest version into /usr/local/bin (overwrite defaults with e.g. ARCHITECTURE=amd64 TO=/home/foo/bin)
  2. Install by hand:
  3. Try using the wkhtmltoimage-binary gem (mac + linux) gem install wkhtmltoimage-binary


# takes the HTML and any options for wkhtmltoimage
# run `wkhtmltoimage --extended-help` for a full list of options
kit =, :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')

# 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 ='')
kit ='/path/to/html'))

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

# Format shortcuts - New in 1.3!"hello").to_jpg"hello").to_jpeg"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.


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:

# config/initializers/imgkit.rb
IMGKit.configure do |config|
  config.wkhtmltoimage = '/path/to/wkhtmltoimage'

Default image format

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

  config.default_format = :png

Prefix for <meta> tag options (see Usage) :

May be changed from its default (imgkit-):

  config.meta_tag_prefix = 'imgkit-option'

Additional default options

Any flag accepted by wkhtmltoimage may be set thus:

  config.default_options = {
    :quality => 60

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

    'no-images' => true

For flags with multiple parameters, use an array:

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

Overriding options

When initializing an IMGKit options may be may be set for the life time of the IMGKit object:'', :post => ['my_field', 'my_unique_value'])


get a version of wkhtmltoimage as an amd64 binary and commit it to your git repo. I like to put mine in "./bin/wkhtmltoimage-amd64"

version 0.10.0 has worked best for me

assuming its in that location you can just do:

IMGKit.configure do |config|
  config.wkhtmltoimage = Rails.root.join('bin', 'wkhtmltoimage-amd64').to_s if ENV['RACK_ENV'] == 'production'

If you're not using Rails just replace Rails.root with the root dir of your app.


Mime Types

register a .jpg mime type in:

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

register a .png mime type in:

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

Controller Actions

You can respond in a controller with:

@kit =

format.jpg do
  send_data(@kit.to_jpg, :type => "image/jpeg", :disposition => 'inline')

- or -

format.png do
  send_data(@kit.to_png, :type => "image/png", :disposition => 'inline')

- or -

respond_to do |format|
            :type => "image/png", :disposition => 'inline')

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 here

  require 'imgkit'
  require 'restclient'
  require 'stringio'

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

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

Paperclip Example


class Model < ActiveRecord::Base
  # attr_accessible :title, :body
   has_attached_file :snapshot, :storage => :s3,
        :s3_credentials => "#{Rails.root}/config/s3.yml"


def upload_image
   model = Model.find(params[:id])
   html  = render_to_string
   kit   =
   img   = kit.to_img(:png)
   file  =["template_#{}", 'png'], 'tmp',
                         :encoding => 'ascii-8bit')
   model.snapshot = file

CarrierWave Workaround

Contributed by @ticktricktrack

  class MyClass < ActiveRecord::Base
    mount_uploader :snapshot, SnapshotUploader

    after_create :take_snapshot

    # private

    def take_snapshot
      file =["template_#{}", 'jpg'], 'tmp', :encoding => 'ascii-8bit')
      file.write(, quality: 50, width: 600).to_jpg)
      self.snapshot = file

Note on Patches/Pull Requests

  • Fork the project.
  • Setup your development environment with: gem install bundler; bundle install
  • Make your feature addition or bug fix.
  • Add tests for it. This is important so I don't break it in a future version unintentionally.
  • Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
  • Send me a pull request. Bonus points for topic branches.


Travis.yml is configured for multiple rubies, so I would just test a 2.1.x version and let travis handle the rest.


Copyright (c) 2010 Chris Continanza Based on work by Jared Pace See LICENSE for details.