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.
Reblogged this on Shailesh's Blog.
rqrcode does render png and svg since 2012, but readme was only updated 2015.