imaginizer 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4b57552f3d3613d48fbe96a2d8271158d4c2e938
4
- data.tar.gz: 8addcc75730714e0c81e484fb1925177d1e311a3
3
+ metadata.gz: 82ba111cb40bc4ffde4bb54212a371ce849b7876
4
+ data.tar.gz: ec933dd1678bf6ee211d9989fb5fac39e4c8ad16
5
5
  SHA512:
6
- metadata.gz: 02d32e79e10a528aef27923c23bed3dfcb034a5faff8f0828e3241e6eb6a2bbed90bbe328b1ae1e000b7e44f2050c59a6373d8c9f21585d9f5cbb78e041bff9b
7
- data.tar.gz: 92340345dffea0b3bbaabba3dc067361954a1a731ee60d010949bf5acba3a3847002c58676584c408e1b4b69bbbd8afff4a4d011bbc899e812fa8e49e4d13ce5
6
+ metadata.gz: 286af7a8402b9a6b55737b36bc39be6ddf5b371bb02741f65660bdc10f371e85af9e44921b5d5dc5dfa40abec54ecd0f660733f8bacde92414aa9ab93e25295e
7
+ data.tar.gz: 378ccaf62c45a887f1f1cf7d8ab9c8855d46dd546caf6fce19429ee42ed0275044827a4f70d2b3ca4bd82715dd778d68bbb9f626700d63550a561c68624a863e
data/README.md CHANGED
@@ -11,7 +11,7 @@ You need [Imagemagick](http://www.imagemagick.org) with [Freetype](http://freety
11
11
 
12
12
  To check if you have it installed, run this command:
13
13
 
14
- check=`cosnvert -list CONFIGURE 2> /dev/null|grep DELEGATES|grep freetype|wc -l`; if [ $check -eq 1 ]; then echo "Imagemagick/Freetype IS installed"; else echo "Imagemagick/Freetype IS NOT installed"; fi
14
+ check=`convert -list CONFIGURE 2> /dev/null|grep DELEGATES|grep freetype|wc -l`; if [ $check -eq 1 ]; then echo "Imagemagick/Freetype IS installed"; else echo "Imagemagick/Freetype IS NOT installed"; fi
15
15
 
16
16
  To install:
17
17
 
@@ -9,9 +9,9 @@ end
9
9
 
10
10
  require 'imaginizer/parser'
11
11
 
12
- options = ImaginizerParser.parse ARGV
12
+ options = Imaginizer::Parser.parse ARGV
13
13
  output = options.delete :output
14
14
  puts "Creating images with #{options}:"
15
15
  images = Imaginizer.create_images options
16
16
  puts "Images created at #{images.map &:image_path}"
17
- ImaginizerParser.output images, output
17
+ Imaginizer::Parser.output images, output
@@ -1,137 +1,24 @@
1
- require 'mini_magick'
1
+ require 'imaginizer/image'
2
2
 
3
3
  module Imaginizer
4
4
  def self.create_images(options = {})
5
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
6
+ sizes.map {|size| create_image size, options}
10
7
  end
11
8
 
12
- def self.create_image(options = {})
13
- Image.create image_path(options) do |image|
9
+ def self.create_image(size, options = {})
10
+ Image.create size, image_path(size) do |image|
14
11
  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]
12
+ image.resize
13
+ image.set_background options[:background] if options[:background]
14
+ image.set_foreground options[:foreground] if options[:foreground]
18
15
  image.set_title options[:title] if options[:title]
19
16
  image.set_subtitle options[:subtitle] if options[:subtitle]
20
17
  image.set_footer options[:footer] if options[:footer]
21
18
  end
22
19
  end
23
20
 
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
21
+ def self.image_path(size)
22
+ "/tmp/#{size}.jpg"
136
23
  end
137
24
  end
