The Process Of Generating Dynamic QR Codes In Rails With 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.

http://mvnrepository.com/artifact/com.google.zxing/core. 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)
#zxing.rb

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

module Zxing
class Zxing
include Magick

def initialize
Rjb::load('.')
Rjb::add_jar(Rails.root.join('lib/core.jar').to_s)
end

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

def encode!
qrcoder = Rjb::import('com.google.zxing.MultiFormatWriter').new
barcode_format = Rjb::import("com.google.zxing.BarcodeFormat")
format = barcode_format.valueOf("QR_CODE")
hint_type = Rjb::import("com.google.zxing.EncodeHintType")
hints = Rjb::import("java.util.HashMap").new
hints.put(hint_type.MARGIN, 0)
result = qrcoder.encode(@content, format, @size, @size, hints)
generate_image(result)
end

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)
else
arr.push(65535, 65535, 65535)
end
end
end
image = Magick::Image.constitute(@size, @size, "RGB", arr.flatten)
image.write(@output_path)
system("convert #{@output_path} -fill '#{@background_color}' -opaque white #{@output_path}")
end

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

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 = Zxing::Zxing.new
zxing.encode(
email_content("qr@example.com", "Testing", "QR code works"),
Rails.root.join("public/qr.png")
)
end

def email_content(email, subject, body)
"mailto:#{email}?subject=#{subject}&body=#{body}"
end

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 qrgenius.net 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.

2 thoughts on “The Process Of Generating Dynamic QR Codes In Rails With Rjb

Leave a Reply

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

WordPress.com Logo

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

Facebook photo

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

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.