image_voodoo 0.8.8 → 0.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|