zxing 0.1.1 → 0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +59 -0
- data/bin/zxing +24 -0
- data/lib/zxing.rb +36 -46
- data/lib/zxing/client.rb +33 -0
- data/lib/zxing/core.jar +0 -0
- data/lib/zxing/decodable.rb +2 -2
- data/lib/zxing/decoder.rb +73 -0
- data/lib/zxing/javase.jar +0 -0
- data/lib/zxing/server.rb +30 -0
- data/lib/zxing/version.rb +3 -0
- data/spec/fixtures/cat.png +0 -0
- data/spec/fixtures/example.png +0 -0
- data/spec/spec_helper.rb +6 -0
- data/spec/zxing/decodable_spec.rb +34 -0
- data/spec/zxing_spec.rb +77 -0
- metadata +75 -52
- data/README.textile +0 -65
- data/VERSION +0 -1
- data/lib/core.jar +0 -0
- data/lib/javase.jar +0 -0
- data/test/qrcode.png +0 -0
- data/test/test_helper.rb +0 -4
- data/test/zxing/decodable_test.rb +0 -40
- data/test/zxing_test.rb +0 -59
data/README.rdoc
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
= ZXing
|
2
|
+
|
3
|
+
Decode QR codes (and other 1D/2D barcode formats)
|
4
|
+
|
5
|
+
QRcode[http://en.wikipedia.org/wiki/QR_Code] generation is well served in the
|
6
|
+
Ruby community, but decoding seems to be stuck in the Java world. This is an
|
7
|
+
attempt to bridge the gap by wrapping the
|
8
|
+
ZXing[http://code.google.com/p/zxing/] library with JRuby. ZXing conveniently
|
9
|
+
decodes a plethora of barcodes. Their site has a complete list.
|
10
|
+
|
11
|
+
== Installation
|
12
|
+
|
13
|
+
gem install zxing
|
14
|
+
|
15
|
+
== Requirements
|
16
|
+
|
17
|
+
* JRuby (tested with 1.5.6), OR
|
18
|
+
* MRI (1.8.7 and 1.9.2) with jruby-jars gem
|
19
|
+
|
20
|
+
== Usage
|
21
|
+
|
22
|
+
require 'zxing'
|
23
|
+
|
24
|
+
# Pass a path to a file, and it will return the characters encoded within
|
25
|
+
# the barcode image. For example, if a QRCode image has the text "QRcode
|
26
|
+
# string" embedded:
|
27
|
+
ZXing.decode '/Users/ecin/qrcode.png' #=> "QRcode string"
|
28
|
+
|
29
|
+
# You can also decode a URL...
|
30
|
+
ZXing.decode 'http://2d-code.co.uk/images/bbc-logo-in-qr-code.gif'
|
31
|
+
|
32
|
+
# or an instance of File
|
33
|
+
ZXing.decode File.new('qrcode.png')
|
34
|
+
|
35
|
+
# or anything that returns a URL or file path when #path is called on it.
|
36
|
+
class Image
|
37
|
+
attr_reader :path
|
38
|
+
def initialize(path); @path = path end
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
# ZXing#decode returns nil if it can't decode the image.
|
43
|
+
ZXing.decode 'image_without_a_code.png' #=> nil
|
44
|
+
|
45
|
+
# ZXing#decode! will raise an error if it can't decode the image.
|
46
|
+
ZXing.decode! 'image_without_a_code.png' #=> raises ZXing::UndecodableError
|
47
|
+
|
48
|
+
== Decodable module
|
49
|
+
|
50
|
+
A Decodable module is included (pun intended) to ease using the library with objects that return the URL or file path to decode when #path or #to_s is called.
|
51
|
+
|
52
|
+
require 'zxing/decodable'
|
53
|
+
|
54
|
+
class File
|
55
|
+
include Decodable
|
56
|
+
end
|
57
|
+
|
58
|
+
file = File.open('qrcode.png')
|
59
|
+
file.decode
|
data/bin/zxing
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require "jruby-jars"
|
3
|
+
|
4
|
+
port = ARGV[0]
|
5
|
+
|
6
|
+
jruby = JRubyJars.core_jar_path
|
7
|
+
jruby_stdlib = JRubyJars.stdlib_jar_path
|
8
|
+
|
9
|
+
java_args = [
|
10
|
+
"-cp", [JRubyJars.core_jar_path, JRubyJars.stdlib_jar_path].join(":"),
|
11
|
+
"org.jruby.Main"
|
12
|
+
]
|
13
|
+
|
14
|
+
lib = File.expand_path('../../lib', __FILE__)
|
15
|
+
$:.unshift(lib) unless $:.include?(lib)
|
16
|
+
|
17
|
+
path = "#{lib}/zxing/server.rb"
|
18
|
+
|
19
|
+
ruby_args = [
|
20
|
+
"-r", path,
|
21
|
+
"-e", "ZXing::Server.start!(#{port})"
|
22
|
+
]
|
23
|
+
|
24
|
+
exec("java", *(java_args + ruby_args))
|
data/lib/zxing.rb
CHANGED
@@ -1,56 +1,46 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require File.expand_path( File.dirname(__FILE__) + '/core.jar' ) # ZXing core classes
|
4
|
-
require File.expand_path( File.dirname(__FILE__) + '/javase.jar' ) # ZXing JavaSE classes
|
5
|
-
|
6
|
-
require 'uri'
|
7
|
-
|
8
|
-
# Google ZXing classes
|
9
|
-
java_import com.google.zxing.MultiFormatReader
|
10
|
-
java_import com.google.zxing.BinaryBitmap
|
11
|
-
java_import com.google.zxing.Binarizer
|
12
|
-
java_import com.google.zxing.common.GlobalHistogramBinarizer
|
13
|
-
java_import com.google.zxing.LuminanceSource
|
14
|
-
java_import com.google.zxing.client.j2se.BufferedImageLuminanceSource
|
15
|
-
|
16
|
-
# Standard Java classes
|
17
|
-
java_import javax.imageio.ImageIO
|
18
|
-
java_import java.net.URL
|
1
|
+
require 'zxing/version'
|
2
|
+
require 'zxing/decoder'
|
19
3
|
|
20
4
|
module ZXing
|
5
|
+
class UndecodableError < StandardError
|
6
|
+
def message; "Image not decodable"; end
|
7
|
+
end
|
21
8
|
|
22
|
-
|
23
|
-
|
24
|
-
#
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
9
|
+
##
|
10
|
+
# Decodes barcodes from an image file
|
11
|
+
#
|
12
|
+
# +file+ should be the path to the image file to decode, as a string.
|
13
|
+
#
|
14
|
+
# Example:
|
15
|
+
#
|
16
|
+
# path = "path/to/file.png"
|
17
|
+
# ZXing.decode(path) #=> "Encoded text"
|
18
|
+
#
|
19
|
+
# When the image cannot be decoded, +decode+ returns +nil+:
|
20
|
+
#
|
21
|
+
# path = "./no_encoded_image.png"
|
22
|
+
# ZXing.decode(path) #=> nil
|
23
|
+
#
|
24
|
+
def self.decode(file)
|
25
|
+
Decoder.decode normalize(file)
|
33
26
|
end
|
34
27
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
28
|
+
##
|
29
|
+
# Same as +decode+, but raises an exception when image cannot be decoded.
|
30
|
+
#
|
31
|
+
# +file+ should be the path to the image file to decode, as a string.
|
32
|
+
#
|
33
|
+
# Example:
|
34
|
+
#
|
35
|
+
# path = "./no_encoded_image.png"
|
36
|
+
# ZXing.decode(path) #=> ZXing::UndecodableError
|
37
|
+
#
|
38
|
+
def self.decode!(file)
|
39
|
+
Decoder.decode! normalize(file)
|
47
40
|
end
|
48
41
|
|
49
42
|
private
|
50
|
-
|
51
|
-
|
52
|
-
luminance = BufferedImageLuminanceSource.new(image)
|
53
|
-
binarizer = GlobalHistogramBinarizer.new(luminance)
|
54
|
-
BinaryBitmap.new(binarizer)
|
43
|
+
def self.normalize(file)
|
44
|
+
file.respond_to?(:path) ? file.path : file
|
55
45
|
end
|
56
46
|
end
|
data/lib/zxing/client.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
module ZXing
|
2
|
+
BIN = File.expand_path('../../../bin/zxing', __FILE__)
|
3
|
+
|
4
|
+
class Client
|
5
|
+
def self.new
|
6
|
+
port = find_available_port
|
7
|
+
remote_client = IO.popen("#{ZXing::BIN} #{port}")
|
8
|
+
|
9
|
+
sleep 0.5 until responsive?(port)
|
10
|
+
|
11
|
+
at_exit { Process.kill(:INT, remote_client.pid) }
|
12
|
+
client = DRbObject.new_with_uri("druby://127.0.0.1:#{port}")
|
13
|
+
client
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
def self.responsive?(port)
|
18
|
+
socket = TCPSocket.open('127.0.0.1', port)
|
19
|
+
true
|
20
|
+
rescue Errno::ECONNREFUSED
|
21
|
+
false
|
22
|
+
ensure
|
23
|
+
socket.close if socket
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.find_available_port
|
27
|
+
server = TCPServer.new('127.0.0.1', 0)
|
28
|
+
server.addr[1]
|
29
|
+
ensure
|
30
|
+
server.close if server
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/lib/zxing/core.jar
ADDED
Binary file
|
data/lib/zxing/decodable.rb
CHANGED
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'uri'
|
2
|
+
|
3
|
+
module ZXing
|
4
|
+
if RUBY_PLATFORM != 'java'
|
5
|
+
require 'zxing/client'
|
6
|
+
Decoder = Client.new
|
7
|
+
else
|
8
|
+
require 'java'
|
9
|
+
require 'zxing/core.jar'
|
10
|
+
require 'zxing/javase.jar'
|
11
|
+
|
12
|
+
java_import com.google.zxing.MultiFormatReader
|
13
|
+
java_import com.google.zxing.BinaryBitmap
|
14
|
+
java_import com.google.zxing.Binarizer
|
15
|
+
java_import com.google.zxing.common.GlobalHistogramBinarizer
|
16
|
+
java_import com.google.zxing.LuminanceSource
|
17
|
+
java_import com.google.zxing.client.j2se.BufferedImageLuminanceSource
|
18
|
+
|
19
|
+
java_import javax.imageio.ImageIO
|
20
|
+
java_import java.net.URL
|
21
|
+
|
22
|
+
class Decoder
|
23
|
+
attr_accessor :file
|
24
|
+
|
25
|
+
def self.decode!(file)
|
26
|
+
new(file).decode
|
27
|
+
rescue NativeException
|
28
|
+
raise UndecodableError
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.decode(file)
|
32
|
+
decode!(file)
|
33
|
+
rescue UndecodableError
|
34
|
+
nil
|
35
|
+
end
|
36
|
+
|
37
|
+
def initialize(file)
|
38
|
+
self.file = file
|
39
|
+
end
|
40
|
+
|
41
|
+
def decode
|
42
|
+
MultiFormatReader.new.decode(bitmap).to_s
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def bitmap
|
48
|
+
BinaryBitmap.new(binarizer)
|
49
|
+
end
|
50
|
+
|
51
|
+
def image
|
52
|
+
ImageIO.read(io)
|
53
|
+
end
|
54
|
+
|
55
|
+
def io
|
56
|
+
if file =~ URI.regexp(['http', 'https'])
|
57
|
+
URL.new(file)
|
58
|
+
else
|
59
|
+
raise ArgumentError, "File #{file} could not be found" unless File.exist?(file)
|
60
|
+
Java::JavaIO::File.new(file)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def luminance
|
65
|
+
BufferedImageLuminanceSource.new(image)
|
66
|
+
end
|
67
|
+
|
68
|
+
def binarizer
|
69
|
+
GlobalHistogramBinarizer.new(luminance)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
Binary file
|
data/lib/zxing/server.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# Run this in jruby only
|
2
|
+
if RUBY_PLATFORM == 'java'
|
3
|
+
lib = File.expand_path('../..', __FILE__)
|
4
|
+
$:.unshift(lib) unless $:.include?(lib)
|
5
|
+
|
6
|
+
require 'zxing'
|
7
|
+
require 'zxing/decoder'
|
8
|
+
require 'drb/drb'
|
9
|
+
|
10
|
+
module ZXing
|
11
|
+
class Server
|
12
|
+
def self.start!(port)
|
13
|
+
abort_on_parent_exit!
|
14
|
+
DRb.start_service("druby://127.0.0.1:#{port}", ZXing)
|
15
|
+
DRb.thread.join
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
def self.abort_on_parent_exit!
|
20
|
+
Thread.new do
|
21
|
+
begin
|
22
|
+
STDIN.read
|
23
|
+
rescue IOError
|
24
|
+
exit
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
Binary file
|
Binary file
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'zxing/decodable'
|
3
|
+
|
4
|
+
describe Decodable do
|
5
|
+
class Object::File
|
6
|
+
include Decodable
|
7
|
+
end
|
8
|
+
|
9
|
+
class URL
|
10
|
+
include Decodable
|
11
|
+
attr_reader :path
|
12
|
+
def initialize(path)
|
13
|
+
@path = path
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
before(:all) do
|
18
|
+
@file = File.new fixture_image('example')
|
19
|
+
@uri = URL.new 'http://2d-code.co.uk/images/bbc-logo-in-qr-code.gif'
|
20
|
+
@bad_uri = URL.new 'http://google.com'
|
21
|
+
end
|
22
|
+
|
23
|
+
it "provides #decode to decode the return value of #path" do
|
24
|
+
@file.decode.should == ZXing.decode(@file.path)
|
25
|
+
@uri.decode.should == ZXing.decode(@uri.path)
|
26
|
+
@bad_uri.decode.should be_nil
|
27
|
+
end
|
28
|
+
|
29
|
+
it "provides #decode! as well" do
|
30
|
+
@file.decode!.should == ZXing.decode(@file.path)
|
31
|
+
@uri.decode!.should == ZXing.decode(@uri.path)
|
32
|
+
expect { @bad_uri.decode! }.to raise_error(ZXing::UndecodableError, "Image not decodable")
|
33
|
+
end
|
34
|
+
end
|
data/spec/zxing_spec.rb
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'zxing'
|
3
|
+
|
4
|
+
class Foo
|
5
|
+
def path
|
6
|
+
File.expand_path("../fixtures/example.png", __FILE__)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
describe ZXing do
|
11
|
+
describe ".decode" do
|
12
|
+
subject { ZXing.decode(file) }
|
13
|
+
|
14
|
+
context "with a string path to image" do
|
15
|
+
let(:file) { fixture_image("example") }
|
16
|
+
it { should == "example" }
|
17
|
+
end
|
18
|
+
|
19
|
+
context "with a uri" do
|
20
|
+
let(:file) { "http://2d-code.co.uk/images/bbc-logo-in-qr-code.gif" }
|
21
|
+
it { should == "http://bbc.co.uk/programmes" }
|
22
|
+
end
|
23
|
+
|
24
|
+
context "with an instance of File" do
|
25
|
+
let(:file) { File.new(fixture_image("example")) }
|
26
|
+
it { should == "example" }
|
27
|
+
end
|
28
|
+
|
29
|
+
context "with an object that responds to #path" do
|
30
|
+
let(:file) { Foo.new }
|
31
|
+
it { should == "example" }
|
32
|
+
end
|
33
|
+
|
34
|
+
context "when the image cannot be decoded" do
|
35
|
+
let(:file) { fixture_image("cat") }
|
36
|
+
it { should be_nil }
|
37
|
+
end
|
38
|
+
|
39
|
+
context "when file does not exist" do
|
40
|
+
let(:file) { 'nonexistentfile.png' }
|
41
|
+
it "raises an error" do
|
42
|
+
expect { subject }.to raise_error(ArgumentError, "File nonexistentfile.png could not be found")
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
describe ".decode!" do
|
49
|
+
subject { ZXing.decode!(file) }
|
50
|
+
|
51
|
+
context "with a qrcode file" do
|
52
|
+
let(:file) { fixture_image("example") }
|
53
|
+
it { should == "example" }
|
54
|
+
end
|
55
|
+
|
56
|
+
context "when the image cannot be decoded" do
|
57
|
+
let(:file) { fixture_image("cat") }
|
58
|
+
it "raises an error" do
|
59
|
+
expect { subject }.to raise_error(ZXing::UndecodableError, "Image not decodable")
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
context "when the image cannot be decoded from a URL" do
|
64
|
+
let(:file) { "http://www.google.com/logos/grandparentsday10.gif" }
|
65
|
+
it "raises an error" do
|
66
|
+
expect { subject }.to raise_error(ZXing::UndecodableError, "Image not decodable")
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context "when file does not exist" do
|
71
|
+
let(:file) { 'nonexistentfile.png' }
|
72
|
+
it "raises an error" do
|
73
|
+
expect { subject }.to raise_error(ArgumentError, "File nonexistentfile.png could not be found")
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
metadata
CHANGED
@@ -3,84 +3,107 @@ name: zxing
|
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
version: 0.1.1
|
6
|
+
- 0
|
7
|
+
- 2
|
8
|
+
version: "0.2"
|
10
9
|
platform: ruby
|
11
10
|
authors:
|
12
|
-
- ecin
|
11
|
+
- ecin
|
12
|
+
- Joshua Davey
|
13
13
|
autorequire:
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date:
|
17
|
+
date: 2011-02-22 00:00:00 -04:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
|
-
- !ruby/object:Gem::Dependency
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: sdoc
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ~>
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 0
|
29
|
+
- 2
|
30
|
+
- 20
|
31
|
+
version: 0.2.20
|
32
|
+
type: :development
|
33
|
+
version_requirements: *id001
|
34
|
+
- !ruby/object:Gem::Dependency
|
35
|
+
name: rspec
|
36
|
+
prerelease: false
|
37
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ~>
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
segments:
|
42
|
+
- 2
|
43
|
+
- 5
|
44
|
+
- 0
|
45
|
+
version: 2.5.0
|
46
|
+
type: :development
|
47
|
+
version_requirements: *id002
|
34
48
|
description: Need to decode 1D/2D bars and don't mind using JRuby to help with the task? ZXing is the wrapper for you!
|
35
|
-
email:
|
36
|
-
|
37
|
-
|
49
|
+
email:
|
50
|
+
- ecin@copypastel.com
|
51
|
+
- josh@joshuadavey.com
|
52
|
+
executables:
|
53
|
+
- zxing
|
38
54
|
extensions: []
|
39
55
|
|
40
|
-
extra_rdoc_files:
|
41
|
-
|
56
|
+
extra_rdoc_files: []
|
57
|
+
|
42
58
|
files:
|
43
|
-
-
|
44
|
-
-
|
45
|
-
- lib/
|
46
|
-
- lib/
|
47
|
-
- lib/zxing.rb
|
48
|
-
- lib/zxing/
|
49
|
-
-
|
50
|
-
-
|
51
|
-
-
|
52
|
-
-
|
59
|
+
- bin/zxing
|
60
|
+
- lib/zxing.rb
|
61
|
+
- lib/zxing/client.rb
|
62
|
+
- lib/zxing/core.jar
|
63
|
+
- lib/zxing/decodable.rb
|
64
|
+
- lib/zxing/decoder.rb
|
65
|
+
- lib/zxing/javase.jar
|
66
|
+
- lib/zxing/server.rb
|
67
|
+
- lib/zxing/version.rb
|
68
|
+
- spec/spec_helper.rb
|
69
|
+
- spec/zxing_spec.rb
|
70
|
+
- spec/fixtures/cat.png
|
71
|
+
- spec/fixtures/example.png
|
72
|
+
- spec/zxing/decodable_spec.rb
|
73
|
+
- README.rdoc
|
53
74
|
has_rdoc: true
|
54
75
|
homepage: http://github.com/ecin/zxing.rb
|
55
76
|
licenses: []
|
56
77
|
|
57
78
|
post_install_message:
|
58
|
-
rdoc_options:
|
59
|
-
|
79
|
+
rdoc_options: []
|
80
|
+
|
60
81
|
require_paths:
|
61
|
-
- lib
|
82
|
+
- lib
|
62
83
|
required_ruby_version: !ruby/object:Gem::Requirement
|
63
84
|
requirements:
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
85
|
+
- - ">="
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
segments:
|
88
|
+
- 0
|
89
|
+
version: "0"
|
69
90
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
70
91
|
requirements:
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
92
|
+
- - ">="
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
segments:
|
95
|
+
- 0
|
96
|
+
version: "0"
|
76
97
|
requirements: []
|
77
98
|
|
78
|
-
rubyforge_project:
|
99
|
+
rubyforge_project: zxing
|
79
100
|
rubygems_version: 1.3.6
|
80
101
|
signing_key:
|
81
102
|
specification_version: 3
|
82
103
|
summary: JRuby wrapper for ZXing 1D/2D barcode image processing library.
|
83
104
|
test_files:
|
84
|
-
-
|
85
|
-
-
|
86
|
-
-
|
105
|
+
- spec/spec_helper.rb
|
106
|
+
- spec/zxing_spec.rb
|
107
|
+
- spec/fixtures/cat.png
|
108
|
+
- spec/fixtures/example.png
|
109
|
+
- spec/zxing/decodable_spec.rb
|
data/README.textile
DELETED
@@ -1,65 +0,0 @@
|
|
1
|
-
h2. Decode QR Codes
|
2
|
-
|
3
|
-
p. "QR code":http://en.wikipedia.org/wiki/QR_Code generation is well served in the Ruby community, but decoding seems to be stuck in the Java world. This is an attempt to bridge the gap by wrapping the "ZXing":http://code.google.com/p/zxing/ library with JRuby. ZXing conveniently decodes a plethora of barcodes. Their site has a complete list.
|
4
|
-
|
5
|
-
h2. Requirements
|
6
|
-
|
7
|
-
* JRuby (tested with 1.4.0)
|
8
|
-
* shoulda (for testing)
|
9
|
-
|
10
|
-
h2. Using the ZXing module/singleton.
|
11
|
-
|
12
|
-
<pre>
|
13
|
-
<code>
|
14
|
-
require 'zxing'
|
15
|
-
|
16
|
-
# You can decode a URL...
|
17
|
-
ZXing.decode 'http://2d-code.co.uk/images/bbc-logo-in-qr-code.gif'
|
18
|
-
|
19
|
-
# ... or a file path...
|
20
|
-
ZXing.decode '/Users/ecin/qrcode.png'
|
21
|
-
|
22
|
-
# ... or a File object...
|
23
|
-
ZXing.decode File.open('qrcode.png')
|
24
|
-
|
25
|
-
# ... or anything that returns a URL or file path when #path or #to_s
|
26
|
-
# is called on it.
|
27
|
-
class Image
|
28
|
-
attr_reader :path
|
29
|
-
def initialize(path); @path = path end
|
30
|
-
end
|
31
|
-
|
32
|
-
image = Image.new('qrcode.png')
|
33
|
-
ZXing.decode image
|
34
|
-
|
35
|
-
# #decode returns nil if it can't decode the image.
|
36
|
-
ZXing.decode 'image_without_a_code.png'
|
37
|
-
# => nil
|
38
|
-
|
39
|
-
# #decode! will raise an error if it can't decode the image.
|
40
|
-
ZXing.decode! 'image_without_a_code.png'
|
41
|
-
# => NativeException
|
42
|
-
|
43
|
-
# Feel free to include ZXing to shorten the call.
|
44
|
-
include ZXing
|
45
|
-
|
46
|
-
decode 'qrcode.png'
|
47
|
-
</code>
|
48
|
-
</pre>
|
49
|
-
|
50
|
-
h2. Including the Decodable module.
|
51
|
-
|
52
|
-
p. A Decodable module is included (pun intended) to ease using the library with objects that return the URL or file path to decode when #path or #to_s is called.
|
53
|
-
|
54
|
-
<pre>
|
55
|
-
<code>
|
56
|
-
require 'zxing/decodable'
|
57
|
-
|
58
|
-
class File
|
59
|
-
include Decodable
|
60
|
-
end
|
61
|
-
|
62
|
-
file = File.open('qrcode.png')
|
63
|
-
file.decode
|
64
|
-
</code>
|
65
|
-
</pre>
|
data/VERSION
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
0.1.1
|
data/lib/core.jar
DELETED
Binary file
|
data/lib/javase.jar
DELETED
Binary file
|
data/test/qrcode.png
DELETED
Binary file
|
data/test/test_helper.rb
DELETED
@@ -1,40 +0,0 @@
|
|
1
|
-
#!/usr/bin/env jruby --headless -rubygems
|
2
|
-
|
3
|
-
require File.expand_path( File.dirname(__FILE__) + '/../test_helper')
|
4
|
-
require 'zxing/decodable'
|
5
|
-
|
6
|
-
class DecodableTest < Test::Unit::TestCase
|
7
|
-
|
8
|
-
class Object::File
|
9
|
-
include Decodable
|
10
|
-
end
|
11
|
-
|
12
|
-
class URL
|
13
|
-
include Decodable
|
14
|
-
def initialize(path)
|
15
|
-
@path = path
|
16
|
-
end
|
17
|
-
def path; @path end
|
18
|
-
end
|
19
|
-
|
20
|
-
context "A Decodable module" do
|
21
|
-
setup do
|
22
|
-
@file = File.open( File.expand_path( File.dirname(__FILE__) + '/../qrcode.png' ))
|
23
|
-
@uri = URL.new "http://2d-code.co.uk/images/bbc-logo-in-qr-code.gif"
|
24
|
-
@bad_uri = URL.new "http://google.com"
|
25
|
-
end
|
26
|
-
|
27
|
-
should "provide #decode to decode the return value of #path" do
|
28
|
-
assert_equal @file.decode, ZXing.decode(@file.path)
|
29
|
-
assert_equal @uri.decode, ZXing.decode(@uri.path)
|
30
|
-
assert_nil @bad_uri.decode
|
31
|
-
end
|
32
|
-
|
33
|
-
should "provide #decode! as well" do
|
34
|
-
assert_equal @file.decode!, ZXing.decode(@file.path)
|
35
|
-
assert_equal @uri.decode!, ZXing.decode(@uri.path)
|
36
|
-
assert_raise(NativeException) { @bad_uri.decode! }
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
end
|
data/test/zxing_test.rb
DELETED
@@ -1,59 +0,0 @@
|
|
1
|
-
#!/usr/bin/env jruby --headless -rubygems
|
2
|
-
|
3
|
-
require File.expand_path( File.dirname(__FILE__) + '/test_helper')
|
4
|
-
require 'zxing'
|
5
|
-
|
6
|
-
class ZXingTest < Test::Unit::TestCase
|
7
|
-
context "A QR decoder singleton" do
|
8
|
-
|
9
|
-
class Foo < Struct.new(:v); def to_s; self.v; end; end
|
10
|
-
|
11
|
-
setup do
|
12
|
-
@decoder = ZXing
|
13
|
-
@uri = "http://2d-code.co.uk/images/bbc-logo-in-qr-code.gif"
|
14
|
-
@path = File.expand_path( File.dirname(__FILE__) + '/qrcode.png')
|
15
|
-
@file = File.new(@path)
|
16
|
-
@google_logo = "http://www.google.com/logos/grandparentsday10.gif"
|
17
|
-
@uri_result = "http://bbc.co.uk/programmes"
|
18
|
-
@path_result = "http://rubyflow.com"
|
19
|
-
end
|
20
|
-
|
21
|
-
should "decode a URL" do
|
22
|
-
assert_equal @decoder.decode(@uri), @uri_result
|
23
|
-
end
|
24
|
-
|
25
|
-
should "decode a file path" do
|
26
|
-
assert_equal @decoder.decode(@path), @path_result
|
27
|
-
end
|
28
|
-
|
29
|
-
should "return nil if #decode fails" do
|
30
|
-
assert_nil @decoder.decode(@google_logo)
|
31
|
-
end
|
32
|
-
|
33
|
-
should "raise an exception if #decode! fails" do
|
34
|
-
assert_raise(NativeException) { @decoder.decode!(@google_logo) }
|
35
|
-
end
|
36
|
-
|
37
|
-
should "decode objects that respond to #path" do
|
38
|
-
assert_equal @decoder.decode(@file), @path_result
|
39
|
-
end
|
40
|
-
|
41
|
-
should "call #to_s to argument passed in as a last resort" do
|
42
|
-
assert_equal @decoder.decode(Foo.new(@path)), @path_result
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
context "A QR decoder module" do
|
47
|
-
|
48
|
-
setup do
|
49
|
-
class SpyRing; include ZXing end
|
50
|
-
@ring = SpyRing.new
|
51
|
-
end
|
52
|
-
|
53
|
-
should "include #decode and #decode! into classes" do
|
54
|
-
assert_equal defined?(@ring.decode), "method"
|
55
|
-
assert_equal defined?(@ring.decode!), "method"
|
56
|
-
end
|
57
|
-
|
58
|
-
end
|
59
|
-
end
|