@@ -0,0 +1,196 @@
1
+ require 'mini_magick'
2
+
3
+ class Imaginizer::Image
4
+ attr_accessor :image_data, :image_path, :image_size
5
+
6
+ def initialize(source_path = nil)
7
+ @image_data = MiniMagick::Image.open source_path || empty_image_path
8
+ end
9
+
10
+ def self.create(size, image_path)
11
+ new.tap do |image|
12
+ image.image_size = size
13
+ image.image_path = image_path
14
+ yield image
15
+ image.image_data.write image_path
16
+ end
17
+ end
18
+
19
+ def make_jpeg
20
+ @image_data.format 'jpg'
21
+ end
22
+
23
+ def resize
24
+ @image_data.resize "#{image_width}x#{image_height}!"
25
+ end
26
+
27
+ def set_background(options = {})
28
+ v = values_for :background
29
+ overlay_image options.merge(blur: '0x15', fill: true, x: v[:x],
30
+ y: v[:y], h: v[:h])
31
+ end
32
+
33
+ def set_foreground(options = {})
34
+ v = values_for :foreground
35
+ overlay_image options.merge(h: v[:h], w: v[:w]) unless v[:skip]
36
+ end
37
+
38
+ def set_title(options = {})
39
+ set_text :title, options do |v|
40
+ {style: 'bold', uppercase: true, x: v[:x], y: v[:y], size: v[:size]}
41
+ end
42
+ end
43
+
44
+ def set_subtitle(options = {})
45
+ set_text :subtitle, options do |v|
46
+ {style: 'italic', size: 14, x: v[:x], y: v[:y]}
47
+ end
48
+ end
49
+
50
+ def set_footer(options = {})
51
+ overlay_box values_for(:footer)
52
+ set_text :footer, options do |v|
53
+ {style: 'bold', uppercase: true, x: v[:x], y: v[:y], size: v[:size]}
54
+ end
55
+ end
56
+
57
+ protected
58
+
59
+ def blur(radius_x_sigma)
60
+ @image_data.combine_options {|c| c.blur radius_x_sigma} if radius_x_sigma
61
+ end
62
+
63
+ def crop(options = {})
64
+ return if options.none?
65
+ w = options[:w] || width
66
+ h = options[:h] || height
67
+ x_offset = (width - w)/2
68
+ y_offset = (height- h)/2
69
+ @image_data.crop "#{w}x#{h}+#{x_offset}+#{y_offset}"
70
+ end
71
+
72
+ private
73
+
74
+ def values_for(property)
75
+ {medium_rectangle: {
76
+ width: 300,
77
+ height: 250,
78
+ background: {y: 125, h: 125},
79
+ foreground: {h: 125},
80
+ title: {y: 23, second_line_y: 57, size: 40},
81
+ subtitle: {y: 84},
82
+ footer: {h: 30, size: 25, y: 111}
83
+ },
84
+ rectangle: {
85
+ width: 180,
86
+ height: 150,
87
+ foreground: {skip: true},
88
+ title: {y: -39, second_line_y: -12, size: 34},
89
+ subtitle: {y: 13},
90
+ footer: {h: 28, size: 16, y: 63}
91
+ },
92
+ wide_skyscraper: {
93
+ width: 160,
94
+ height: 600,
95
+ background: {y: 250, h: 125},
96
+ foreground: {h: 250},
97
+ title: {y: -23, second_line_y: 0, size: 30},
98
+ subtitle: {y: 33},
99
+ footer: {h: 94, size: 26, y: 242, second_line_y: 263}
100
+ },
101
+ leaderboard: {
102
+ width: 728,
103
+ height: 90,
104
+ background: {x: 228},
105
+ foreground: {w: 228},
106
+ title: {x: 120, y: -24, size: 42},
107
+ subtitle: {x: 120, y: 5},
108
+ footer: {w: 500, h: 29, size: 26, x: 120, y: 30}
109
+ }
110
+ }[@image_size].fetch property, {}
111
+ end
112
+
113
+ [:height, :width, :format].each do |method|
114
+ define_method method do
115
+ image_data[method]
116
+ end
117
+ end
118
+
119
+ def size
120
+ "#{width}x#{height}"
121
+ end
122
+
123
+ def image_width
124
+ values_for :width
125
+ end
126
+
127
+ def image_height
128
+ values_for :height
129
+ end
130
+
131
+ def set_text(size, options = {})
132
+ values = values_for size
133
+ size_options = options.merge yield(values)
134
+ if values[:second_line_y]
135
+ line1, line2 = word_wrap options[:text]
136
+ overlay_text size_options.merge(text: line1)
137
+ overlay_text size_options.merge(text: line2, y: values[:second_line_y])
138
+ else
139
+ overlay_text size_options
140
+ end
141
+ end
142
+
143
+ def word_wrap(text)
144
+ text.delete("\n").sub(/(.{1,9})(\s+|$)/, "\\1\n").strip.split("\n")
145
+ end
146
+
147
+ def overlay_text(options = {})
148
+ return unless text = options[:text]
149
+ text.upcase! if options[:uppercase]
150
+ @image_data.combine_options do |c|
151
+ c.fill 'white'
152
+ c.font font_path(options[:style])
153
+ c.gravity 'center'
154
+ c.pointsize options[:size] if options[:size]
155
+ c.draw "text #{options[:x] || 0},#{options[:y] || 0} '#{options[:text]}'"
156
+ end
157
+ end
158
+
159
+ def overlay_box(options = {})
160
+ return if options.none?
161
+ x2 = width
162
+ y2 = height
163
+ x1 = x2 - (options[:w] || x2)
164
+ y1 = y2 - (options[:h] || y2)
165
+ @image_data.combine_options do |c|
166
+ c.fill 'graya(0%, 0.5)'
167
+ c.draw "rectangle #{x1}, #{y1}, #{x2}, #{y2}"
168
+ end
169
+ end
170
+
171
+ def overlay_image(options = {})
172
+ return unless options[:img]
173
+ image = self.class.new options[:img]
174
+ image.blur options[:blur]
175
+
176
+ image.crop options
177
+ image.resize image_size if options[:fill]
178
+ overlay_x = options[:x] || 0
179
+ overlay_y = options[:y] || 0
180
+ @image_data = @image_data.composite image.image_data do |c|
181
+ c.geometry "#{image.width}x#{image.height}+#{overlay_x}+#{overlay_y}"
182
+ end
183
+ end
184
+
185
+
186
+
187
+ def empty_image_path
188
+ File.expand_path '../../assets/1x1.jpg', __FILE__
189
+ end
190
+
191
+ def font_path(style)
192
+ style ||= 'regular'
193
+ font_file = "../../assets/RobotoCondensed-#{style.capitalize}.ttf"
194
+ File.expand_path font_file, __FILE__
195
+ end
196
+ end
@@ -1,5 +1,11 @@
1
+ # coding: utf-8
1
2
  require 'optparse'
