qrencoder 1.0.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +5 -0
- data/{README.txt → README.rdoc} +41 -19
- data/ext/qrencoder_ext/extconf.rb +7 -0
- data/ext/qrencoder_ext/qrencoder_ext.c +273 -0
- data/lib/qrencoder.rb +54 -268
- data/lib/qrencoder/qrcode.rb +54 -0
- data/lib/qrencoder/qrencoder_ext.bundle +0 -0
- data/lib/qrencoder/version.rb +3 -0
- data/spec/qrcode_spec.rb +204 -0
- data/spec/qrencoder_spec.rb +69 -0
- data/spec/spec_helper.rb +8 -0
- metadata +140 -59
- data/Manifest.txt +0 -7
- data/Rakefile +0 -19
- data/bin/qrencoder +0 -0
- data/test/test_qrencoder.rb +0 -99
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'png'
|
2
|
+
|
3
|
+
module QREncoder
|
4
|
+
# Stores and represents data, points, and/or pixels for a QRCode
|
5
|
+
class QRCode
|
6
|
+
##
|
7
|
+
# Shortcut to save the QRcode as a PNG at +path+ using default options.
|
8
|
+
#
|
9
|
+
# For more control, or to specify non-default options, see QRCode#png
|
10
|
+
def save_png(path)
|
11
|
+
png.save(path)
|
12
|
+
end
|
13
|
+
|
14
|
+
##
|
15
|
+
# Returns an instance of PNG, which can be saved to a file with PNG#save or
|
16
|
+
# converted to a blob for inline file transfer with PNG#to_blob. For more
|
17
|
+
# information, see http://seattlerb.rubyforge.org/png/
|
18
|
+
#
|
19
|
+
# Options:
|
20
|
+
#
|
21
|
+
# [:margin] A pixel value for the margin around each side of the code. This should be 4 or greater. (default: +4+)
|
22
|
+
# [:transparent] Background transparency. Can be true or false. (default: +false+)
|
23
|
+
#
|
24
|
+
def png(options={})
|
25
|
+
PNG.new(canvas(options))
|
26
|
+
end
|
27
|
+
|
28
|
+
##
|
29
|
+
# Returns an instance of PNG::Canvas
|
30
|
+
#
|
31
|
+
# Takes an optional hash of options. See QRCode#png for details.
|
32
|
+
def canvas(options={})
|
33
|
+
@margin = options[:margin] || 4
|
34
|
+
background = options[:transparent] ? PNG::Color::Background : PNG::Color::White
|
35
|
+
png_width = width + (2 * @margin)
|
36
|
+
|
37
|
+
canvas = PNG::Canvas.new(png_width, png_width, background)
|
38
|
+
|
39
|
+
points.each do |p|
|
40
|
+
x, y = png_coordinates_for_point(p)
|
41
|
+
canvas[x,y] = PNG::Color::Black
|
42
|
+
end
|
43
|
+
|
44
|
+
canvas
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
def png_coordinates_for_point(point)
|
49
|
+
x = point[0] + @margin
|
50
|
+
y = width - 1 - point[1] + @margin
|
51
|
+
[x,y]
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
Binary file
|
data/spec/qrcode_spec.rb
ADDED
@@ -0,0 +1,204 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'fixtures'
|
3
|
+
|
4
|
+
describe QREncoder::QRCode do
|
5
|
+
|
6
|
+
describe "#data" do
|
7
|
+
context "with default options and 'String'" do
|
8
|
+
subject { QREncoder.encode("String").data }
|
9
|
+
it { should be_kind_of(Array) }
|
10
|
+
it "generates the correct data array" do
|
11
|
+
subject.should == QREncoder::Fixtures::String1
|
12
|
+
end
|
13
|
+
end
|
14
|
+
context "with version 4 and 'String'" do
|
15
|
+
subject { QREncoder.encode("String", :version => 4).data }
|
16
|
+
it { should be_kind_of(Array) }
|
17
|
+
it "generates the correct data array" do
|
18
|
+
subject.should == QREncoder::Fixtures::String4
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "#dup" do
|
24
|
+
subject { QREncoder.encode("something").dup }
|
25
|
+
its(:width) { should == 21 }
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "#width" do
|
29
|
+
subject { QREncoder.encode("something").width }
|
30
|
+
it { should == 21 }
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "#version" do
|
34
|
+
|
35
|
+
context "when not specified" do
|
36
|
+
subject { QREncoder.encode(string).version }
|
37
|
+
context "and string fits within version 1" do
|
38
|
+
let(:string) { "hello" }
|
39
|
+
it { should == 1 }
|
40
|
+
end
|
41
|
+
context "and string is too large for version 1" do
|
42
|
+
let(:string) { "hello" }
|
43
|
+
it { should == 1 }
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context "when specified" do
|
48
|
+
subject { QREncoder.encode(string, :version => 2).version }
|
49
|
+
context "and string fits within specified version" do
|
50
|
+
let(:string) { "hello" }
|
51
|
+
it { should == 2 }
|
52
|
+
end
|
53
|
+
context "and string is too large for specified version" do
|
54
|
+
let(:string) { "Lorem ipsum dolor et al and then some more content" }
|
55
|
+
it { should == 3 }
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
describe "#width" do
|
62
|
+
subject { QREncoder.encode("test", :version => version).width }
|
63
|
+
context "with version 1" do
|
64
|
+
let(:version) { 1 }
|
65
|
+
it { should == 21 }
|
66
|
+
end
|
67
|
+
context "with version 2" do
|
68
|
+
let(:version) { 2 }
|
69
|
+
it { should == 25 }
|
70
|
+
end
|
71
|
+
context "with version 3" do
|
72
|
+
let(:version) { 3 }
|
73
|
+
it { should == 29 }
|
74
|
+
end
|
75
|
+
context "with version 4" do
|
76
|
+
let(:version) { 4 }
|
77
|
+
it { should == 33 }
|
78
|
+
end
|
79
|
+
context "with version 5" do
|
80
|
+
let(:version) { 5 }
|
81
|
+
it { should == 37 }
|
82
|
+
end
|
83
|
+
context "with version 6" do
|
84
|
+
let(:version) { 6 }
|
85
|
+
it { should == 41 }
|
86
|
+
end
|
87
|
+
context "with version 11" do
|
88
|
+
let(:version) { 11 }
|
89
|
+
it { should == 61 }
|
90
|
+
end
|
91
|
+
context "with version 15" do
|
92
|
+
let(:version) { 15 }
|
93
|
+
it { should == 77 }
|
94
|
+
end
|
95
|
+
context "with version 40 (the maximum)" do
|
96
|
+
let(:version) { 40 }
|
97
|
+
it { should == 177 }
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe "#height" do
|
102
|
+
subject { QREncoder.encode("test") }
|
103
|
+
it "should be the same as the width" do
|
104
|
+
subject.height.should == subject.width
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
describe "#pixels" do
|
109
|
+
let(:qrcode) { QREncoder.encode("hi") }
|
110
|
+
let(:pixels) do
|
111
|
+
arr = []
|
112
|
+
qrcode.data.each_slice(qrcode.width) do |a|
|
113
|
+
arr << a.map { |p| p & 0x1 }
|
114
|
+
end
|
115
|
+
arr
|
116
|
+
end
|
117
|
+
|
118
|
+
it "provides pixel data" do
|
119
|
+
qrcode.pixels.should == pixels
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
describe "#points" do
|
124
|
+
let(:qrcode) { QREncoder.encode("hi") }
|
125
|
+
let(:points) do
|
126
|
+
arr = []
|
127
|
+
y = 0
|
128
|
+
qrcode.data.each_slice(qrcode.width) do |r|
|
129
|
+
x = 0;
|
130
|
+
r.each do |p|
|
131
|
+
if (p & 0x1) == 1
|
132
|
+
arr << [x, y]
|
133
|
+
end
|
134
|
+
x += 1
|
135
|
+
end
|
136
|
+
y += 1
|
137
|
+
end
|
138
|
+
arr
|
139
|
+
end
|
140
|
+
|
141
|
+
it "provides point data" do
|
142
|
+
qrcode.points.should == points
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
describe "#canvas" do
|
147
|
+
let(:qrcode) { QREncoder.encode("hi") }
|
148
|
+
|
149
|
+
it "returns an instance of PNG::Canvas" do
|
150
|
+
qrcode.canvas.should be_kind_of(PNG::Canvas)
|
151
|
+
end
|
152
|
+
|
153
|
+
context "with no options specified" do
|
154
|
+
subject { qrcode.canvas }
|
155
|
+
its(:width) { should == qrcode.width + (4 * 2) }
|
156
|
+
specify "background should be white" do
|
157
|
+
subject.data.first.first.should == PNG::Color::White
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
context "with margin option of 8" do
|
162
|
+
subject { qrcode.canvas(:margin => 8) }
|
163
|
+
its(:width) { should == qrcode.width + (8 * 2) }
|
164
|
+
end
|
165
|
+
|
166
|
+
context "with transparent set to true" do
|
167
|
+
subject { qrcode.canvas(:transparent => true) }
|
168
|
+
specify "background should be transparent" do
|
169
|
+
subject.data.first.first.should == PNG::Color::Background
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
describe "#png" do
|
175
|
+
let(:qrcode) { QREncoder.encode("hi") }
|
176
|
+
|
177
|
+
it "returns an instance of PNG" do
|
178
|
+
qrcode.png.should be_kind_of(PNG)
|
179
|
+
end
|
180
|
+
|
181
|
+
it "sends options to #canvas" do
|
182
|
+
canvas = PNG::Canvas.new(1,1)
|
183
|
+
options = { :margin => 5, :transparent => true }
|
184
|
+
qrcode.should_receive(:canvas).with(options).and_return(canvas)
|
185
|
+
qrcode.png(options)
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
describe "#save_png" do
|
190
|
+
let(:qrcode) { QREncoder.encode("hi") }
|
191
|
+
let(:path) do
|
192
|
+
File.expand_path("../../tmp/test.png", __FILE__)
|
193
|
+
end
|
194
|
+
|
195
|
+
before { File.unlink(path) if File.file?(path) }
|
196
|
+
|
197
|
+
it "saves a png image to path specified" do
|
198
|
+
qrcode.save_png(path)
|
199
|
+
File.open(path) { true }
|
200
|
+
File.size(path).should_not be_zero
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe QREncoder do
|
4
|
+
|
5
|
+
describe ".encode" do
|
6
|
+
context "when passed a string" do
|
7
|
+
subject { QREncoder.encode("string") }
|
8
|
+
|
9
|
+
it { should be_a_kind_of(QREncoder::QRCode) }
|
10
|
+
end
|
11
|
+
|
12
|
+
context "when passed a string and version option" do
|
13
|
+
subject { QREncoder.encode("string", :version => 2) }
|
14
|
+
|
15
|
+
it { should be_a_kind_of(QREncoder::QRCode) }
|
16
|
+
it "encodes using the specified version" do
|
17
|
+
QREncoder::QRCode.should_receive(:new).with("string",
|
18
|
+
2,
|
19
|
+
QREncoder::QR_ECLEVEL_L,
|
20
|
+
QREncoder::QR_MODE_8,
|
21
|
+
1)
|
22
|
+
subject
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context "when passed a string and correction option" do
|
27
|
+
subject { QREncoder.encode("string", :correction => :high) }
|
28
|
+
|
29
|
+
it { should be_a_kind_of(QREncoder::QRCode) }
|
30
|
+
it "encodes using the specified correction mode" do
|
31
|
+
QREncoder::QRCode.should_receive(:new).with("string",
|
32
|
+
1,
|
33
|
+
QREncoder::QR_ECLEVEL_H,
|
34
|
+
QREncoder::QR_MODE_8,
|
35
|
+
1)
|
36
|
+
subject
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context "when passed a string and mode option" do
|
41
|
+
subject { QREncoder.encode("string", :mode => :alphanumeric) }
|
42
|
+
|
43
|
+
it { should be_a_kind_of(QREncoder::QRCode) }
|
44
|
+
it "encodes using the specified mode" do
|
45
|
+
QREncoder::QRCode.should_receive(:new).with("string",
|
46
|
+
1,
|
47
|
+
QREncoder::QR_ECLEVEL_L,
|
48
|
+
QREncoder::QR_MODE_AN,
|
49
|
+
1)
|
50
|
+
subject
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context "when passed a string and case_sensitive option" do
|
55
|
+
subject { QREncoder.encode("string", :case_sensitive => false) }
|
56
|
+
|
57
|
+
it { should be_a_kind_of(QREncoder::QRCode) }
|
58
|
+
it "encodes using the specified case sensitivity" do
|
59
|
+
QREncoder::QRCode.should_receive(:new).with("string",
|
60
|
+
1,
|
61
|
+
QREncoder::QR_ECLEVEL_L,
|
62
|
+
QREncoder::QR_MODE_8,
|
63
|
+
0)
|
64
|
+
subject
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
CHANGED
@@ -1,78 +1,159 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
|
-
rubygems_version: 0.9.1
|
3
|
-
specification_version: 1
|
4
2
|
name: qrencoder
|
5
3
|
version: !ruby/object:Gem::Version
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
-
|
11
|
-
|
12
|
-
homepage: http://nycrb.rubyforge.org/qrencoder
|
13
|
-
rubyforge_project: nycrb
|
14
|
-
description: The author was too lazy to write a description
|
15
|
-
autorequire:
|
16
|
-
default_executable:
|
17
|
-
bindir: bin
|
18
|
-
has_rdoc: true
|
19
|
-
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
-
requirements:
|
21
|
-
- - ">"
|
22
|
-
- !ruby/object:Gem::Version
|
23
|
-
version: 0.0.0
|
24
|
-
version:
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 1
|
7
|
+
- 2
|
8
|
+
- 0
|
9
|
+
version: 1.2.0
|
25
10
|
platform: ruby
|
26
|
-
signing_key:
|
27
|
-
cert_chain:
|
28
|
-
post_install_message:
|
29
11
|
authors:
|
30
12
|
- Jacob Harris
|
31
|
-
|
32
|
-
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
- bin/qrencoder
|
37
|
-
- lib/qrencoder.rb
|
38
|
-
- test/test_qrencoder.rb
|
39
|
-
test_files:
|
40
|
-
- test/test_qrencoder.rb
|
41
|
-
rdoc_options: []
|
42
|
-
|
43
|
-
extra_rdoc_files: []
|
44
|
-
|
45
|
-
executables:
|
46
|
-
- qrencoder
|
47
|
-
extensions: []
|
48
|
-
|
49
|
-
requirements: []
|
13
|
+
- Joshua Davey
|
14
|
+
- Wesley Moore
|
15
|
+
autorequire:
|
16
|
+
bindir: bin
|
17
|
+
cert_chain: []
|
50
18
|
|
19
|
+
date: 2010-11-23 00:00:00 -06:00
|
20
|
+
default_executable:
|
51
21
|
dependencies:
|
52
22
|
- !ruby/object:Gem::Dependency
|
53
|
-
name:
|
54
|
-
|
55
|
-
|
23
|
+
name: rspec
|
24
|
+
prerelease: false
|
25
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
56
27
|
requirements:
|
57
|
-
- -
|
28
|
+
- - ~>
|
58
29
|
- !ruby/object:Gem::Version
|
59
|
-
|
60
|
-
|
30
|
+
segments:
|
31
|
+
- 2
|
32
|
+
- 4
|
33
|
+
- 0
|
34
|
+
version: 2.4.0
|
35
|
+
type: :development
|
36
|
+
version_requirements: *id001
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: rake-compiler
|
39
|
+
prerelease: false
|
40
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
segments:
|
46
|
+
- 0
|
47
|
+
- 7
|
48
|
+
- 5
|
49
|
+
version: 0.7.5
|
50
|
+
type: :development
|
51
|
+
version_requirements: *id002
|
52
|
+
- !ruby/object:Gem::Dependency
|
53
|
+
name: sdoc
|
54
|
+
prerelease: false
|
55
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
56
|
+
none: false
|
57
|
+
requirements:
|
58
|
+
- - ~>
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
segments:
|
61
|
+
- 0
|
62
|
+
- 2
|
63
|
+
- 20
|
64
|
+
version: 0.2.20
|
65
|
+
type: :development
|
66
|
+
version_requirements: *id003
|
61
67
|
- !ruby/object:Gem::Dependency
|
62
68
|
name: png
|
63
|
-
|
64
|
-
|
69
|
+
prerelease: false
|
70
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
71
|
+
none: false
|
65
72
|
requirements:
|
66
|
-
- -
|
73
|
+
- - ~>
|
67
74
|
- !ruby/object:Gem::Version
|
68
|
-
|
69
|
-
|
75
|
+
segments:
|
76
|
+
- 1
|
77
|
+
- 2
|
78
|
+
- 0
|
79
|
+
version: 1.2.0
|
80
|
+
type: :runtime
|
81
|
+
version_requirements: *id004
|
70
82
|
- !ruby/object:Gem::Dependency
|
71
|
-
name:
|
72
|
-
|
73
|
-
|
83
|
+
name: RubyInline
|
84
|
+
prerelease: false
|
85
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
86
|
+
none: false
|
74
87
|
requirements:
|
75
88
|
- - ">="
|
76
89
|
- !ruby/object:Gem::Version
|
77
|
-
|
78
|
-
|
90
|
+
segments:
|
91
|
+
- 3
|
92
|
+
- 6
|
93
|
+
- 2
|
94
|
+
version: 3.6.2
|
95
|
+
type: :runtime
|
96
|
+
version_requirements: *id005
|
97
|
+
description: |-
|
98
|
+
This Gem is a wrapper around an useful open-source library for creating QR
|
99
|
+
Codes, a two-dimensional bar code format popular in Japan created by the Denso-Wave Corporation in 1994.
|
100
|
+
email:
|
101
|
+
- harrisj@schizopolis.net
|
102
|
+
- josh@joshuadavey.com
|
103
|
+
executables: []
|
104
|
+
|
105
|
+
extensions: []
|
106
|
+
|
107
|
+
extra_rdoc_files:
|
108
|
+
- README.rdoc
|
109
|
+
- ext/qrencoder_ext/qrencoder_ext.c
|
110
|
+
files:
|
111
|
+
- lib/qrencoder/qrcode.rb
|
112
|
+
- lib/qrencoder/qrencoder_ext.bundle
|
113
|
+
- lib/qrencoder/version.rb
|
114
|
+
- lib/qrencoder.rb
|
115
|
+
- ext/qrencoder_ext/extconf.rb
|
116
|
+
- ext/qrencoder_ext/qrencoder_ext.c
|
117
|
+
- History.txt
|
118
|
+
- README.rdoc
|
119
|
+
- spec/qrcode_spec.rb
|
120
|
+
- spec/qrencoder_spec.rb
|
121
|
+
- spec/spec_helper.rb
|
122
|
+
has_rdoc: true
|
123
|
+
homepage: http://nycrb.rubyforge.org/qrencoder
|
124
|
+
licenses: []
|
125
|
+
|
126
|
+
post_install_message:
|
127
|
+
rdoc_options: []
|
128
|
+
|
129
|
+
require_paths:
|
130
|
+
- lib
|
131
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
132
|
+
none: false
|
133
|
+
requirements:
|
134
|
+
- - ">="
|
135
|
+
- !ruby/object:Gem::Version
|
136
|
+
segments:
|
137
|
+
- 0
|
138
|
+
version: "0"
|
139
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
140
|
+
none: false
|
141
|
+
requirements:
|
142
|
+
- - ">="
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
segments:
|
145
|
+
- 1
|
146
|
+
- 3
|
147
|
+
- 6
|
148
|
+
version: 1.3.6
|
149
|
+
requirements: []
|
150
|
+
|
151
|
+
rubyforge_project:
|
152
|
+
rubygems_version: 1.3.7
|
153
|
+
signing_key:
|
154
|
+
specification_version: 3
|
155
|
+
summary: Wrapper around the C qrencode library for creating QR Codes
|
156
|
+
test_files:
|
157
|
+
- spec/qrcode_spec.rb
|
158
|
+
- spec/qrencoder_spec.rb
|
159
|
+
- spec/spec_helper.rb
|