Generating dynamic QR codes in Rails using Rjb

When I started looking for gems which generate QR code in ruby I found “rqrcode” which generates only HTML code which was not useful to me. I wanted the QR code image so I looked at “qr4r” but here we can not customize the color, background color etc,  so I decided to write my own code to generate the QR codes where I can have customized data, color, background color (transparent) and last but not the least, it should be fast!!

After looking at various libraries I found this much interesting. See demo.

You can download the jar file from here. As it is a jar file we need a bridge between Ruby and JVM. Here the Rjb gem comes into picture. Follow the instructions and install the Rjb gem. Ensure you have openjdk installed before installing Rjb gem. Also make sure you add the code below on top of your Gemfile to avoid the errors at the time of deployment.

java_home = '/usr/lib/jvm/java-7-openjdk-amd64'
ENV['JAVA_HOME'] = java_home if Dir.exist?(java_home)

require 'rjb'
require 'RMagick'
require 'rvg/rvg'
require 'color'

module Zxing
 class Zxing
   include Magick

   def initialize

   def encode(content, output_path, color='#000000', size=300, background = '#FFFFFF')
     @content = content
     @output_path = output_path
     @color = color
     @size = size
     @background_color = background

   def encode!
     qrcoder = Rjb::import('').new
     barcode_format = Rjb::import("")
     format = barcode_format.valueOf("QR_CODE")
     hint_type = Rjb::import("")
     hints = Rjb::import("java.util.HashMap").new
     hints.put(hint_type.MARGIN, 0)
     result = qrcoder.encode(@content, format, @size, @size, hints)

   def generate_image(result)
     arr = []
     red, green, blue = set_image_color
     for i in 0...@size
       for j in 0...@size
         if result.get(j, i)
           arr.push(red, green, blue)
           arr.push(65535, 65535, 65535)
     image = Magick::Image.constitute(@size, @size, "RGB", arr.flatten)
     system("convert #{@output_path} -fill '#{@background_color}' -opaque white #{@output_path}")

   def set_image_color
     c = ::Color::RGB.from_html(@color)
     [( * 257).to_i, ( * 257).to_i, ( * 257).to_i]

Here hints are used to reduce the margins from the QR code image. If you want margins then you can remove the hints option.

result = qrcoder.encode(@content, format, @size, @size, hints)

Above code will return an array of qr code elements with ‘0’s & ‘1’s. ‘1’ stands for qr code position. The ‘generate_image’ method will loop through the result set and wherever it finds ‘1’ it will replace it with RGB colors.  Here we have used ‘color gem‘ which returns the RGB codes from the given Hex color.  Also you will notice that each RGB color code is multiplied with ‘257’ because we want 16-bit colors to generate the image. There is a method in jar library that will generate the QR code image but it is very slow. So to make the QR code generation faster we will write our own method ‘generate_image’ which generates the image using Rmagick

def generate_QR
  zxing =
   email_content("", "Testing", "QR code works"),

def email_content(email, subject, body)

In the above code, “email_content” method will have the QR code specific content. We can have similar methods to generate different types of QR codes like SMS, Vcards, Youtube links, Bookmarks, website url etc.

Refer for more qr code details.

The QR code image will be generated at the given output path, which you can use to display on HTML page.

This entry was posted in Ruby, Ruby on Rails and tagged , , , , , . Bookmark the permalink.

2 Responses to Generating dynamic QR codes in Rails using Rjb

  1. Martin says:

    rqrcode does render png and svg since 2012, but readme was only updated 2015.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s