2
- class ImaginizerParser
3
+
4
+ class Imaginizer::Parser
5
+ def self.valid_sizes
6
+ [:medium_rectangle, :rectangle, :wide_skyscraper, :leaderboard]
7
+ end
8
+
3
9
  def self.parse(args)
4
10
  options = default_values
5
11
 
@@ -9,49 +15,38 @@ class ImaginizerParser
9
15
  opts.separator ''
10
16
  opts.separator 'Specific options:'
11
17
 
12
- opts.on('-d', '--dimension WxH', String, 'Image width x height') do |d|
18
+ opts.on('-d', '--dimension [IAB_SIZE]', valid_sizes,
19
+ %Q(Sizes to create #{valid_sizes} – multiple values accepted)) do |d|
13
20
  options[:sizes] << d
14
21
  end
15
- default_sizes = options.delete(:default_sizes)
16
- options[:sizes] = default_sizes if options[:sizes].empty?
17
22
 
18
- opts.on('-b', '--background path', String, 'Background image') do |path|
19
- options[:bg][:img] = path
23
+ opts.on('-b', '--background path', String,
24
+ %q(Background image – either a local path or a URL)) do |path|
25
+ options[:background][:img] = path
20
26
  end
21
27
 
22
- opts.on('-f', '--foreground path', String, 'Foreground image') do |path|
23
- options[:fg][:img] = path
28
+ opts.on('-f', '--foreground path', String,
29
+ %q(Foreground image – either a local path or a URL)) do |path|
30
+ options[:foreground][:img] = path
24
31
  end
25
32
 
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|
33
+ opts.on('-t', '--title text', String,
34
+ %q(Title to overlay – maximum 15 characters)) do |text|
31
35
  options[:title][:text] = text
32
36
  end
33
37
 
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|
38
+ opts.on('-s', '--subtitle text', String,
39
+ %q(Subtitle to overlay – maximum 15 characters)) do |text|
39
40
  options[:subtitle][:text] = text
40
41
  end
41
42
 
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|
43
+ opts.on('-r', '--footer text', String,
44
+ %q(Footer to overlay – maximum 20 characters)) do |text|
47
45
  options[:footer][:text] = text
48
46
  end
49
47
 
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|
48
+ opts.on('-o', '--output [OUTPUT]', [:image, :html],
49
+ %q(Output type – either an image or an HTML page)) do |o|
55
50
  options[:output] = o
56
51
  end
57
52
 
@@ -70,6 +65,8 @@ class ImaginizerParser
70
65
  end
71
66
 
72
67
  opt_parser.parse!(args)
68
+
69
+ options[:sizes] = self.valid_sizes if options[:sizes].empty?
73
70
  options
74
71
  end
75
72
 
@@ -77,12 +74,11 @@ class ImaginizerParser
77
74
  {}.tap do |opts|
78
75
  opts[:output] = :html
79
76
  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}
77
+ opts[:title] = {text: 'Title max 18 chars'}
78
+ opts[:subtitle] = {text: 'This subtitle is 30 characters'}
79
+ opts[:footer] = {text: 'A footer w/ 20 chars'}
80
+ opts[:background] = {img: 'http://lorempixel.com/300/300/abstract'}
81
+ opts[:foreground] = {img: 'http://lorempixel.com/300/300/people'}
86
82
  end
87
83
  end
88
84
 
@@ -98,13 +94,17 @@ class ImaginizerParser
98
94
  <html>
99
95
  <head>
100
96
  <meta charset="UTF-8" />
97
+ <style>
98
+ body {background-color: #ccc}
99
+ figure {float: left}
100
+ </style>
101
101
  <title>Imaginizer output</title>
102
102
  </head>
103
103
  <body>
104
104
  #{images.map do |image|
105
105
  '<figure>' +
106
106
  '<img src="' + image.image_path + '" />' +
107
- '<figcaption>Size: ' + image.size + '</figcaption>' +
107
+ '<figcaption>Size: ' + image.image_size.to_s + '</figcaption>' +
108
108
  '</figure>'
109
109
  end.join}
110
110
  </body>
@@ -1,3 +1,3 @@
1
1
  module Imaginizer
2
- VERSION = '0.0.2'
2
+ VERSION = '0.0.3'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: imaginizer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Claudio Baccigalupo
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-08-22 00:00:00.000000000 Z
12
+ date: 2013-08-26 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: mini_magick
@@ -123,6 +123,7 @@ files:
123
123
  - lib/assets/RobotoCondensed-Bold.ttf
124
124
  - lib/assets/RobotoCondensed-Italic.ttf
125
125
  - lib/assets/RobotoCondensed-Regular.ttf
126
+ - lib/imaginizer/image.rb
126
127
  - lib/imaginizer/parser.rb
127
128
  - lib/imaginizer/version.rb
128
129
  - lib/imaginizer.rb