dragonfly 0.3.6 → 0.3.7
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of dragonfly might be problematic. Click here for more details.
- data/.yardopts +1 -0
- data/README.md +1 -1
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/dragonfly.gemspec +3 -2
- data/extra_docs/ExampleUseCases.md +17 -0
- data/features/steps/dragonfly_steps.rb +3 -3
- data/features/support/env.rb +5 -0
- data/lib/dragonfly/parameters.rb +2 -2
- data/lib/dragonfly/processing/r_magick_processor.rb +130 -14
- data/spec/dragonfly/processing/rmagick_processor_spec.rb +225 -131
- data/spec/spec_helper.rb +5 -0
- metadata +3 -2
data/.yardopts
CHANGED
data/README.md
CHANGED
@@ -42,7 +42,7 @@ View (to display):
|
|
42
42
|
<%= image_tag @album.cover_image.url('400x200') %>
|
43
43
|
<%= image_tag @album.cover_image.url('100x100!', :png) %>
|
44
44
|
<%= image_tag @album.cover_image.url('100x100#') %>
|
45
|
-
<%= image_tag @album.cover_image.url('50x50+30+30sw', :
|
45
|
+
<%= image_tag @album.cover_image.url('50x50+30+30sw', :tiff) %>
|
46
46
|
<%= image_tag @album.cover_image.url(:rotate, 15) %>
|
47
47
|
...etc.
|
48
48
|
|
data/Rakefile
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.3.
|
1
|
+
0.3.7
|
data/dragonfly.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{dragonfly}
|
8
|
-
s.version = "0.3.
|
8
|
+
s.version = "0.3.7"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Mark Evans"]
|
12
|
-
s.date = %q{
|
12
|
+
s.date = %q{2010-01-02}
|
13
13
|
s.email = %q{mark@new-bamboo.co.uk}
|
14
14
|
s.extra_rdoc_files = [
|
15
15
|
"LICENSE",
|
@@ -30,6 +30,7 @@ Gem::Specification.new do |s|
|
|
30
30
|
"extra_docs/Analysers.md",
|
31
31
|
"extra_docs/DataStorage.md",
|
32
32
|
"extra_docs/Encoding.md",
|
33
|
+
"extra_docs/ExampleUseCases.md",
|
33
34
|
"extra_docs/GettingStarted.md",
|
34
35
|
"extra_docs/Index.md",
|
35
36
|
"extra_docs/Processing.md",
|
@@ -0,0 +1,17 @@
|
|
1
|
+
Example Use Cases
|
2
|
+
=================
|
3
|
+
|
4
|
+
Image thumbnails in Rails
|
5
|
+
-------------------------
|
6
|
+
|
7
|
+
Rails thumbnails on Heroku with S3
|
8
|
+
----------------------------------
|
9
|
+
|
10
|
+
Serving attachments with no processing
|
11
|
+
--------------------------------------
|
12
|
+
|
13
|
+
Generating test data
|
14
|
+
--------------------
|
15
|
+
|
16
|
+
Text image replacement
|
17
|
+
----------------------
|
@@ -43,15 +43,15 @@ Then /the response should have mime-type '(.+?)'/ do |mime_type|
|
|
43
43
|
@response.headers['Content-Type'].should == mime_type
|
44
44
|
end
|
45
45
|
|
46
|
-
Then
|
46
|
+
Then /^the image should have width '(.+?)'$/ do |width|
|
47
47
|
@response.body.should have_width(width.to_i)
|
48
48
|
end
|
49
49
|
|
50
|
-
Then
|
50
|
+
Then /^the image should have height '(.+?)'$/ do |height|
|
51
51
|
@response.body.should have_height(height.to_i)
|
52
52
|
end
|
53
53
|
|
54
|
-
Then
|
54
|
+
Then /^the image should have format '(.+?)'$/ do |format|
|
55
55
|
@response.body.should have_format(format)
|
56
56
|
end
|
57
57
|
|
data/features/support/env.rb
CHANGED
@@ -5,6 +5,11 @@ require 'test/unit/assertions'
|
|
5
5
|
require 'ruby-debug'
|
6
6
|
require File.dirname(__FILE__) + '/../../spec/image_matchers.rb'
|
7
7
|
|
8
|
+
# A hack as system calls weren't using my path
|
9
|
+
extra_paths = %w(/opt/local/bin)
|
10
|
+
ENV['PATH'] ||= ''
|
11
|
+
ENV['PATH'] += ':' + extra_paths.join(':')
|
12
|
+
|
8
13
|
# A hash of <name for reference> => <dragonfly uid> pairs
|
9
14
|
TEMP_FILES = {}
|
10
15
|
|
data/lib/dragonfly/parameters.rb
CHANGED
@@ -154,8 +154,8 @@ module Dragonfly
|
|
154
154
|
uid,
|
155
155
|
format,
|
156
156
|
processing_method,
|
157
|
-
processing_options.sort{|a,b| a[
|
158
|
-
encoding.sort{|a,b| a[
|
157
|
+
processing_options.sort{|a,b| a[0].to_s <=> b[0].to_s },
|
158
|
+
encoding.sort{|a,b| a[0].to_s <=> b[0].to_s }
|
159
159
|
]
|
160
160
|
end
|
161
161
|
|
@@ -5,7 +5,7 @@ module Dragonfly
|
|
5
5
|
|
6
6
|
class RMagickProcessor < Base
|
7
7
|
|
8
|
-
|
8
|
+
GRAVITIES = {
|
9
9
|
'nw' => Magick::NorthWestGravity,
|
10
10
|
'n' => Magick::NorthGravity,
|
11
11
|
'ne' => Magick::NorthEastGravity,
|
@@ -17,10 +17,65 @@ module Dragonfly
|
|
17
17
|
'se' => Magick::SouthEastGravity
|
18
18
|
}
|
19
19
|
|
20
|
+
FONT_STYLES = {
|
21
|
+
'normal' => Magick::NormalStyle,
|
22
|
+
'italic' => Magick::ItalicStyle,
|
23
|
+
'oblique' => Magick::ObliqueStyle
|
24
|
+
}
|
25
|
+
|
26
|
+
FONT_STRETCHES = {
|
27
|
+
'normal' => Magick::NormalStretch,
|
28
|
+
'semi-condensed' => Magick::SemiCondensedStretch,
|
29
|
+
'condensed' => Magick::CondensedStretch,
|
30
|
+
'extra-condensed' => Magick::ExtraCondensedStretch,
|
31
|
+
'ultra-condensed' => Magick::UltraCondensedStretch,
|
32
|
+
'semi-expanded' => Magick::SemiExpandedStretch,
|
33
|
+
'expanded' => Magick::ExpandedStretch,
|
34
|
+
'extra-expanded' => Magick::ExtraExpandedStretch,
|
35
|
+
'ultra-expanded' => Magick::UltraExpandedStretch
|
36
|
+
}
|
37
|
+
|
38
|
+
FONT_WEIGHTS = {
|
39
|
+
'normal' => Magick::NormalWeight,
|
40
|
+
'bold' => Magick::BoldWeight,
|
41
|
+
'bolder' => Magick::BolderWeight,
|
42
|
+
'lighter' => Magick::LighterWeight,
|
43
|
+
'100' => 100,
|
44
|
+
'200' => 200,
|
45
|
+
'300' => 300,
|
46
|
+
'400' => 400,
|
47
|
+
'500' => 500,
|
48
|
+
'600' => 600,
|
49
|
+
'700' => 700,
|
50
|
+
'800' => 800,
|
51
|
+
'900' => 900
|
52
|
+
}
|
53
|
+
|
54
|
+
# HashWithCssStyleKeys is solely for being able to access a hash
|
55
|
+
# which has css-style keys (e.g. 'font-size') with the underscore
|
56
|
+
# symbol version
|
57
|
+
# @example
|
58
|
+
# opts = {'font-size' => '23px', :color => 'white'}
|
59
|
+
# opts = HashWithCssStyleKeys[opts]
|
60
|
+
# opts[:font_size] # ===> '23px'
|
61
|
+
# opts[:color] # ===> 'white'
|
62
|
+
class HashWithCssStyleKeys < Hash
|
63
|
+
def [](key)
|
64
|
+
super || (
|
65
|
+
str_key = key.to_s
|
66
|
+
css_key = str_key.gsub('_','-')
|
67
|
+
super(str_key) || super(css_key) || super(css_key.to_sym)
|
68
|
+
)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
# Processing methods
|
74
|
+
|
20
75
|
def crop(temp_object, opts={})
|
21
76
|
x = opts[:x].to_i
|
22
77
|
y = opts[:y].to_i
|
23
|
-
gravity =
|
78
|
+
gravity = GRAVITIES[opts[:gravity]] || Magick::ForgetGravity
|
24
79
|
width = opts[:width].to_i
|
25
80
|
height = opts[:height].to_i
|
26
81
|
|
@@ -34,17 +89,9 @@ module Dragonfly
|
|
34
89
|
image.crop(gravity, x, y, width, height).to_blob
|
35
90
|
end
|
36
91
|
|
37
|
-
def generate(width, height)
|
38
|
-
image = Magick::Image.
|
39
|
-
|
40
|
-
args = []
|
41
|
-
num_points.times do
|
42
|
-
args << rand(width)
|
43
|
-
args << rand(height)
|
44
|
-
args << "rgb(#{rand(256)},#{rand(256)},#{rand(256)})"
|
45
|
-
end
|
46
|
-
image = image.sparse_color(Magick::ShepardsColorInterpolate, *args)
|
47
|
-
image.format = 'png'
|
92
|
+
def generate(width, height, format='png')
|
93
|
+
image = Magick::Image.read("plasma:fractal"){self.size = "#{width}x#{height}"}.first
|
94
|
+
image.format = format.to_s
|
48
95
|
image.to_blob
|
49
96
|
end
|
50
97
|
|
@@ -59,7 +106,7 @@ module Dragonfly
|
|
59
106
|
|
60
107
|
width = opts[:width] ? opts[:width].to_i : image.columns
|
61
108
|
height = opts[:height] ? opts[:height].to_i : image.rows
|
62
|
-
gravity =
|
109
|
+
gravity = GRAVITIES[opts[:gravity]] || Magick::CenterGravity
|
63
110
|
|
64
111
|
image.crop_resized(width, height, gravity).to_blob
|
65
112
|
end
|
@@ -77,6 +124,52 @@ module Dragonfly
|
|
77
124
|
temp_object
|
78
125
|
end
|
79
126
|
end
|
127
|
+
|
128
|
+
def text(temp_object, opts={})
|
129
|
+
opts = HashWithCssStyleKeys[opts]
|
130
|
+
|
131
|
+
draw = Magick::Draw.new
|
132
|
+
draw.gravity = Magick::CenterGravity
|
133
|
+
draw.text_antialias = true
|
134
|
+
|
135
|
+
# Settings
|
136
|
+
draw.font = opts[:font] if opts[:font]
|
137
|
+
draw.font_family = opts[:font_family] if opts[:font_family]
|
138
|
+
draw.pointsize = opts[:font_size].to_f if opts[:font_size]
|
139
|
+
draw.fill = opts[:color] if opts[:color]
|
140
|
+
draw.stroke = opts[:stroke_color] if opts[:stroke_color]
|
141
|
+
draw.font_style = FONT_STYLES[opts[:font_style]] if opts[:font_style]
|
142
|
+
draw.font_stretch = FONT_STRETCHES[opts[:font_stretch]] if opts[:font_stretch]
|
143
|
+
draw.font_weight = FONT_WEIGHTS[opts[:font_weight]] if opts[:font_weight]
|
144
|
+
|
145
|
+
text = temp_object.data
|
146
|
+
|
147
|
+
# Calculate dimensions
|
148
|
+
metrics = draw.get_type_metrics(text)
|
149
|
+
width, height = metrics.width, metrics.height
|
150
|
+
|
151
|
+
pt, pr, pb, pl = parse_padding_string(opts[:padding]) if opts[:padding]
|
152
|
+
padding_top = opts[:padding_top] || pt || 0
|
153
|
+
padding_right = opts[:padding_right] || pr || 0
|
154
|
+
padding_bottom = opts[:padding_bottom] || pb || 0
|
155
|
+
padding_left = opts[:padding_left] || pl || 0
|
156
|
+
|
157
|
+
# Hack - for small font sizes, the width seems to be affected by rounding errors
|
158
|
+
padding_right += 2
|
159
|
+
|
160
|
+
total_width = padding_left + width + padding_right
|
161
|
+
total_height = padding_top + height + padding_bottom
|
162
|
+
|
163
|
+
# Draw the background
|
164
|
+
image = Magick::Image.new(total_width, total_height){
|
165
|
+
self.background_color = opts[:background_color] || 'transparent'
|
166
|
+
}
|
167
|
+
# Draw the text
|
168
|
+
draw.annotate(image, width, height, padding_left, padding_top, text)
|
169
|
+
# Output image as string
|
170
|
+
image.format = 'png'
|
171
|
+
image.to_blob
|
172
|
+
end
|
80
173
|
|
81
174
|
def vignette(temp_object, opts={})
|
82
175
|
x = opts[:x].to_f || temp_object.width * 0.1
|
@@ -93,6 +186,29 @@ module Dragonfly
|
|
93
186
|
Magick::Image.from_blob(temp_object.data).first
|
94
187
|
end
|
95
188
|
|
189
|
+
# Use css-style padding declaration, i.e.
|
190
|
+
# 10 (all sides)
|
191
|
+
# 10 5 (top/bottom, left/right)
|
192
|
+
# 10 5 10 (top, left/right, bottom)
|
193
|
+
# 10 5 10 5 (top, right, bottom, left)
|
194
|
+
def parse_padding_string(str)
|
195
|
+
padding_parts = str.gsub('px','').split(/\s+/).map{|px| px.to_i}
|
196
|
+
case padding_parts.size
|
197
|
+
when 1
|
198
|
+
p = *padding_parts
|
199
|
+
[p,p,p,p]
|
200
|
+
when 2
|
201
|
+
p,q = *padding_parts
|
202
|
+
[p,q,p,q]
|
203
|
+
when 3
|
204
|
+
p,q,r = *padding_parts
|
205
|
+
[p,q,r,q]
|
206
|
+
when 4
|
207
|
+
padding_parts
|
208
|
+
else raise ArgumentError, "Couldn't parse padding string '#{str}' - should be a css-style string"
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
96
212
|
end
|
97
213
|
|
98
214
|
end
|
@@ -2,174 +2,268 @@ require File.dirname(__FILE__) + '/../../spec_helper'
|
|
2
2
|
|
3
3
|
describe Dragonfly::Processing::RMagickProcessor do
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
@processor = Dragonfly::Processing::RMagickProcessor.new
|
9
|
-
end
|
10
|
-
|
11
|
-
describe "#resize" do
|
12
|
-
|
13
|
-
it "should work correctly with xNN" do
|
14
|
-
image = @processor.resize(@image, :geometry => 'x30')
|
15
|
-
image.should have_width(24)
|
16
|
-
image.should have_height(30)
|
5
|
+
describe "generate" do
|
6
|
+
before(:each) do
|
7
|
+
@processor = Dragonfly::Processing::RMagickProcessor.new
|
17
8
|
end
|
18
9
|
|
19
|
-
it "should
|
20
|
-
image = @processor.
|
21
|
-
image.should have_width(
|
22
|
-
image.should have_height(
|
10
|
+
it "should generate an image with the given dimensions, defaulting to png format" do
|
11
|
+
image = @processor.generate(23,12)
|
12
|
+
image.should have_width(23)
|
13
|
+
image.should have_height(12)
|
14
|
+
image.should have_format('png')
|
23
15
|
end
|
24
|
-
|
25
|
-
|
26
|
-
image
|
27
|
-
image.should have_width(24)
|
28
|
-
image.should have_height(30)
|
16
|
+
it "should allow specifying the format" do
|
17
|
+
image = @processor.generate(23, 12, :gif)
|
18
|
+
image.should have_format('gif')
|
29
19
|
end
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "processing methods" do
|
23
|
+
|
24
|
+
before(:each) do
|
25
|
+
sample_file = File.dirname(__FILE__) + '/../../../samples/beach.png' # 280x355
|
26
|
+
@image = Dragonfly::TempObject.new(File.new(sample_file))
|
27
|
+
@processor = Dragonfly::Processing::RMagickProcessor.new
|
35
28
|
end
|
29
|
+
|
30
|
+
describe "resize" do
|
36
31
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
32
|
+
it "should work correctly with xNN" do
|
33
|
+
image = @processor.resize(@image, :geometry => 'x30')
|
34
|
+
image.should have_width(24)
|
35
|
+
image.should have_height(30)
|
36
|
+
end
|
42
37
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
image
|
47
|
-
image.should have_width(280)
|
48
|
-
image.should have_height(355)
|
38
|
+
it "should work correctly with NNx" do
|
39
|
+
image = @processor.resize(@image, :geometry => '30x')
|
40
|
+
image.should have_width(30)
|
41
|
+
image.should have_height(38)
|
49
42
|
end
|
50
|
-
|
51
|
-
it "should
|
52
|
-
image = @processor.resize(@image, :geometry => '30x30
|
43
|
+
|
44
|
+
it "should work correctly with NNxNN" do
|
45
|
+
image = @processor.resize(@image, :geometry => '30x30')
|
53
46
|
image.should have_width(24)
|
54
47
|
image.should have_height(30)
|
55
48
|
end
|
56
|
-
|
57
|
-
end
|
58
49
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
image
|
63
|
-
|
64
|
-
|
50
|
+
it "should work correctly with NNxNN!" do
|
51
|
+
image = @processor.resize(@image, :geometry => '30x30!')
|
52
|
+
image.should have_width(30)
|
53
|
+
image.should have_height(30)
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should work correctly with NNxNN%" do
|
57
|
+
image = @processor.resize(@image, :geometry => '25x50%')
|
58
|
+
image.should have_width(70)
|
59
|
+
image.should have_height(178)
|
65
60
|
end
|
61
|
+
|
62
|
+
describe "NNxNN>" do
|
63
|
+
|
64
|
+
it "should not resize if the image is smaller than specified" do
|
65
|
+
image = @processor.resize(@image, :geometry => '1000x1000>')
|
66
|
+
image.should have_width(280)
|
67
|
+
image.should have_height(355)
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should resize if the image is larger than specified" do
|
71
|
+
image = @processor.resize(@image, :geometry => '30x30>')
|
72
|
+
image.should have_width(24)
|
73
|
+
image.should have_height(30)
|
74
|
+
end
|
66
75
|
|
67
|
-
it "should resize if the image is smaller than specified" do
|
68
|
-
image = @processor.resize(@image, :geometry => '400x400<')
|
69
|
-
image.should have_width(315)
|
70
|
-
image.should have_height(400)
|
71
76
|
end
|
77
|
+
|
78
|
+
describe "NNxNN<" do
|
72
79
|
|
73
|
-
|
80
|
+
it "should not resize if the image is larger than specified" do
|
81
|
+
image = @processor.resize(@image, :geometry => '10x10<')
|
82
|
+
image.should have_width(280)
|
83
|
+
image.should have_height(355)
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should resize if the image is smaller than specified" do
|
87
|
+
image = @processor.resize(@image, :geometry => '400x400<')
|
88
|
+
image.should have_width(315)
|
89
|
+
image.should have_height(400)
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
74
93
|
|
75
|
-
|
94
|
+
end
|
76
95
|
|
77
|
-
|
96
|
+
describe "crop" do # Difficult to test here other than dimensions
|
78
97
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
98
|
+
it "should not crop if no args given" do
|
99
|
+
image = @processor.crop(@image)
|
100
|
+
image.should have_width(280)
|
101
|
+
image.should have_height(355)
|
102
|
+
end
|
84
103
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
104
|
+
it "should crop using the offset given" do
|
105
|
+
image = @processor.crop(@image, :x => '7', :y => '12')
|
106
|
+
image.should have_width(273)
|
107
|
+
image.should have_height(343)
|
108
|
+
end
|
90
109
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
110
|
+
it "should crop using the dimensions given" do
|
111
|
+
image = @processor.crop(@image, :width => '10', :height => '20')
|
112
|
+
image.should have_width(10)
|
113
|
+
image.should have_height(20)
|
114
|
+
end
|
96
115
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
116
|
+
it "should crop in one dimension if given" do
|
117
|
+
image = @processor.crop(@image, :width => '10')
|
118
|
+
image.should have_width(10)
|
119
|
+
image.should have_height(355)
|
120
|
+
end
|
102
121
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
122
|
+
it "should take into account the gravity given" do
|
123
|
+
image1 = @processor.crop(@image, :width => '10', :height => '10', :gravity => 'nw')
|
124
|
+
image2 = @processor.crop(@image, :width => '10', :height => '10', :gravity => 'se')
|
125
|
+
image1.should_not == image2
|
126
|
+
end
|
108
127
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
128
|
+
it "should clip bits of the image outside of the requested crop area when not nw gravity" do
|
129
|
+
# Rmagick was previously throwing an error when the cropping area was outside the image size, when
|
130
|
+
# using a gravity other than nw
|
131
|
+
image = @processor.crop(@image, :width => '500', :height => '1000', :x => '100', :y => '200', :gravity => 'se')
|
132
|
+
image.should have_width(180)
|
133
|
+
image.should have_height(155)
|
134
|
+
end
|
116
135
|
|
117
|
-
|
136
|
+
end
|
118
137
|
|
119
|
-
|
138
|
+
describe "resize_and_crop" do
|
120
139
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
140
|
+
it "should do nothing if no args given" do
|
141
|
+
image = @processor.resize_and_crop(@image)
|
142
|
+
image.should have_width(280)
|
143
|
+
image.should have_height(355)
|
144
|
+
end
|
126
145
|
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
146
|
+
it "should crop to the correct dimensions" do
|
147
|
+
image = @processor.resize_and_crop(@image, :width => '100', :height => '100')
|
148
|
+
image.should have_width(100)
|
149
|
+
image.should have_height(100)
|
150
|
+
end
|
132
151
|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
152
|
+
it "should allow cropping in one dimension" do
|
153
|
+
image = @processor.resize_and_crop(@image, :width => '100')
|
154
|
+
image.should have_width(100)
|
155
|
+
image.should have_height(355)
|
156
|
+
end
|
138
157
|
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
158
|
+
it "should take into account the gravity given" do
|
159
|
+
image1 = @processor.resize_and_crop(@image, :width => '10', :height => '10', :gravity => 'nw')
|
160
|
+
image2 = @processor.resize_and_crop(@image, :width => '10', :height => '10', :gravity => 'se')
|
161
|
+
image1.should_not == image2
|
162
|
+
end
|
144
163
|
|
145
|
-
|
164
|
+
end
|
146
165
|
|
147
|
-
|
166
|
+
describe "rotate" do
|
148
167
|
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
168
|
+
it "should rotate by 90 degrees" do
|
169
|
+
image = @processor.rotate(@image, :amount => '90')
|
170
|
+
image.should have_width(355)
|
171
|
+
image.should have_height(280)
|
172
|
+
end
|
154
173
|
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
174
|
+
it "should not rotate given a larger height and the '>' qualifier" do
|
175
|
+
image = @processor.rotate(@image, :amount => 90, :qualifier => '>')
|
176
|
+
image.should have_width(280)
|
177
|
+
image.should have_height(355)
|
178
|
+
end
|
160
179
|
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
180
|
+
it "should rotate given a larger height and the '<' qualifier" do
|
181
|
+
image = @processor.rotate(@image, :amount => 90, :qualifier => '<')
|
182
|
+
image.should have_width(355)
|
183
|
+
image.should have_height(280)
|
184
|
+
end
|
166
185
|
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
186
|
+
it "should do nothing if no amount given" do
|
187
|
+
image = @processor.rotate(@image)
|
188
|
+
image.should have_width(280)
|
189
|
+
image.should have_height(355)
|
190
|
+
end
|
172
191
|
|
192
|
+
end
|
193
|
+
|
194
|
+
describe "text" do
|
195
|
+
before(:each) do
|
196
|
+
@text = Dragonfly::TempObject.new("mmm")
|
197
|
+
end
|
198
|
+
|
199
|
+
it "should create a text image, defaulted to png" do
|
200
|
+
image = @processor.text(@text)
|
201
|
+
image.should have_width(34)
|
202
|
+
image.should have_height(14)
|
203
|
+
image.should have_format('png')
|
204
|
+
end
|
205
|
+
|
206
|
+
# it "should ignore percent characters used by rmagick"
|
207
|
+
|
208
|
+
describe "padding" do
|
209
|
+
it "1 number shortcut" do
|
210
|
+
image = @processor.text(@text, :padding => '10')
|
211
|
+
image.should have_width(54)
|
212
|
+
image.should have_height(34)
|
213
|
+
end
|
214
|
+
it "2 numbers shortcut" do
|
215
|
+
image = @processor.text(@text, :padding => '10 5')
|
216
|
+
image.should have_width(44)
|
217
|
+
image.should have_height(34)
|
218
|
+
end
|
219
|
+
it "3 numbers shortcut" do
|
220
|
+
image = @processor.text(@text, :padding => '10 5 8')
|
221
|
+
image.should have_width(44)
|
222
|
+
image.should have_height(32)
|
223
|
+
end
|
224
|
+
it "4 numbers shortcut" do
|
225
|
+
image = @processor.text(@text, :padding => '1 2 3 4')
|
226
|
+
image.should have_width(40)
|
227
|
+
image.should have_height(18)
|
228
|
+
end
|
229
|
+
it "should override the general padding declaration with the specific one (e.g. 'padding-left')" do
|
230
|
+
image = @processor.text(@text, :padding => '10', 'padding-left' => 9)
|
231
|
+
image.should have_width(53)
|
232
|
+
image.should have_height(34)
|
233
|
+
end
|
234
|
+
it "should ignore 'px' suffixes" do
|
235
|
+
image = @processor.text(@text, :padding => '1px 2px 3px 4px')
|
236
|
+
image.should have_width(40)
|
237
|
+
image.should have_height(18)
|
238
|
+
end
|
239
|
+
it "bad padding string" do
|
240
|
+
lambda{
|
241
|
+
@processor.text(@text, :padding => '1 2 3 4 5')
|
242
|
+
}.should raise_error(ArgumentError)
|
243
|
+
end
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
173
247
|
end
|
174
248
|
|
175
249
|
end
|
250
|
+
|
251
|
+
describe Dragonfly::Processing::RMagickProcessor::HashWithCssStyleKeys do
|
252
|
+
before(:each) do
|
253
|
+
@hash = Dragonfly::Processing::RMagickProcessor::HashWithCssStyleKeys[
|
254
|
+
:font_style => 'normal',
|
255
|
+
:'font-weight' => 'bold',
|
256
|
+
'font_colour' => 'white',
|
257
|
+
'font-size' => 23,
|
258
|
+
:hello => 'there'
|
259
|
+
]
|
260
|
+
end
|
261
|
+
describe "accessing using underscore symbol style" do
|
262
|
+
it{ @hash[:font_style].should == 'normal' }
|
263
|
+
it{ @hash[:font_weight].should == 'bold' }
|
264
|
+
it{ @hash[:font_colour].should == 'white' }
|
265
|
+
it{ @hash[:font_size].should == 23 }
|
266
|
+
it{ @hash[:hello].should == 'there' }
|
267
|
+
it{ @hash[:non_existent_key].should be_nil }
|
268
|
+
end
|
269
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -8,6 +8,11 @@ require 'argument_matchers'
|
|
8
8
|
require 'simple_matchers'
|
9
9
|
require 'image_matchers'
|
10
10
|
|
11
|
+
# A hack as system calls weren't using my path
|
12
|
+
extra_paths = %w(/opt/local/bin)
|
13
|
+
ENV['PATH'] ||= ''
|
14
|
+
ENV['PATH'] += ':' + extra_paths.join(':')
|
15
|
+
|
11
16
|
SAMPLES_DIR = File.expand_path(File.dirname(__FILE__) + '/../samples') unless defined?(SAMPLES_DIR)
|
12
17
|
|
13
18
|
Spec::Runner.configure do |config|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dragonfly
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mark Evans
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date:
|
12
|
+
date: 2010-01-02 00:00:00 +00:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -46,6 +46,7 @@ files:
|
|
46
46
|
- extra_docs/Analysers.md
|
47
47
|
- extra_docs/DataStorage.md
|
48
48
|
- extra_docs/Encoding.md
|
49
|
+
- extra_docs/ExampleUseCases.md
|
49
50
|
- extra_docs/GettingStarted.md
|
50
51
|
- extra_docs/Index.md
|
51
52
|
- extra_docs/Processing.md
|