image_voodoo 0.8.8 → 0.9.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +4 -0
- data/.rubocop.yml +165 -0
- data/.travis.yml +16 -1
- data/Gemfile +5 -0
- data/Jars.lock +3 -0
- data/Rakefile +14 -4
- data/bin/image_voodoo +73 -84
- data/image_voodoo.gemspec +14 -7
- data/lib/image_science.rb +3 -1
- data/lib/image_voodoo/awt/core_ext/buffered_image.rb +15 -0
- data/lib/image_voodoo/awt/core_ext/graphics2d.rb +15 -0
- data/lib/image_voodoo/awt/shapes.rb +41 -3
- data/lib/image_voodoo/awt.rb +162 -152
- data/lib/image_voodoo/gae.rb +12 -6
- data/lib/image_voodoo/metadata.rb +138 -90
- data/lib/image_voodoo/needs_head.rb +3 -0
- data/lib/image_voodoo/version.rb +3 -1
- data/lib/image_voodoo.rb +47 -96
- data/samples/bench.rb +30 -36
- data/samples/file_greyscale.rb +2 -0
- data/samples/file_thumbnail.rb +2 -0
- data/samples/file_view.rb +4 -1
- data/samples/{in-memory.rb → in_memory.rb} +2 -0
- data/samples/lossy.rb +2 -0
- data/test/test_image_science.rb +34 -74
- data/test/test_image_voodoo.rb +84 -0
- data/test/test_metadata.rb +31 -16
- data/test/test_shapes.rb +23 -0
- data/tools/gen.rb +34 -27
- metadata +87 -10
- data/vendor/metadata-extractor-2.7.0.jar +0 -0
- data/vendor/xmpcore-5.1.2.jar +0 -0
data/lib/image_voodoo.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Before we load image_voodoo we can specify whether we want it to load full
|
2
4
|
# AWT ala http://www.oracle.com/technetwork/articles/javase/headless-136834.html
|
3
5
|
# Most users are using image_voodoo as a library for manipulation and do not
|
@@ -5,10 +7,7 @@
|
|
5
7
|
unless defined? ImageVoodoo::NEEDS_HEAD
|
6
8
|
java.lang.System.set_property 'java.awt.headless', 'true'
|
7
9
|
end
|
8
|
-
|
9
10
|
|
10
|
-
##
|
11
|
-
#
|
12
11
|
# = ImageVoodoo
|
13
12
|
# == Description
|
14
13
|
#
|
@@ -33,24 +32,22 @@ end
|
|
33
32
|
#
|
34
33
|
# img = ImageVoodoo.with_image(ARGV[0])
|
35
34
|
# negative_img = img.negative
|
36
|
-
#
|
37
35
|
class ImageVoodoo
|
38
|
-
|
36
|
+
attr_writer :quality # used by quality(value)
|
39
37
|
|
40
38
|
include Java
|
41
39
|
|
42
40
|
JFile = java.io.File
|
43
41
|
|
44
|
-
##
|
45
42
|
# FIXME: This has an issue when used in test/unit where the classcastexception
|
46
43
|
# is throwing the stack trace to output. This does not happen when used
|
47
44
|
# directly. Not sure....
|
48
45
|
# gae and awt define the technology-specific methods and more importantly
|
49
46
|
# all the *_impl methods which you will see referenced in this file.
|
50
47
|
begin
|
51
|
-
|
48
|
+
require 'image_voodoo/gae'
|
52
49
|
rescue
|
53
|
-
|
50
|
+
require 'image_voodoo/awt'
|
54
51
|
end
|
55
52
|
|
56
53
|
def initialize(io, src, format=nil)
|
@@ -58,263 +55,217 @@ class ImageVoodoo
|
|
58
55
|
@quality = nil # nil means no specific quality ever specified
|
59
56
|
end
|
60
57
|
|
61
|
-
|
62
|
-
#
|
58
|
+
# Gets RGB value within the source image at [x, y]. If using AWT backend
|
59
|
+
# then consider using color_at as this is a Java signed int value of an
|
60
|
+
# unsigned value.
|
61
|
+
def pixel(x, y)
|
62
|
+
@src.getRGB(x, y)
|
63
|
+
end
|
64
|
+
|
63
65
|
# Adjusts the brightness of each pixel in image by the following formula:
|
64
66
|
# new_pixel = pixel * scale + offset
|
65
|
-
#
|
66
67
|
def adjust_brightness(scale, offset)
|
67
68
|
image = guard { adjust_brightness_impl(scale, offset) }
|
68
69
|
block_given? ? yield(image) : image
|
69
70
|
end
|
70
71
|
|
71
|
-
##
|
72
|
-
#
|
73
72
|
# Converts rgb hex color value to an alpha value an yields/returns the new
|
74
73
|
# image.
|
75
|
-
#
|
76
74
|
def alpha(rgb)
|
77
75
|
target = guard { alpha_impl(rgb) }
|
78
76
|
block_given? ? yield(target) : target
|
79
77
|
end
|
80
78
|
|
81
|
-
##
|
82
|
-
#
|
83
79
|
# Get current image bytes as a String using provided format. Format parameter
|
84
80
|
# is the informal name of an image type - for instance,
|
85
81
|
# "bmp" or "jpg". If the backend is AWT the types available are listed in
|
86
82
|
# javax.imageio.ImageIO.getWriterFormatNames()
|
87
|
-
#
|
88
83
|
def bytes(format)
|
89
84
|
java_bytes = guard { bytes_impl(format) }
|
90
85
|
String.from_java_bytes java_bytes
|
91
86
|
end
|
92
87
|
|
93
|
-
##
|
94
88
|
# If current image was taken by a phone it might save the orientation
|
95
89
|
# in format it was physically taken and added IFD0 Orientation information
|
96
90
|
# instead of rotating it. This method will perform that rotation based
|
97
91
|
# on Orientation metadata.
|
98
|
-
#
|
99
92
|
def correct_orientation
|
100
93
|
target = guard { correct_orientation_impl }
|
101
94
|
block_given? ? yield(target) : target
|
102
95
|
end
|
103
96
|
|
104
|
-
##
|
105
|
-
#
|
106
97
|
# Creates a square thumbnail of the image cropping the longest edge to
|
107
98
|
# match the shortest edge, resizes to size, and yields/returns the new image.
|
108
|
-
#
|
109
99
|
def cropped_thumbnail(size)
|
110
|
-
l, t, r, b
|
111
|
-
l, r = half, half + height if width > height
|
112
|
-
t, b = half, half + width if height > width
|
113
|
-
|
100
|
+
l, t, r, b = calculate_thumbnail_dimensions
|
114
101
|
target = with_crop(l, t, r, b).thumbnail(size)
|
115
102
|
block_given? ? yield(target) : target
|
116
103
|
end
|
117
104
|
|
118
|
-
|
119
|
-
|
105
|
+
private def calculate_thumbnail_dimensions
|
106
|
+
half = (width - height).abs / 2
|
107
|
+
if width > height
|
108
|
+
[half, 0, half + height, height]
|
109
|
+
else
|
110
|
+
[0, half, width, half + width]
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
120
114
|
# Flips the image horizontally and yields/returns the new image.
|
121
|
-
#
|
122
115
|
def flip_horizontally
|
123
116
|
target = guard { flip_horizontally_impl }
|
124
117
|
block_given? ? yield(target) : target
|
125
118
|
end
|
126
119
|
|
127
|
-
##
|
128
|
-
#
|
129
120
|
# Flips the image vertically and yields/returns the new image.
|
130
|
-
#
|
131
121
|
def flip_vertically
|
132
122
|
target = guard { flip_vertically_impl }
|
133
123
|
block_given? ? yield(target) : target
|
134
124
|
end
|
135
125
|
|
136
|
-
##
|
137
|
-
#
|
138
126
|
# Creates a grayscale version of image and yields/returns the new image.
|
139
|
-
#
|
140
127
|
def greyscale
|
141
128
|
target = guard { greyscale_impl }
|
142
129
|
block_given? ? yield(target) : target
|
143
130
|
end
|
144
|
-
|
131
|
+
alias grayscale greyscale
|
145
132
|
|
146
|
-
##
|
147
|
-
#
|
148
133
|
# Extracts metadata from an image.
|
149
|
-
#
|
150
134
|
def metadata
|
151
135
|
guard { metadata_impl }
|
152
136
|
end
|
153
137
|
|
154
|
-
##
|
155
|
-
#
|
156
138
|
# Creates a negative and yields/returns the new image.
|
157
|
-
#
|
158
139
|
def negative
|
159
140
|
target = guard { negative_impl }
|
160
141
|
block_given? ? yield(target) : target
|
161
142
|
end
|
162
143
|
|
163
|
-
##
|
164
|
-
#
|
165
144
|
# Set quality you want resulting image to be once you save or extract
|
166
145
|
# bytes for the image. Note: This will only work for lossy image
|
167
146
|
# formats like PNG of JPEG. For others it will be ignored.
|
168
147
|
def quality(amount)
|
169
148
|
if amount < 0.0 || amount > 1.0
|
170
|
-
raise ArgumentError
|
149
|
+
raise ArgumentError, 'Quality must be between 0.0 and 1.0'
|
171
150
|
end
|
172
151
|
|
173
|
-
target =
|
152
|
+
target = dup
|
174
153
|
target.quality = amount
|
175
154
|
block_given? ? yield(target) : target
|
176
155
|
end
|
177
156
|
|
178
|
-
##
|
179
|
-
#
|
180
157
|
# Resizes the image to width and height and yields/returns the new image.
|
181
|
-
#
|
182
158
|
def resize(width, height)
|
183
159
|
target = guard { resize_impl(width, height) }
|
184
160
|
block_given? ? yield(target) : target
|
185
|
-
rescue
|
186
|
-
raise ArgumentError,
|
161
|
+
rescue java.lang.Exception => e # figure out why this is here at all?
|
162
|
+
raise ArgumentError, e.message
|
187
163
|
end
|
188
164
|
|
189
|
-
##
|
190
|
-
#
|
191
165
|
# Rotates the image by angle (specified in degrees).
|
192
|
-
#
|
193
166
|
def rotate(angle)
|
194
|
-
target = guard { rotate_impl(angle) }
|
167
|
+
target = guard { rotate_impl(to_radians(angle)) }
|
195
168
|
block_given? ? yield(target) : target
|
196
169
|
end
|
197
170
|
|
198
|
-
##
|
199
|
-
#
|
200
171
|
# Saves the image out to path. Changing the file extension will convert
|
201
172
|
# the file type to the appropriate format.
|
202
|
-
#
|
203
173
|
def save(file)
|
204
174
|
format = File.extname(file)
|
205
|
-
return false if format ==
|
175
|
+
return false if format == ''
|
176
|
+
|
206
177
|
format = format[1..-1].downcase
|
207
178
|
guard { save_impl(format, JFile.new(file)) }
|
208
179
|
true
|
209
180
|
end
|
210
181
|
|
211
|
-
##
|
212
|
-
#
|
213
182
|
# Resize (scale) the current image by the provided ratio and yield/return
|
214
183
|
# the new image.
|
215
|
-
#
|
216
184
|
def scale(ratio)
|
217
185
|
new_width, new_height = (width * ratio).to_i, (height * ratio).to_i
|
218
186
|
target = resize(new_width, new_height)
|
219
187
|
block_given? ? yield(target) : target
|
220
188
|
end
|
221
189
|
|
222
|
-
##
|
223
|
-
#
|
224
190
|
# Creates a proportional thumbnail of the image scaled so its longest
|
225
191
|
# edge is resized to size and yields/returns the new image.
|
226
|
-
#
|
227
192
|
def thumbnail(size)
|
228
193
|
target = scale(size.to_f / (width > height ? width : height))
|
229
194
|
block_given? ? yield(target) : target
|
230
195
|
end
|
231
196
|
|
232
|
-
##
|
233
|
-
#
|
234
197
|
# Crops an image to left, top, right, and bottom and then yields/returns the
|
235
198
|
# new image.
|
236
|
-
#
|
237
199
|
def with_crop(left, top, right, bottom)
|
238
200
|
image = guard { with_crop_impl(left, top, right, bottom) }
|
239
201
|
block_given? ? yield(image) : image
|
240
202
|
end
|
241
203
|
|
242
|
-
|
243
|
-
|
204
|
+
# Creates a new (empty) image with a file name specified.
|
205
|
+
def self.new_image(width, height, file_name)
|
206
|
+
image = guard { new_image_impl(width, height, file_name) }
|
207
|
+
block_given? ? yield(image) : image
|
208
|
+
end
|
209
|
+
|
244
210
|
# A top-level image loader opens path and then yields/returns the image.
|
245
|
-
#
|
246
211
|
def self.with_image(path)
|
247
212
|
raise ArgumentError, "file does not exist: #{path}" unless File.file?(path)
|
213
|
+
|
248
214
|
image = guard { with_image_impl(JFile.new(path)) }
|
249
215
|
image && block_given? ? yield(image) : image
|
250
216
|
end
|
251
217
|
|
252
|
-
##
|
253
|
-
#
|
254
218
|
# A top-level image loader reads bytes and then yields/returns the image.
|
255
|
-
#
|
256
219
|
def self.with_bytes(bytes)
|
257
|
-
bytes = bytes.to_java_bytes if String
|
220
|
+
bytes = bytes.to_java_bytes if bytes.is_a? String
|
258
221
|
image = guard { with_bytes_impl(bytes) }
|
259
222
|
block_given? ? yield(image) : image
|
260
223
|
end
|
261
224
|
|
262
225
|
class << self
|
263
|
-
|
226
|
+
alias with_image_from_memory with_bytes
|
264
227
|
end
|
265
228
|
|
266
|
-
##
|
267
|
-
#
|
268
229
|
# *_impl providers only need provide the implementation if it can
|
269
230
|
# support it. Otherwise, this method will detect that the method is
|
270
231
|
# missing.
|
271
|
-
#
|
272
232
|
def self.guard(&block)
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
"Unimplemented Feature: #{e}"
|
277
|
-
end
|
233
|
+
block.call
|
234
|
+
rescue NoMethodError => e
|
235
|
+
"Unimplemented Feature: #{e}"
|
278
236
|
end
|
237
|
+
|
279
238
|
def guard(&block)
|
280
239
|
ImageVoodoo.guard(&block)
|
281
240
|
end
|
282
241
|
|
283
|
-
##
|
284
|
-
#
|
285
242
|
# Returns the height of the image, in pixels.
|
286
|
-
#
|
287
243
|
def height
|
288
244
|
@src.height
|
289
245
|
end
|
290
246
|
|
291
|
-
##
|
292
|
-
#
|
293
247
|
# Returns the width of the image, in pixels.
|
294
|
-
#
|
295
248
|
def width
|
296
249
|
@src.width
|
297
250
|
end
|
298
251
|
|
299
|
-
##
|
300
|
-
#
|
301
252
|
# Returns the underlying Java class associated with this object. Note:
|
302
253
|
# Depending on whether you are using AWT or GAE/J you will get a totally
|
303
254
|
# different Java class. So caveat emptor!
|
304
|
-
#
|
305
255
|
def to_java
|
306
256
|
@src
|
307
257
|
end
|
308
258
|
|
309
|
-
##
|
310
|
-
#
|
311
259
|
# Returns detected image format from binary representation of input data
|
312
260
|
# as upper case string. Eg. JPEG, BMP, PNG. For GWT image representation
|
313
261
|
# compatibility method name is :format. It also accepts block and returns
|
314
262
|
# format as first block argument. When format not detected or not set it
|
315
263
|
# returns nil
|
316
|
-
#
|
317
264
|
def format
|
318
265
|
@format && block_given? ? yield(@format) : @format
|
319
266
|
end
|
267
|
+
|
268
|
+
def to_radians(degrees)
|
269
|
+
degrees * Math::PI / 180
|
270
|
+
end
|
320
271
|
end
|
data/samples/bench.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
#!/usr/local/bin/ruby -w
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
4
|
require 'benchmark'
|
4
5
|
require 'rbconfig'
|
@@ -6,59 +7,52 @@ require 'rubygems'
|
|
6
7
|
require 'image_science'
|
7
8
|
|
8
9
|
max = (ARGV.shift || 100).to_i
|
9
|
-
ext = ARGV.shift ||
|
10
|
-
|
10
|
+
ext = ARGV.shift || 'png'
|
11
11
|
file = "blah_big.#{ext}"
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
13
|
+
unless File.exist?(file)
|
14
|
+
if RbConfig::CONFIG['host_os'] =~ /darwin/i
|
15
|
+
puts 'taking screenshot for thumbnailing benchmarks'
|
16
|
+
system "screencapture -SC #{file}"
|
17
|
+
elsif RbConfig::CONFIG['host_os'] =~ /linux/i
|
18
|
+
puts 'taking screenshot for thumbnailing benchmarks'
|
19
|
+
system "gnome-screenshot -f #{file}"
|
20
|
+
else
|
21
|
+
abort "You need to save an image to #{file} since we cannot generate one"
|
22
|
+
end
|
23
|
+
end
|
20
24
|
|
21
|
-
|
22
|
-
img.save(file)
|
23
|
-
end
|
25
|
+
if ext != 'png'
|
26
|
+
ImageScience.with_image(file.sub(/#{ext}$/, 'png')) { |img| img.save(file) }
|
27
|
+
end
|
24
28
|
|
25
29
|
puts "# of iterations = #{max}"
|
26
|
-
Benchmark
|
27
|
-
x.report(
|
28
|
-
for i in 0..max do
|
29
|
-
# do nothing
|
30
|
-
end
|
31
|
-
}
|
30
|
+
Benchmark.bm(20) do |x|
|
31
|
+
x.report('null_time') { max.times {} }
|
32
32
|
|
33
|
-
x.report(
|
34
|
-
|
33
|
+
x.report('cropped') do
|
34
|
+
max.times do
|
35
35
|
ImageScience.with_image(file) do |img|
|
36
|
-
img.cropped_thumbnail(100)
|
37
|
-
thumb.save("blah_cropped.#{ext}")
|
38
|
-
end
|
36
|
+
img.cropped_thumbnail(100) { |thumb| thumb.save("blah_cropped.#{ext}") }
|
39
37
|
end
|
40
38
|
end
|
41
|
-
|
39
|
+
end
|
42
40
|
|
43
|
-
x.report(
|
44
|
-
|
41
|
+
x.report('proportional') do
|
42
|
+
max.times do
|
45
43
|
ImageScience.with_image(file) do |img|
|
46
|
-
img.thumbnail(100)
|
47
|
-
thumb.save("blah_thumb.#{ext}")
|
48
|
-
end
|
44
|
+
img.thumbnail(100) { |thumb| thumb.save("blah_thumb.#{ext}") }
|
49
45
|
end
|
50
46
|
end
|
51
|
-
|
47
|
+
end
|
52
48
|
|
53
|
-
x.report(
|
54
|
-
|
49
|
+
x.report('resize') do
|
50
|
+
max.times do
|
55
51
|
ImageScience.with_image(file) do |img|
|
56
|
-
img.resize(200, 200)
|
57
|
-
resize.save("blah_resize.#{ext}")
|
58
|
-
end
|
52
|
+
img.resize(200, 200) { |resize| resize.save("blah_resize.#{ext}") }
|
59
53
|
end
|
60
54
|
end
|
61
|
-
|
55
|
+
end
|
62
56
|
end
|
63
57
|
|
64
58
|
# File.unlink(*Dir["blah*#{ext}"])
|
data/samples/file_greyscale.rb
CHANGED
data/samples/file_thumbnail.rb
CHANGED
data/samples/file_view.rb
CHANGED
data/samples/lossy.rb
CHANGED
data/test/test_image_science.rb
CHANGED
@@ -1,9 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'test/unit/testcase'
|
2
|
-
require 'test/unit' if $
|
4
|
+
require 'test/unit' if $PROGRAM_NAME == __FILE__
|
3
5
|
require 'image_science'
|
4
6
|
|
5
7
|
class TestImageScience < Test::Unit::TestCase
|
6
|
-
def deny
|
8
|
+
def deny(x)
|
9
|
+
assert !x
|
10
|
+
end
|
11
|
+
|
12
|
+
def similar_image?(w, h, img)
|
13
|
+
assert_kind_of ImageScience, img
|
14
|
+
assert_equal h, img.height
|
15
|
+
assert_equal w, img.width
|
16
|
+
end
|
7
17
|
|
8
18
|
def setup
|
9
19
|
@path = 'test/pix.png'
|
@@ -17,118 +27,68 @@ class TestImageScience < Test::Unit::TestCase
|
|
17
27
|
|
18
28
|
def test_class_with_image
|
19
29
|
ImageScience.with_image @path do |img|
|
20
|
-
|
21
|
-
assert_equal @h, img.height
|
22
|
-
assert_equal @w, img.width
|
30
|
+
similar_image? @w, @h, img
|
23
31
|
assert img.save(@tmppath)
|
24
32
|
end
|
25
33
|
|
26
|
-
|
27
|
-
|
28
|
-
ImageScience.with_image @tmppath do |img|
|
29
|
-
assert_kind_of ImageScience, img
|
30
|
-
assert_equal @h, img.height
|
31
|
-
assert_equal @w, img.width
|
32
|
-
end
|
34
|
+
ImageScience.with_image(@tmppath) { |img| similar_image? @w, @h, img }
|
33
35
|
end
|
34
36
|
|
35
37
|
def test_class_with_image_missing
|
36
38
|
assert_raises ArgumentError do
|
37
|
-
ImageScience.with_image
|
38
|
-
flunk
|
39
|
-
end
|
39
|
+
ImageScience.with_image("#{@path}nope") { flunk }
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
43
|
def test_class_with_image_missing_with_img_extension
|
44
44
|
assert_raises ArgumentError do
|
45
|
-
ImageScience.with_image("nope#{@path}")
|
46
|
-
flunk
|
47
|
-
end
|
45
|
+
ImageScience.with_image("nope#{@path}") { flunk }
|
48
46
|
end
|
49
47
|
end
|
50
48
|
|
51
49
|
def test_class_with_image_return_nil_on_bogus_image
|
52
|
-
File.open(@tmppath,
|
53
|
-
assert_nil ImageScience.with_image(@tmppath)
|
54
|
-
flunk
|
55
|
-
end
|
50
|
+
File.open(@tmppath, 'w') { |f| f << 'bogus image file' }
|
51
|
+
assert_nil ImageScience.with_image(@tmppath) { flunk }
|
56
52
|
end
|
57
53
|
|
58
54
|
def test_resize
|
59
55
|
ImageScience.with_image @path do |img|
|
60
|
-
img.resize(25, 25)
|
61
|
-
assert thumb.save(@tmppath)
|
62
|
-
end
|
56
|
+
img.resize(25, 25) { |thumb| assert thumb.save(@tmppath) }
|
63
57
|
end
|
64
58
|
|
65
|
-
|
66
|
-
|
67
|
-
ImageScience.with_image @tmppath do |img|
|
68
|
-
assert_kind_of ImageScience, img
|
69
|
-
assert_equal 25, img.height
|
70
|
-
assert_equal 25, img.width
|
71
|
-
end
|
59
|
+
ImageScience.with_image(@tmppath) { |img| similar_image? 25, 25, img }
|
72
60
|
end
|
73
61
|
|
74
62
|
def test_resize_floats
|
75
63
|
ImageScience.with_image @path do |img|
|
76
|
-
img.resize(25.2, 25.7)
|
77
|
-
assert thumb.save(@tmppath)
|
78
|
-
end
|
64
|
+
img.resize(25.2, 25.7) { |thumb| assert thumb.save(@tmppath) }
|
79
65
|
end
|
80
66
|
|
81
|
-
|
82
|
-
|
83
|
-
ImageScience.with_image @tmppath do |img|
|
84
|
-
assert_kind_of ImageScience, img
|
85
|
-
assert_equal 25, img.height
|
86
|
-
assert_equal 25, img.width
|
87
|
-
end
|
67
|
+
ImageScience.with_image(@tmppath) { |img| similar_image? 25, 25, img }
|
88
68
|
end
|
89
69
|
|
90
70
|
def test_resize_zero
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
assert thumb.save(@tmppath)
|
71
|
+
[[0, 25], [25, 0], [0, 0]].each do |w, h|
|
72
|
+
assert_raises ArgumentError do
|
73
|
+
ImageScience.with_image @path do |img|
|
74
|
+
img.resize(w, h) { |thumb| assert thumb.save(@tmppath) }
|
95
75
|
end
|
96
76
|
end
|
97
|
-
end
|
98
77
|
|
99
|
-
|
100
|
-
|
101
|
-
assert_raises ArgumentError do
|
102
|
-
ImageScience.with_image @path do |img|
|
103
|
-
img.resize(25, 0) do |thumb|
|
104
|
-
assert thumb.save(@tmppath)
|
105
|
-
end
|
106
|
-
end
|
78
|
+
deny File.exist?(@tmppath)
|
107
79
|
end
|
108
|
-
|
109
|
-
deny File.exists?(@tmppath)
|
110
80
|
end
|
111
81
|
|
112
82
|
def test_resize_negative
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
assert thumb.save(@tmppath)
|
83
|
+
[[-25, 25], [25, -25], [-25, -25]].each do |w, h|
|
84
|
+
assert_raises ArgumentError do
|
85
|
+
ImageScience.with_image @path do |img|
|
86
|
+
img.resize(w, h) { |thumb| assert thumb.save(@tmppath) }
|
117
87
|
end
|
118
88
|
end
|
119
|
-
end
|
120
89
|
|
121
|
-
|
122
|
-
|
123
|
-
assert_raises ArgumentError do
|
124
|
-
ImageScience.with_image @path do |img|
|
125
|
-
img.resize(25, -25) do |thumb|
|
126
|
-
assert thumb.save(@tmppath)
|
127
|
-
end
|
128
|
-
end
|
90
|
+
deny File.exist?(@tmppath)
|
129
91
|
end
|
130
|
-
|
131
|
-
deny File.exists?(@tmppath)
|
132
92
|
end
|
133
93
|
|
134
94
|
def test_image_format_retrieval
|
@@ -147,7 +107,7 @@ class TestImageScience < Test::Unit::TestCase
|
|
147
107
|
end
|
148
108
|
|
149
109
|
def test_image_format_retrieval_fail_when_invalid_bytes
|
150
|
-
image = ImageScience.with_bytes(
|
110
|
+
image = ImageScience.with_bytes('some invalid image bytes')
|
151
111
|
assert_equal nil, image.format
|
152
112
|
end
|
153
113
|
|
@@ -166,6 +126,6 @@ class TestImageScience < Test::Unit::TestCase
|
|
166
126
|
assert new_img.save(@tmppath)
|
167
127
|
end
|
168
128
|
|
169
|
-
assert File.
|
129
|
+
assert File.exist?(@tmppath)
|
170
130
|
end
|
171
131
|
end
|