Create JPGs using plain old HTML+CSS. Uses wkhtmltoimage on the backend which renders HTML using Webkit.
Heavily based on PDFKit.
gem install imgkit - Use the
wkhtmltoimage-binarygem (mac + linux)
gem install wkhtmltoimage-binary - Install by hand: http://wkhtmltopdf.org/downloads.html
- Use installer:
sudo imgkit --install-wkhtmltoimageinstall latest version into /usr/local/bin (overwrite defaults with e.g. ARCHITECTURE=amd64 TO=/home/foo/bin)
# 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. 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' end You could put the binaries in your bin/ folder and load the correct one depending on the platform and CPU type:
# config/initializers/imgkit.rb IMGKit.configure do |config| if OS.linux? && OS.host_cpu == "x86_64" config.wkhtmltoimage = Rails.root.join("bin", "wkhtmltoimage-linux-amd64").to_s elsif OS.mac? && OS.host_cpu == "x86_64" config.wkhtmltoimage = Rails.root.join("bin", "wkhtmltoimage-macos-amd64").to_s else puts OS.report abort "You need to add a binary for wkhtmltoimage for your OS and CPU" end endTo get wkhtmltoimage-linux-amd64 you can get the latest .deb (if you are targeting ubuntu) from https://github.com/wkhtmltopdf/packaging/releases
docker run -it -v $(pwd):/data ubuntu:latest /bin/bash # or with fish # docker run -it -v (pwd):/data ubuntu:latest /bin/bash cd data dpkg -x wkhtmltox_0.12.6-1.focal_amd64.deb out exit cp out/usr/local/bin/wkhtmltoimage bin/wkhtmltoimage-linux-amd64 And for wkhtmltoimage-macos-amd64 you can download the .pkg from https://github.com/wkhtmltopdf/packaging/releases, install it, then:
mv /usr/local/bin/wkhtmltoimage bin/wkhtmltoimage-macos-amd64 May be set to one of IMGKit::KNOWN_FORMATS = [:jpg, :jpeg, :png]
config.default_format = :png May be changed from its default (imgkit-):
config.meta_tag_prefix = 'imgkit-option' 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'] When initializing an IMGKit options may be may be set for the life time of the IMGKit object:
IMGKit.new('http://example.com/form', :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"
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' end If you're not using Rails just replace Rails.root with the root dir of your app.
register a .jpg mime type in:
#config/initializers/mime_type.rb Mime::Type.register "image/jpeg", :jpg register a .png mime type in:
#config/initializers/mime_type.rb Mime::Type.register "image/png", :png You can respond in a controller with:
@kit = IMGKit.new(render_to_string) format.jpg do send_data(@kit.to_jpg, :type => "image/jpeg", :disposition => 'inline') end - or - format.png do send_data(@kit.to_png, :type => "image/png", :disposition => 'inline') end - or - 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.
To overcome the lack of support for --user-style-sheet option by wkhtmltoimage 0.10.0 rc2 as reported here http://code.google.com/p/wkhtmltopdf/issues/detail?id=387
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 Model:
class Model < ActiveRecord::Base # attr_accessible :title, :body has_attached_file :snapshot, :storage => :s3, :s3_credentials => "#{Rails.root}/config/s3.yml" endController:
def upload_image model = Model.find(params[:id]) html = render_to_string kit = IMGKit.new(html) img = kit.to_img(:png) file = Tempfile.new(["template_#{model.id}", 'png'], 'tmp', :encoding => 'ascii-8bit') file.write(img) file.flush model.snapshot = file model.save file.unlink endContributed by @ticktricktrack
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- 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.