imaginizer 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5f785f60e2c5ecffeb7a70fb74e10c83f06f4605
4
+ data.tar.gz: 0f68a4e28ef3cdfd4b4b4acd57ac812d4252b305
5
+ SHA512:
6
+ metadata.gz: 804f0bdce8fd34c718be7b653e949f2b8f00792690a2a1eb7d1a31d290a3563b35f2f953f86db479ff5698111e1667c4e6678b7743fd37c9e71d4a7c797042c5
7
+ data.tar.gz: 20d5fa5ec919fbe91f20f75b8f49eb225d23faebc7f9a4d65dd0b43f0add7284a8773b25301922a234be87464c57382065dccdc5c74fb5b00e083afb57a68db0
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2013 Topspin Media Inc.
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,24 @@
1
+ What is Imaginizer
2
+ ================
3
+
4
+ Create an image given a size and optional content
5
+
6
+ [![Build Status](https://travis-ci.org/topspin/imaginizer.png)](https://travis-ci.org/topspin/imaginizer)
7
+ [![Code Climate](https://codeclimate.com/github/topspin/imaginizer.png)](https://codeclimate.com/github/topspin/imaginizer)
8
+ [![Coverage Status](https://coveralls.io/repos/topspin/imaginizer/badge.png)](https://coveralls.io/r/topspin/imaginizer)
9
+ [![Dependency Status](https://gemnasium.com/topspin/imaginizer.png)](https://gemnasium.com/topspin/imaginizer)
10
+
11
+ Why Imaginizer was born
12
+ =====================
13
+
14
+ Requirements
15
+ ============
16
+
17
+ How to use from the command line
18
+ ================================
19
+
20
+ How to use from other programs
21
+ ==============================
22
+
23
+ How to contribute
24
+ =================
data/bin/imaginizer ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ begin
4
+ require 'imaginizer'
5
+ rescue LoadError
6
+ require 'rubygems'
7
+ require 'imaginizer'
8
+ end
9
+
10
+ require 'imaginizer/parser'
11
+
12
+ options = ImaginizerParser.parse ARGV
13
+ output = options.delete :output
14
+ puts "Creating images with #{options}:"
15
+ images = Imaginizer.create_images options
16
+ puts "Images created at #{images.map &:image_path}"
17
+ ImaginizerParser.output images, output
Binary file
Binary file
@@ -0,0 +1,117 @@
1
+ require 'optparse'
2
+ class ImaginizerParser
3
+ def self.parse(args)
4
+ options = default_values
5
+
6
+ opt_parser = OptionParser.new do |opts|
7
+ opts.banner = "Usage: #{File.basename($0)}"
8
+
9
+ opts.separator ''
10
+ opts.separator 'Specific options:'
11
+
12
+ opts.on('-d', '--dimension WxH', String, 'Image width x height') do |d|
13
+ options[:sizes] << d
14
+ end
15
+ default_sizes = options.delete(:default_sizes)
16
+ options[:sizes] = default_sizes if options[:sizes].empty?
17
+
18
+ opts.on('-b', '--background path', String, 'Background image') do |path|
19
+ options[:bg][:img] = path
20
+ end
21
+
22
+ opts.on('-f', '--foreground path', String, 'Foreground image') do |path|
23
+ options[:fg][:img] = path
24
+ end
25
+
26
+ opts.on('--foreground-height N', String, 'Foreground image height') do |n|
27
+ options[:fg][:height] = n
28
+ end
29
+
30
+ opts.on('-t', '--title text', String, 'Overlay title') do |text|
31
+ options[:title][:text] = text
32
+ end
33
+
34
+ opts.on('--title-size N', Integer, 'Title size') do |size|
35
+ options[:title][:size] = size
36
+ end
37
+
38
+ opts.on('-s', '--subtitle text', String, 'Overlay subtitle') do |text|
39
+ options[:subtitle][:text] = text
40
+ end
41
+
42
+ opts.on('--subtitle-size N', Integer, 'Subtitle size') do |size|
43
+ options[:subtitle][:size] = size
44
+ end
45
+
46
+ opts.on('-r', '--footer text', String, 'Overlay footer') do |text|
47
+ options[:footer][:text] = text
48
+ end
49
+
50
+ opts.on('--footer-size N', Integer, 'Footer size') do |size|
51
+ options[:footer][:size] = size
52
+ end
53
+
54
+ opts.on('-o', '--output [OUTPUT]', [:image, :html], 'What to show') do |o|
55
+ options[:output] = o
56
+ end
57
+
58
+ opts.separator ''
59
+ opts.separator 'Common options:'
60
+
61
+ opts.on_tail('-h', '--help', 'Show this message') do
62
+ puts opts
63
+ exit
64
+ end
65
+
66
+ opts.on_tail('--version', 'Show version') do
67
+ puts Imaginizer::VERSION
68
+ exit
69
+ end
70
+ end
71
+
72
+ opt_parser.parse!(args)
73
+ options
74
+ end
75
+
76
+ def self.default_values
77
+ {}.tap do |opts|
78
+ opts[:output] = :html
79
+ opts[:sizes] = []
80
+ opts[:default_sizes] = ['300x250', '180x150', '160x600', '728x90']
81
+ opts[:title] = {text: 'Sample title', size: 40}
82
+ opts[:subtitle] = {text: 'Sample subtitle', size: 14}
83
+ opts[:footer] = {text: 'Sample footer', size: 25}
84
+ opts[:bg] = {img: 'http://lorempixel.com/300/300/abstract'}
85
+ opts[:fg] = {img: 'http://lorempixel.com/300/300/people', height: 100}
86
+ end
87
+ end
88
+
89
+ def self.output(images, output)
90
+ case output
91
+ when :image
92
+ images.each {|image| `open #{image.image_path}`}
93
+ when :html
94
+ tmp_file = '/tmp/imaginizer.html'
95
+ File.open tmp_file, 'w' do |f|
96
+ f.write <<-HTML
97
+ <!DOCTYPE html>
98
+ <html>
99
+ <head>
100
+ <meta charset="UTF-8" />
101
+ <title>Imaginizer output</title>
102
+ </head>
103
+ <body>
104
+ #{images.map do |image|
105
+ '<figure>' +
106
+ '<img src="' + image.image_path + '" />' +
107
+ '<figcaption>Size: ' + image.size + '</figcaption>' +
108
+ '</figure>'
109
+ end.join}
110
+ </body>
111
+ </html>
112
+ HTML
113
+ end
114
+ `open #{tmp_file}`
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,3 @@
1
+ module Imaginizer
2
+ VERSION = '0.0.1'
3
+ end
data/lib/imaginizer.rb ADDED
@@ -0,0 +1,137 @@
1
+ require 'mini_magick'
2
+
3
+ module Imaginizer
4
+ def self.create_images(options = {})
5
+ sizes = options.delete(:sizes) { [] }
6
+ sizes.map do |size|
7
+ width, height = size.split 'x'
8
+ create_image options.merge(width: width, height: height)
9
+ end
10
+ end
11
+
12
+ def self.create_image(options = {})
13
+ Image.create image_path(options) do |image|
14
+ image.make_jpeg
15
+ image.resize options[:width], options[:height]
16
+ image.set_background options[:bg] if options[:bg]
17
+ image.overlay_image options[:fg] if options[:fg]
18
+ image.set_title options[:title] if options[:title]
19
+ image.set_subtitle options[:subtitle] if options[:subtitle]
20
+ image.set_footer options[:footer] if options[:footer]
21
+ end
22
+ end
23
+
24
+ def self.image_path(options)
25
+ basename = options.values_at(:width, :height).join('_')
26
+ "/tmp/#{basename}.jpg"
27
+ end
28
+
29
+ class Image
30
+ attr_accessor :image_data, :image_path
31
+
32
+ def initialize(source_path = nil)
33
+ @image_data = MiniMagick::Image.open source_path || empty_image_path
34
+ end
35
+
36
+ def self.create(image_path)
37
+ new.tap do |image|
38
+ image.image_path = image_path
39
+ yield image
40
+ image.image_data.write image_path
41
+ end
42
+ end
43
+
44
+ [:height, :width, :format].each do |method|
45
+ define_method method do
46
+ image_data[method]
47
+ end
48
+ end
49
+
50
+ def size
51
+ "#{width}x#{height}"
52
+ end
53
+
54
+ def make_jpeg
55
+ @image_data.format 'jpg'
56
+ end
57
+
58
+ def resize(w, h)
59
+ @image_data.resize "#{w}x#{h}!" if w and h
60
+ end
61
+
62
+ def crop(options = {})
63
+ return if options.none?
64
+ w = options[:width] || width
65
+ h = options[:height] || height
66
+ x_offset = (width - w)/2
67
+ y_offset = (height- h)/2
68
+ @image_data.crop "#{w}x#{h}+#{x_offset}+#{y_offset}"
69
+ end
70
+
71
+ def blur(radius_x_sigma)
72
+ @image_data.combine_options {|c| c.blur radius_x_sigma} if radius_x_sigma
73
+ end
74
+
75
+ def set_background(options = {})
76
+ overlay_image options.merge(blur: '0x15', fill: true)
77
+ end
78
+
79
+ def set_title(options = {})
80
+ overlay_text options.merge(uppercase: true)
81
+ end
82
+
83
+ def set_subtitle(options = {})
84
+ overlay_text options.merge(style: 'italic')
85
+ end
86
+
87
+ def set_footer(options = {})
88
+ overlay_box options.fetch(:box, {height: options[:size]})
89
+ overlay_text options.merge(style: 'bold', uppercase: true, gravity: 'south')
90
+ end
91
+
92
+ def overlay_text(options = {})
93
+ return unless text = options[:text]
94
+ text.upcase! if options[:uppercase]
95
+ @image_data.combine_options do |c|
96
+ c.fill 'white'
97
+ c.font font_path(options[:style])
98
+ c.gravity options.fetch(:gravity, 'center')
99
+ c.pointsize options[:size] if options[:size]
100
+ c.draw "text 0,0 '#{options[:text]}'"
101
+ end
102
+ end
103
+
104
+ def overlay_box(options = {})
105
+ return if options.none?
106
+ x2 = width
107
+ y2 = height
108
+ x1 = x2 - (options[:width] || x2)
109
+ y1 = y2 - (options[:height] || y2)
110
+ @image_data.combine_options do |c|
111
+ c.fill 'graya(0%, 0.5)'
112
+ c.draw "rectangle #{x1}, #{y1}, #{x2}, #{y2}"
113
+ end
114
+ end
115
+
116
+ def overlay_image(options = {})
117
+ return unless options[:img]
118
+ image = Image.new options[:img]
119
+ image.blur options[:blur]
120
+ image.crop height: options[:height]
121
+ image.resize width, height if options[:fill]
122
+ @image_data = @image_data.composite image.image_data
123
+ end
124
+
125
+ private
126
+
127
+ def empty_image_path
128
+ File.expand_path '../assets/1x1.jpg', __FILE__
129
+ end
130
+
131
+ def font_path(style)
132
+ style ||= 'regular'
133
+ font_file = "../assets/RobotoCondensed-#{style.capitalize}.ttf"
134
+ File.expand_path font_file, __FILE__
135
+ end
136
+ end
137
+ end
metadata ADDED
@@ -0,0 +1,158 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: imaginizer
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Claudio Baccigalupo
8
+ - Mike Durnhofer
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-08-22 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: mini_magick
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - '>='
19
+ - !ruby/object:Gem::Version
20
+ version: '0'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - '>='
26
+ - !ruby/object:Gem::Version
27
+ version: '0'
28
+ - !ruby/object:Gem::Dependency
29
+ name: bundler
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ~>
33
+ - !ruby/object:Gem::Version
34
+ version: '1.3'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ~>
40
+ - !ruby/object:Gem::Version
41
+ version: '1.3'
42
+ - !ruby/object:Gem::Dependency
43
+ name: rake
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - '>='
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: rspec
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - '>='
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: redcarpet
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - '>='
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ - !ruby/object:Gem::Dependency
85
+ name: yard
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - '>='
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - '>='
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ - !ruby/object:Gem::Dependency
99
+ name: coveralls
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - '>='
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ type: :development
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - '>='
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ description: Create an image given a size and optional content
113
+ email:
114
+ - claudio@topspinmedia.com
115
+ - mike@topspinmedia.com
116
+ executables:
117
+ - imaginizer
118
+ extensions: []
119
+ extra_rdoc_files: []
120
+ files:
121
+ - bin/imaginizer
122
+ - lib/assets/1x1.jpg
123
+ - lib/assets/RobotoCondensed-Bold.ttf
124
+ - lib/assets/RobotoCondensed-Italic.ttf
125
+ - lib/assets/RobotoCondensed-Regular.ttf
126
+ - lib/imaginizer/parser.rb
127
+ - lib/imaginizer/version.rb
128
+ - lib/imaginizer.rb
129
+ - MIT-LICENSE
130
+ - README.md
131
+ homepage: https://github.com/topspin/imaginizer
132
+ licenses:
133
+ - MIT
134
+ metadata: {}
135
+ post_install_message:
136
+ rdoc_options: []
137
+ require_paths:
138
+ - lib
139
+ required_ruby_version: !ruby/object:Gem::Requirement
140
+ requirements:
141
+ - - '>='
142
+ - !ruby/object:Gem::Version
143
+ version: 1.9.0
144
+ required_rubygems_version: !ruby/object:Gem::Requirement
145
+ requirements:
146
+ - - '>='
147
+ - !ruby/object:Gem::Version
148
+ version: '0'
149
+ requirements: []
150
+ rubyforge_project:
151
+ rubygems_version: 2.0.3
152
+ signing_key:
153
+ specification_version: 4
154
+ summary: Combines a title, subtitle and footer into an image, together with a background
155
+ and foreground images. Allows multiple images to be created at once, in different
156
+ sizes.
157
+ test_files: []
158
+ has_rdoc: