qrencoder 1.3.4 → 1.4.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 +13 -0
- data/README.rdoc +9 -9
- data/ext/qrencoder_ext/qrencoder_ext.c +13 -1
- data/lib/qrencoder.rb +2 -1
- data/lib/qrencoder/png.rb +51 -0
- data/lib/qrencoder/qrcode.rb +3 -24
- data/lib/qrencoder/version.rb +1 -1
- data/spec/integration_spec.rb +32 -4
- data/spec/qrencoder/png_spec.rb +107 -0
- data/spec/{qrcode_spec.rb → qrencoder/qrcode_spec.rb} +5 -5
- data/spec/qrencoder_spec.rb +1 -1
- metadata +9 -6
data/History.txt
CHANGED
@@ -1,3 +1,16 @@
|
|
1
|
+
== 1.4.0 / 2011-10-02
|
2
|
+
|
3
|
+
* API changes
|
4
|
+
* PNG is now a full-fledged object to allow further
|
5
|
+
customization. See chunky_png for more details.
|
6
|
+
* Update chunky_png dependency to allow newest versions
|
7
|
+
|
8
|
+
* Bugfixes
|
9
|
+
* alphanumeric mode was not working correctly
|
10
|
+
* numeric mode segfaulted when passed an integer
|
11
|
+
* Passing an invalid string now raises an ArgumentError
|
12
|
+
rather than segfaulting
|
13
|
+
|
1
14
|
== 1.3.4 / 2011-03-08
|
2
15
|
|
3
16
|
* 1 Minor enhancement
|
data/README.rdoc
CHANGED
@@ -12,12 +12,12 @@ like the following:
|
|
12
12
|
|
13
13
|
http://www.denso-wave.com/qrcode/images/qrcode.gif
|
14
14
|
|
15
|
-
The specification for QR
|
15
|
+
The specification for QR Code is readable at
|
16
16
|
http://www.denso-wave.com/qrcode/index-e.html. QR Code is not the only 2-D
|
17
17
|
barcode standard in existence, and it is in wider use in Japan than elsewhere.
|
18
18
|
Notable competitors include PDF417, Semacode/DataMatrix, and Maxi Code (seen on
|
19
19
|
UPS labels) in North America; ShotCode in the UK; and an additional format used
|
20
|
-
in Korea. All vary in look and capacity, but QR
|
20
|
+
in Korea. All vary in look and capacity, but QR Code has one of the largest
|
21
21
|
information densities and capacities among them with the following maximum data
|
22
22
|
|
23
23
|
* Numeric 7,089
|
@@ -40,7 +40,7 @@ Basic usage is as follows:
|
|
40
40
|
puts "#{qrcode.width}" #=> 34
|
41
41
|
qrcode.save_png("/tmp/foo.png")
|
42
42
|
|
43
|
-
You can retrieve the pixels of the
|
43
|
+
You can retrieve the pixels of the QR Code object directly or use the included
|
44
44
|
methods to save a PNG file directly.
|
45
45
|
|
46
46
|
See the rdocs[http://rdoc.info/github/harrisj/qrencoder] for options you can
|
@@ -53,13 +53,13 @@ from http://megaui.net/fukuchi/works/qrencode/index.en.html.
|
|
53
53
|
|
54
54
|
Installation is usually as simple as:
|
55
55
|
|
56
|
-
curl http://fukuchi.org/works/qrencode/qrencode-3.1.1.tar.gz | tar xz
|
57
|
-
cd qrencode-3.1.1
|
58
|
-
./configure
|
59
|
-
make
|
60
|
-
sudo make install
|
56
|
+
curl http://fukuchi.org/works/qrencode/qrencode-3.1.1.tar.gz | tar xz
|
57
|
+
cd qrencode-3.1.1
|
58
|
+
./configure
|
59
|
+
make
|
60
|
+
sudo make install
|
61
61
|
|
62
|
-
If
|
62
|
+
If it worked, you should be able to type <tt>qrencode</tt> and get a help
|
63
63
|
message.
|
64
64
|
|
65
65
|
Normally, the build process also expects you to have <tt>libpng</tt>, but
|
@@ -1,8 +1,11 @@
|
|
1
1
|
#include "qrencode.h"
|
2
2
|
#include "ruby.h"
|
3
|
+
#include "errno.h"
|
4
|
+
#include "string.h"
|
3
5
|
|
4
6
|
VALUE mQREncoder;
|
5
7
|
VALUE cQRCode;
|
8
|
+
int errno;
|
6
9
|
|
7
10
|
static void qrcode_free(void *p) {
|
8
11
|
QRcode *qrcode = (QRcode *) p;
|
@@ -235,8 +238,17 @@ static VALUE qr_initialize(VALUE self, VALUE _string, VALUE _version, VALUE _ecl
|
|
235
238
|
int eclevel = FIX2INT(_eclevel);
|
236
239
|
int hint = FIX2INT(_hint);
|
237
240
|
int casesensitive = FIX2INT(_casesensitive);
|
241
|
+
int error = errno;
|
242
|
+
QRcode *code;
|
243
|
+
|
244
|
+
QRinput *input = QRinput_new2(version, eclevel);
|
245
|
+
QRinput_append(input, hint, strlen(string), string);
|
246
|
+
code = QRcode_encodeInput(input);
|
247
|
+
QRinput_free(input);
|
238
248
|
|
239
|
-
|
249
|
+
if (errno != error && errno == 22) {
|
250
|
+
rb_raise(rb_eArgError, "input was too long");
|
251
|
+
}
|
240
252
|
|
241
253
|
if (DATA_PTR(self)) {
|
242
254
|
QRcode_free(DATA_PTR(self));
|
data/lib/qrencoder.rb
CHANGED
@@ -45,7 +45,8 @@ module QREncoder
|
|
45
45
|
correction = corrections[options[:correction] || :low]
|
46
46
|
mode = modes[options[:mode] || :ascii]
|
47
47
|
case_sensitive = options[:case_sensitive] == false ? 0 : 1
|
48
|
-
|
48
|
+
string.upcase! if mode == QR_MODE_AN
|
49
|
+
QRCode.new(string.to_s, version, correction, mode, case_sensitive)
|
49
50
|
end
|
50
51
|
|
51
52
|
def self.corrections
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'chunky_png'
|
2
|
+
|
3
|
+
module QREncoder
|
4
|
+
class PNG
|
5
|
+
attr_reader :canvas,
|
6
|
+
:background,
|
7
|
+
:margin,
|
8
|
+
:pixels_per_module,
|
9
|
+
:points,
|
10
|
+
:width
|
11
|
+
|
12
|
+
##
|
13
|
+
# Takes an optional hash of options. See QRCode#png for details.
|
14
|
+
def initialize(qrcode, options={})
|
15
|
+
@points = qrcode.points
|
16
|
+
@margin = options[:margin] || 4
|
17
|
+
@pixels_per_module= options[:pixels_per_module] || 1
|
18
|
+
@background = options[:transparent] ? ChunkyPNG::Color::TRANSPARENT : ChunkyPNG::Color::WHITE
|
19
|
+
@width = (qrcode.width + (2 * margin)) * pixels_per_module
|
20
|
+
|
21
|
+
@canvas = ChunkyPNG::Image.new(width, width, background)
|
22
|
+
plot_points
|
23
|
+
end
|
24
|
+
|
25
|
+
def method_missing(method, *args, &block)
|
26
|
+
if canvas.respond_to?(method)
|
27
|
+
canvas.send(method, *args, &block)
|
28
|
+
else
|
29
|
+
super
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def respond_to?(method)
|
34
|
+
super || canvas.respond_to?(method)
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
def plot_points
|
39
|
+
points.each do |point|
|
40
|
+
pixels_per_module.times do |x_offset|
|
41
|
+
x = (point[0] + margin) * pixels_per_module + x_offset
|
42
|
+
pixels_per_module.times do |y_offset|
|
43
|
+
y = (point[1] + margin) * pixels_per_module + y_offset
|
44
|
+
canvas[x,y] = ChunkyPNG::Color::BLACK
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
data/lib/qrencoder/qrcode.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'qrencoder/png'
|
2
2
|
|
3
3
|
module QREncoder
|
4
4
|
# Stores and represents data, points, and/or pixels for a QRCode
|
@@ -22,32 +22,11 @@ module QREncoder
|
|
22
22
|
# [:pixels_per_module] Adjusts the entire PNG image by the given factor, integer. (default: +1+)
|
23
23
|
#
|
24
24
|
def png(options={})
|
25
|
-
|
25
|
+
PNG.new(self, options)
|
26
26
|
end
|
27
27
|
|
28
|
-
##
|
29
|
-
# Returns an instance of PNG::Canvas
|
30
|
-
#
|
31
|
-
# Takes an optional hash of options. See QRCode#png for details.
|
32
28
|
def canvas(options={})
|
33
|
-
|
34
|
-
ppm = options[:pixels_per_module] || 1
|
35
|
-
background = options[:transparent] ? ChunkyPNG::Color::TRANSPARENT : ChunkyPNG::Color::WHITE
|
36
|
-
png_width = (width + (2 * @margin)) * ppm
|
37
|
-
|
38
|
-
canvas = ChunkyPNG::Image.new(png_width, png_width, background)
|
39
|
-
|
40
|
-
points.each do |point|
|
41
|
-
ppm.times do |x_offset|
|
42
|
-
x = (point[0] + @margin) * ppm + x_offset
|
43
|
-
ppm.times do |y_offset|
|
44
|
-
y = (point[1] + @margin) * ppm + y_offset
|
45
|
-
canvas[x,y] = ChunkyPNG::Color::BLACK
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
canvas
|
29
|
+
png(options).canvas
|
51
30
|
end
|
52
31
|
end
|
53
32
|
end
|
data/lib/qrencoder/version.rb
CHANGED
data/spec/integration_spec.rb
CHANGED
@@ -4,8 +4,9 @@ require 'zxing'
|
|
4
4
|
describe QREncoder do
|
5
5
|
context "integration" do
|
6
6
|
let(:path) { File.expand_path("../../tmp/integration.png", __FILE__) }
|
7
|
-
let(:
|
8
|
-
let(:
|
7
|
+
let(:png_options) { Hash.new }
|
8
|
+
let(:encoding_options) { Hash.new }
|
9
|
+
let(:png) { QREncoder.encode(message, encoding_options).png(png_options) }
|
9
10
|
before do
|
10
11
|
File.unlink(path) if File.file?(path)
|
11
12
|
png.save(path)
|
@@ -23,10 +24,26 @@ describe QREncoder do
|
|
23
24
|
it { should == message }
|
24
25
|
end
|
25
26
|
|
27
|
+
context "with alphanumeric characters" do
|
28
|
+
let(:message) { "A63b902f" }
|
29
|
+
let(:encoding_options) do
|
30
|
+
{ :mode => :alphanumeric }
|
31
|
+
end
|
32
|
+
it { should == "A63B902F" }
|
33
|
+
end
|
34
|
+
|
35
|
+
context "with numeric characters" do
|
36
|
+
let(:message) { 83913 }
|
37
|
+
let(:encoding_options) do
|
38
|
+
{ :mode => :numeric }
|
39
|
+
end
|
40
|
+
it { should == "83913" }
|
41
|
+
end
|
42
|
+
|
26
43
|
context "with a custom pixel per module size" do
|
27
44
|
let(:message) { "bigger" }
|
28
|
-
let(:
|
29
|
-
{ :pixels_per_module => 4
|
45
|
+
let(:png_options) do
|
46
|
+
{ :pixels_per_module => 4 }
|
30
47
|
end
|
31
48
|
it { should == message }
|
32
49
|
it "produces a larger png width and height" do
|
@@ -34,4 +51,15 @@ describe QREncoder do
|
|
34
51
|
end
|
35
52
|
end
|
36
53
|
end
|
54
|
+
|
55
|
+
describe "encoding errors" do
|
56
|
+
context "with too-long input" do
|
57
|
+
let(:message) { "a" * 2960 }
|
58
|
+
it "raises an error" do
|
59
|
+
expect {
|
60
|
+
QREncoder.encode(message)
|
61
|
+
}.to raise_error(ArgumentError)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
37
65
|
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe QREncoder::PNG do
|
4
|
+
let(:png) { QREncoder::PNG.new(qrcode, options) }
|
5
|
+
let(:qrcode) { QREncoder.encode("hi") }
|
6
|
+
let(:options) { Hash.new }
|
7
|
+
|
8
|
+
describe "#points" do
|
9
|
+
it "is initialized from QRCode points" do
|
10
|
+
points = []
|
11
|
+
qrcode.stub(:points => points)
|
12
|
+
png.points.should == points
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "#width" do
|
17
|
+
before { qrcode.stub(:width => qrcode_width) }
|
18
|
+
let(:qrcode_width) { 21 }
|
19
|
+
subject { png.width }
|
20
|
+
|
21
|
+
context "with a QRCode width of 21, default margin" do
|
22
|
+
it { should == 29 }
|
23
|
+
end
|
24
|
+
|
25
|
+
context "with a QRCode width of 21, margin of 8" do
|
26
|
+
let(:options) { {:margin => 8} }
|
27
|
+
it { should == 37 }
|
28
|
+
end
|
29
|
+
|
30
|
+
context "with QRCode width of 21, pixels-per-module of 2" do
|
31
|
+
let(:qrcode_width) { 21 }
|
32
|
+
let(:options) { {:pixels_per_module => 2} }
|
33
|
+
it { should == 58 }
|
34
|
+
end
|
35
|
+
|
36
|
+
context "with QRCode width of 25, pixels-per-module of 5, margin of 5" do
|
37
|
+
let(:qrcode_width) { 25 }
|
38
|
+
let(:options) { {:pixels_per_module => 5, :margin => 5} }
|
39
|
+
it { should == (10 + 25) * 5 }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "#background" do
|
44
|
+
subject { png }
|
45
|
+
|
46
|
+
context "with default options" do
|
47
|
+
it "should be white" do
|
48
|
+
subject.get_pixel(1,1).should == ChunkyPNG::Color::WHITE
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context "with transparent set to true" do
|
53
|
+
subject { png.canvas() }
|
54
|
+
let(:options) { {:transparent => true} }
|
55
|
+
it "should be transparent" do
|
56
|
+
subject.get_pixel(1,1).should == ChunkyPNG::Color::TRANSPARENT
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe "#canvas" do
|
62
|
+
subject { png.canvas }
|
63
|
+
it { should be_kind_of(ChunkyPNG::Image) }
|
64
|
+
end
|
65
|
+
|
66
|
+
describe "#save" do
|
67
|
+
it "is delegated to canvas" do
|
68
|
+
path = 'a/path.png'
|
69
|
+
png.canvas.should_receive(:save).with(path)
|
70
|
+
png.save(path)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe "#to_datastream" do
|
75
|
+
it "is delegated to canvas" do
|
76
|
+
png.canvas.should_receive(:to_datastream)
|
77
|
+
png.to_datastream
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
describe "#to_blob" do
|
82
|
+
it "is delegated to canvas" do
|
83
|
+
png.canvas.should_receive(:to_blob)
|
84
|
+
png.to_blob
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe "#respond_to?" do
|
89
|
+
context "when method exists" do
|
90
|
+
it "returns true" do
|
91
|
+
png.should respond_to(:width)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
context "when method does not exist but is defined on ChunkyPNG::Canvas" do
|
96
|
+
it "returns true" do
|
97
|
+
png.should respond_to(:to_datastream)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
context "when method exists on neither self or canvas" do
|
102
|
+
it "returns false" do
|
103
|
+
png.should_not respond_to(:a_method_that_does_not_exist)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -179,14 +179,14 @@ describe QREncoder::QRCode do
|
|
179
179
|
describe "#png" do
|
180
180
|
let(:qrcode) { QREncoder.encode("hi") }
|
181
181
|
|
182
|
-
it "returns an instance of
|
183
|
-
qrcode.png.should be_kind_of(
|
182
|
+
it "returns an instance of QREncoder::PNG" do
|
183
|
+
qrcode.png.should be_kind_of(QREncoder::PNG)
|
184
184
|
end
|
185
185
|
|
186
186
|
it "sends options to #canvas" do
|
187
|
-
canvas =
|
187
|
+
canvas = QREncoder::PNG.new(qrcode)
|
188
188
|
options = { :margin => 5, :transparent => true }
|
189
|
-
qrcode.should_receive(:
|
189
|
+
qrcode.should_receive(:png).with(options).and_return(canvas)
|
190
190
|
qrcode.png(options)
|
191
191
|
end
|
192
192
|
end
|
@@ -194,7 +194,7 @@ describe QREncoder::QRCode do
|
|
194
194
|
describe "#save_png" do
|
195
195
|
let(:qrcode) { QREncoder.encode("hi") }
|
196
196
|
let(:path) do
|
197
|
-
File.expand_path("
|
197
|
+
File.expand_path("../../../tmp/test.png", __FILE__)
|
198
198
|
end
|
199
199
|
|
200
200
|
before { File.unlink(path) if File.file?(path) }
|
data/spec/qrencoder_spec.rb
CHANGED
@@ -42,7 +42,7 @@ describe QREncoder do
|
|
42
42
|
|
43
43
|
it { should be_a_kind_of(QREncoder::QRCode) }
|
44
44
|
it "encodes using the specified mode" do
|
45
|
-
QREncoder::QRCode.should_receive(:new).with("
|
45
|
+
QREncoder::QRCode.should_receive(:new).with("STRING",
|
46
46
|
1,
|
47
47
|
QREncoder::QR_ECLEVEL_L,
|
48
48
|
QREncoder::QR_MODE_AN,
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: qrencoder
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 1.
|
5
|
+
version: 1.4.0
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Jacob Harris
|
@@ -12,7 +12,7 @@ autorequire:
|
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
14
|
|
15
|
-
date: 2011-
|
15
|
+
date: 2011-10-02 00:00:00 -05:00
|
16
16
|
default_executable:
|
17
17
|
dependencies:
|
18
18
|
- !ruby/object:Gem::Dependency
|
@@ -23,7 +23,7 @@ dependencies:
|
|
23
23
|
requirements:
|
24
24
|
- - ~>
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 2.4
|
26
|
+
version: "2.4"
|
27
27
|
type: :development
|
28
28
|
version_requirements: *id001
|
29
29
|
- !ruby/object:Gem::Dependency
|
@@ -67,7 +67,7 @@ dependencies:
|
|
67
67
|
requirements:
|
68
68
|
- - ~>
|
69
69
|
- !ruby/object:Gem::Version
|
70
|
-
version: 1.1
|
70
|
+
version: "1.1"
|
71
71
|
type: :runtime
|
72
72
|
version_requirements: *id005
|
73
73
|
description: |-
|
@@ -84,6 +84,7 @@ extra_rdoc_files:
|
|
84
84
|
- README.rdoc
|
85
85
|
- ext/qrencoder_ext/qrencoder_ext.c
|
86
86
|
files:
|
87
|
+
- lib/qrencoder/png.rb
|
87
88
|
- lib/qrencoder/qrcode.rb
|
88
89
|
- lib/qrencoder/version.rb
|
89
90
|
- lib/qrencoder.rb
|
@@ -92,7 +93,8 @@ files:
|
|
92
93
|
- History.txt
|
93
94
|
- README.rdoc
|
94
95
|
- spec/integration_spec.rb
|
95
|
-
- spec/
|
96
|
+
- spec/qrencoder/png_spec.rb
|
97
|
+
- spec/qrencoder/qrcode_spec.rb
|
96
98
|
- spec/qrencoder_spec.rb
|
97
99
|
- spec/spec_helper.rb
|
98
100
|
has_rdoc: true
|
@@ -125,6 +127,7 @@ specification_version: 3
|
|
125
127
|
summary: Wrapper around the C qrencode library for creating QR Codes
|
126
128
|
test_files:
|
127
129
|
- spec/integration_spec.rb
|
128
|
-
- spec/
|
130
|
+
- spec/qrencoder/png_spec.rb
|
131
|
+
- spec/qrencoder/qrcode_spec.rb
|
129
132
|
- spec/qrencoder_spec.rb
|
130
133
|
- spec/spec_helper.rb
|