rqrcode-renderer 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +25 -0
- data/Rakefile +2 -0
- data/lib/rqrcode/renderer/version.rb +5 -0
- data/lib/rqrcode/renderer.rb +111 -0
- data/lib/rqrcode-renderer.rb +7 -0
- data/rqrcode-renderer.gemspec +22 -0
- metadata +109 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Samuel Cochran
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# Rqrcode::Renderer
|
2
|
+
|
3
|
+
Render QR codes from rails as images or SVG.
|
4
|
+
|
5
|
+
Auto-negotiates based on requested format and browser acceptance.
|
6
|
+
|
7
|
+
## Usage
|
8
|
+
|
9
|
+
Put it in your Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem rqrcode-renderer
|
13
|
+
```
|
14
|
+
|
15
|
+
Use it in an action:
|
16
|
+
|
17
|
+
```ruby
|
18
|
+
class MyController < ActionController::Base
|
19
|
+
def my_action
|
20
|
+
render qrcode: "something"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
```
|
24
|
+
|
25
|
+
Add `scale: 5` etc. to make it bigger.
|
data/Rakefile
ADDED
@@ -0,0 +1,111 @@
|
|
1
|
+
module RQRCode
|
2
|
+
LEVELS = %w(l m q h).freeze
|
3
|
+
|
4
|
+
SIZES = (1..40).to_a.freeze
|
5
|
+
|
6
|
+
# CAPACITY = Hash[LEVELS.map { |level| [level, [nil] * SIZES.length] }]
|
7
|
+
# SIZES.each { |size| LEVELS.each { |level| next if CAPACITY[level][size - 1]; string = "a" * (CAPACITY[level][size - 2] || 0); begin; loop { QRCode.new(string << "a", size: size, level: level) }; rescue QRCodeRunTimeError; CAPACITY[level][size - 1] = string.length; puts "#{size}#{level}: #{CAPACITY[level][size - 1]}"; end } }
|
8
|
+
|
9
|
+
CAPACITY = {"l"=>[18, 33, 54, 79, 107, 135, 155, 193, 231, 272, 322, 368, 426, 459, 521, 587, 645, 719, 793, 859, 930, 1004, 1092, 1172, 1274, 1368, 1466, 1529, 1629, 1733, 1841, 1953, 2069, 2189, 2304, 2432, 2564, 2700, 2810, 2954], "m"=>[15, 27, 43, 63, 85, 107, 123, 153, 181, 214, 252, 288, 332, 363, 413, 451, 505, 561, 625, 667, 712, 780, 858, 912, 998, 1060, 1126, 1191, 1265, 1371, 1453, 1539, 1629, 1723, 1810, 1912, 1990, 2100, 2214, 2332], "q"=>[12, 21, 33, 47, 61, 75, 87, 109, 131, 152, 178, 204, 242, 259, 293, 323, 365, 395, 443, 483, 510, 566, 612, 662, 716, 752, 806, 869, 909, 983, 1031, 1113, 1169, 1229, 1284, 1352, 1424, 1500, 1580, 1664], "h"=>[8, 15, 25, 35, 45, 59, 65, 85, 99, 120, 138, 156, 178, 195, 196, 251, 281, 311, 339, 383, 404, 440, 462, 512, 536, 594, 626, 659, 699, 743, 791, 843, 899, 959, 984, 1052, 1094, 1140, 1220, 1274]}.with_indifferent_access.freeze
|
10
|
+
|
11
|
+
def self.size_for string, level=:h
|
12
|
+
length = string.length
|
13
|
+
SIZES.find { |size| CAPACITY[level][size - 1] > length }
|
14
|
+
end
|
15
|
+
|
16
|
+
module Renderer
|
17
|
+
ActiveSupport.on_load(:action_controller) do
|
18
|
+
ActionController::Renderers.add :qrcode do |string, options|
|
19
|
+
level = options.delete :level
|
20
|
+
level ||= :h
|
21
|
+
|
22
|
+
size = options.delete :size
|
23
|
+
size ||= RQRCode.size_for string
|
24
|
+
|
25
|
+
qrcode = RQRCode::QRCode.new string, :size => size, :level => level
|
26
|
+
|
27
|
+
type = options.delete(:type) || request.negotiate_mime(ImageBody::TYPES).try(:to_s) || "image/png"
|
28
|
+
|
29
|
+
self.content_type = type
|
30
|
+
self.response_body = Body.new qrcode.modules, type, options
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class Body
|
35
|
+
attr_accessor :modules, :type, :options
|
36
|
+
|
37
|
+
def self.new modules, type, options={}
|
38
|
+
return super unless self == Body
|
39
|
+
if type == "image/svg+xml"
|
40
|
+
SvgBody
|
41
|
+
else
|
42
|
+
ImageBody
|
43
|
+
end.new modules, type, options
|
44
|
+
end
|
45
|
+
|
46
|
+
def initialize modules, type, options={}
|
47
|
+
self.modules = modules
|
48
|
+
self.type = type
|
49
|
+
self.options = options
|
50
|
+
end
|
51
|
+
|
52
|
+
def width
|
53
|
+
modules.first.length
|
54
|
+
end
|
55
|
+
|
56
|
+
def height
|
57
|
+
modules.length
|
58
|
+
end
|
59
|
+
|
60
|
+
def scale
|
61
|
+
@scale ||= [options[:scale].to_i, 1].max
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
class ImageBody < Body
|
66
|
+
FORMATS = Hash[*Magick.formats.select { |key, value| value.include? 'w' }.map do |key, value|
|
67
|
+
extension = key.downcase
|
68
|
+
MIME::Types.of(extension).select { |type| type.media_type == "image" }.map do |type|
|
69
|
+
Mime::Type.register type.to_s, extension unless Mime::Type.lookup_by_extension extension
|
70
|
+
[type.to_s, key]
|
71
|
+
end
|
72
|
+
end.flatten.compact].freeze
|
73
|
+
|
74
|
+
TYPES = FORMATS.keys.freeze
|
75
|
+
|
76
|
+
COLORS = {true => 0, false => Magick::QuantumRange}.freeze
|
77
|
+
|
78
|
+
def pixels
|
79
|
+
modules.flatten.map { |dark| COLORS[dark] }
|
80
|
+
end
|
81
|
+
|
82
|
+
def image
|
83
|
+
# "I" = greyscale integers
|
84
|
+
Magick::Image.constitute(width, height, "I", pixels).tap do |image|
|
85
|
+
image.format = FORMATS[type]
|
86
|
+
image.scale! scale unless scale == 1
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def each
|
91
|
+
yield image.to_blob
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
# ImageMagick doesn't generate well-formed SVG, and it uses circles (wtf), so we special-case it
|
96
|
+
class SvgBody < Body
|
97
|
+
COLORS = {true => "black", false => "white"}.freeze
|
98
|
+
|
99
|
+
def each
|
100
|
+
yield %{<?xml version="1.0" standalone="yes"?>}
|
101
|
+
yield %{<svg xmlns="http://www.w3.org/2000/svg" width="#{width * scale}" height="#{height * scale}">}
|
102
|
+
modules.each.with_index do |row, y|
|
103
|
+
row.each.with_index do |dark, x|
|
104
|
+
yield %{<rect width="#{scale}" height="#{scale}" x="#{x * scale}" y="#{y * scale}" style="fill:#{COLORS[dark]}"/>}
|
105
|
+
end
|
106
|
+
end
|
107
|
+
yield %{</svg>}
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/rqrcode/renderer/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.author = "Samuel Cochran"
|
6
|
+
gem.email = "sj26@sj26.com"
|
7
|
+
gem.description = gem.summary
|
8
|
+
gem.summary = %q{Render QR codes from Rails as images or SVG.}
|
9
|
+
gem.homepage = "https://github.com/sj26/rqrcode-renderer"
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.test_files = gem.files.grep(%r{^spec/})
|
13
|
+
gem.name = "rqrcode-renderer"
|
14
|
+
gem.require_paths = ["lib"]
|
15
|
+
gem.version = RQRCode::Renderer::VERSION
|
16
|
+
|
17
|
+
gem.add_dependency 'activesupport'
|
18
|
+
gem.add_dependency 'actionpack'
|
19
|
+
gem.add_dependency 'rqrcode'
|
20
|
+
gem.add_dependency 'rmagick'
|
21
|
+
gem.add_dependency 'mime-types'
|
22
|
+
end
|
metadata
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rqrcode-renderer
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Samuel Cochran
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-04-30 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: activesupport
|
16
|
+
requirement: &70146999303760 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70146999303760
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: actionpack
|
27
|
+
requirement: &70146999303000 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70146999303000
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rqrcode
|
38
|
+
requirement: &70146999302180 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :runtime
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70146999302180
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rmagick
|
49
|
+
requirement: &70146999301260 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :runtime
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *70146999301260
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: mime-types
|
60
|
+
requirement: &70146999300480 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
type: :runtime
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *70146999300480
|
69
|
+
description: ''
|
70
|
+
email: sj26@sj26.com
|
71
|
+
executables: []
|
72
|
+
extensions: []
|
73
|
+
extra_rdoc_files: []
|
74
|
+
files:
|
75
|
+
- .gitignore
|
76
|
+
- Gemfile
|
77
|
+
- LICENSE
|
78
|
+
- README.md
|
79
|
+
- Rakefile
|
80
|
+
- lib/rqrcode-renderer.rb
|
81
|
+
- lib/rqrcode/renderer.rb
|
82
|
+
- lib/rqrcode/renderer/version.rb
|
83
|
+
- rqrcode-renderer.gemspec
|
84
|
+
homepage: https://github.com/sj26/rqrcode-renderer
|
85
|
+
licenses: []
|
86
|
+
post_install_message:
|
87
|
+
rdoc_options: []
|
88
|
+
require_paths:
|
89
|
+
- lib
|
90
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
91
|
+
none: false
|
92
|
+
requirements:
|
93
|
+
- - ! '>='
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0'
|
96
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
requirements: []
|
103
|
+
rubyforge_project:
|
104
|
+
rubygems_version: 1.8.11
|
105
|
+
signing_key:
|
106
|
+
specification_version: 3
|
107
|
+
summary: Render QR codes from Rails as images or SVG.
|
108
|
+
test_files: []
|
109
|
+
has_rdoc:
|