image_voodoo 0.8.7 → 0.9.1
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 +17 -0
- data/Gemfile +5 -0
- data/Jars.lock +3 -0
- data/LICENSE-2.0.txt +202 -0
- data/README.exif +18 -0
- data/README.md +1 -0
- data/Rakefile +21 -0
- data/bin/image_voodoo +81 -72
- 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 +177 -124
- data/lib/image_voodoo/gae.rb +12 -6
- data/lib/image_voodoo/metadata.rb +1689 -0
- data/lib/image_voodoo/needs_head.rb +3 -0
- data/lib/image_voodoo/version.rb +3 -1
- data/lib/image_voodoo.rb +77 -90
- 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 +65 -0
- data/test/test_shapes.rb +23 -0
- data/tools/gen.rb +68 -0
- metadata +94 -7
data/lib/image_voodoo/version.rb
CHANGED
data/lib/image_voodoo.rb
CHANGED
@@ -1,5 +1,13 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Before we load image_voodoo we can specify whether we want it to load full
|
4
|
+
# AWT ala http://www.oracle.com/technetwork/articles/javase/headless-136834.html
|
5
|
+
# Most users are using image_voodoo as a library for manipulation and do not
|
6
|
+
# want a full peer window popping up.
|
7
|
+
unless defined? ImageVoodoo::NEEDS_HEAD
|
8
|
+
java.lang.System.set_property 'java.awt.headless', 'true'
|
9
|
+
end
|
10
|
+
|
3
11
|
# = ImageVoodoo
|
4
12
|
# == Description
|
5
13
|
#
|
@@ -24,261 +32,240 @@
|
|
24
32
|
#
|
25
33
|
# img = ImageVoodoo.with_image(ARGV[0])
|
26
34
|
# negative_img = img.negative
|
27
|
-
#
|
28
35
|
class ImageVoodoo
|
29
|
-
|
36
|
+
attr_writer :quality # used by quality(value)
|
30
37
|
|
31
38
|
include Java
|
32
39
|
|
33
40
|
JFile = java.io.File
|
34
41
|
|
35
|
-
##
|
36
42
|
# FIXME: This has an issue when used in test/unit where the classcastexception
|
37
43
|
# is throwing the stack trace to output. This does not happen when used
|
38
44
|
# directly. Not sure....
|
39
45
|
# gae and awt define the technology-specific methods and more importantly
|
40
46
|
# all the *_impl methods which you will see referenced in this file.
|
41
47
|
begin
|
42
|
-
|
48
|
+
require 'image_voodoo/gae'
|
43
49
|
rescue
|
44
|
-
|
50
|
+
require 'image_voodoo/awt'
|
45
51
|
end
|
46
52
|
|
47
|
-
def initialize(src, format=nil)
|
48
|
-
@src = src
|
49
|
-
@format = format
|
53
|
+
def initialize(io, src, format=nil)
|
54
|
+
@io, @src, @format = io, src, format
|
50
55
|
@quality = nil # nil means no specific quality ever specified
|
51
56
|
end
|
52
57
|
|
53
|
-
|
54
|
-
#
|
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
|
+
|
55
65
|
# Adjusts the brightness of each pixel in image by the following formula:
|
56
66
|
# new_pixel = pixel * scale + offset
|
57
|
-
#
|
58
67
|
def adjust_brightness(scale, offset)
|
59
68
|
image = guard { adjust_brightness_impl(scale, offset) }
|
60
69
|
block_given? ? yield(image) : image
|
61
70
|
end
|
62
71
|
|
63
|
-
##
|
64
|
-
#
|
65
72
|
# Converts rgb hex color value to an alpha value an yields/returns the new
|
66
73
|
# image.
|
67
|
-
#
|
68
74
|
def alpha(rgb)
|
69
75
|
target = guard { alpha_impl(rgb) }
|
70
76
|
block_given? ? yield(target) : target
|
71
77
|
end
|
72
78
|
|
73
|
-
##
|
74
|
-
#
|
75
79
|
# Get current image bytes as a String using provided format. Format parameter
|
76
80
|
# is the informal name of an image type - for instance,
|
77
81
|
# "bmp" or "jpg". If the backend is AWT the types available are listed in
|
78
82
|
# javax.imageio.ImageIO.getWriterFormatNames()
|
79
|
-
#
|
80
83
|
def bytes(format)
|
81
84
|
java_bytes = guard { bytes_impl(format) }
|
82
85
|
String.from_java_bytes java_bytes
|
83
86
|
end
|
84
87
|
|
85
|
-
|
86
|
-
#
|
88
|
+
# If current image was taken by a phone it might save the orientation
|
89
|
+
# in format it was physically taken and added IFD0 Orientation information
|
90
|
+
# instead of rotating it. This method will perform that rotation based
|
91
|
+
# on Orientation metadata.
|
92
|
+
def correct_orientation
|
93
|
+
target = guard { correct_orientation_impl }
|
94
|
+
block_given? ? yield(target) : target
|
95
|
+
end
|
96
|
+
|
87
97
|
# Creates a square thumbnail of the image cropping the longest edge to
|
88
98
|
# match the shortest edge, resizes to size, and yields/returns the new image.
|
89
|
-
#
|
90
99
|
def cropped_thumbnail(size)
|
91
|
-
l, t, r, b
|
92
|
-
l, r = half, half + height if width > height
|
93
|
-
t, b = half, half + width if height > width
|
94
|
-
|
100
|
+
l, t, r, b = calculate_thumbnail_dimensions
|
95
101
|
target = with_crop(l, t, r, b).thumbnail(size)
|
96
102
|
block_given? ? yield(target) : target
|
97
103
|
end
|
98
104
|
|
99
|
-
|
100
|
-
|
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
|
+
|
101
114
|
# Flips the image horizontally and yields/returns the new image.
|
102
|
-
#
|
103
115
|
def flip_horizontally
|
104
116
|
target = guard { flip_horizontally_impl }
|
105
117
|
block_given? ? yield(target) : target
|
106
118
|
end
|
107
119
|
|
108
|
-
##
|
109
|
-
#
|
110
120
|
# Flips the image vertically and yields/returns the new image.
|
111
|
-
#
|
112
121
|
def flip_vertically
|
113
122
|
target = guard { flip_vertically_impl }
|
114
123
|
block_given? ? yield(target) : target
|
115
124
|
end
|
116
125
|
|
117
|
-
##
|
118
|
-
#
|
119
126
|
# Creates a grayscale version of image and yields/returns the new image.
|
120
|
-
#
|
121
127
|
def greyscale
|
122
128
|
target = guard { greyscale_impl }
|
123
129
|
block_given? ? yield(target) : target
|
124
130
|
end
|
125
|
-
|
131
|
+
alias grayscale greyscale
|
132
|
+
|
133
|
+
# Extracts metadata from an image.
|
134
|
+
def metadata
|
135
|
+
guard { metadata_impl }
|
136
|
+
end
|
126
137
|
|
127
|
-
##
|
128
|
-
#
|
129
138
|
# Creates a negative and yields/returns the new image.
|
130
|
-
#
|
131
139
|
def negative
|
132
140
|
target = guard { negative_impl }
|
133
141
|
block_given? ? yield(target) : target
|
134
142
|
end
|
135
143
|
|
136
|
-
##
|
137
|
-
#
|
138
144
|
# Set quality you want resulting image to be once you save or extract
|
139
145
|
# bytes for the image. Note: This will only work for lossy image
|
140
146
|
# formats like PNG of JPEG. For others it will be ignored.
|
141
147
|
def quality(amount)
|
142
148
|
if amount < 0.0 || amount > 1.0
|
143
|
-
raise ArgumentError
|
149
|
+
raise ArgumentError, 'Quality must be between 0.0 and 1.0'
|
144
150
|
end
|
145
151
|
|
146
|
-
target =
|
152
|
+
target = dup
|
147
153
|
target.quality = amount
|
148
154
|
block_given? ? yield(target) : target
|
149
155
|
end
|
150
156
|
|
151
|
-
##
|
152
|
-
#
|
153
157
|
# Resizes the image to width and height and yields/returns the new image.
|
154
|
-
#
|
155
158
|
def resize(width, height)
|
156
159
|
target = guard { resize_impl(width, height) }
|
157
160
|
block_given? ? yield(target) : target
|
158
|
-
rescue
|
159
|
-
raise ArgumentError,
|
161
|
+
rescue java.lang.Exception => e # figure out why this is here at all?
|
162
|
+
raise ArgumentError, e.message
|
163
|
+
end
|
164
|
+
|
165
|
+
# Rotates the image by angle (specified in degrees).
|
166
|
+
def rotate(angle)
|
167
|
+
target = guard { rotate_impl(to_radians(angle)) }
|
168
|
+
block_given? ? yield(target) : target
|
160
169
|
end
|
161
170
|
|
162
|
-
##
|
163
|
-
#
|
164
171
|
# Saves the image out to path. Changing the file extension will convert
|
165
172
|
# the file type to the appropriate format.
|
166
|
-
#
|
167
173
|
def save(file)
|
168
174
|
format = File.extname(file)
|
169
|
-
return false if format ==
|
175
|
+
return false if format == ''
|
176
|
+
|
170
177
|
format = format[1..-1].downcase
|
171
178
|
guard { save_impl(format, JFile.new(file)) }
|
172
179
|
true
|
173
180
|
end
|
174
181
|
|
175
|
-
##
|
176
|
-
#
|
177
182
|
# Resize (scale) the current image by the provided ratio and yield/return
|
178
183
|
# the new image.
|
179
|
-
#
|
180
184
|
def scale(ratio)
|
181
185
|
new_width, new_height = (width * ratio).to_i, (height * ratio).to_i
|
182
186
|
target = resize(new_width, new_height)
|
183
187
|
block_given? ? yield(target) : target
|
184
188
|
end
|
185
189
|
|
186
|
-
##
|
187
|
-
#
|
188
190
|
# Creates a proportional thumbnail of the image scaled so its longest
|
189
191
|
# edge is resized to size and yields/returns the new image.
|
190
|
-
#
|
191
192
|
def thumbnail(size)
|
192
193
|
target = scale(size.to_f / (width > height ? width : height))
|
193
194
|
block_given? ? yield(target) : target
|
194
195
|
end
|
195
196
|
|
196
|
-
##
|
197
|
-
#
|
198
197
|
# Crops an image to left, top, right, and bottom and then yields/returns the
|
199
198
|
# new image.
|
200
|
-
#
|
201
199
|
def with_crop(left, top, right, bottom)
|
202
200
|
image = guard { with_crop_impl(left, top, right, bottom) }
|
203
201
|
block_given? ? yield(image) : image
|
204
202
|
end
|
205
203
|
|
206
|
-
|
207
|
-
|
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
|
+
|
208
210
|
# A top-level image loader opens path and then yields/returns the image.
|
209
|
-
#
|
210
211
|
def self.with_image(path)
|
211
|
-
raise ArgumentError, "file does not exist" unless File.file?(path)
|
212
|
+
raise ArgumentError, "file does not exist: #{path}" unless File.file?(path)
|
213
|
+
|
212
214
|
image = guard { with_image_impl(JFile.new(path)) }
|
213
215
|
image && block_given? ? yield(image) : image
|
214
216
|
end
|
215
217
|
|
216
|
-
##
|
217
|
-
#
|
218
218
|
# A top-level image loader reads bytes and then yields/returns the image.
|
219
|
-
#
|
220
219
|
def self.with_bytes(bytes)
|
221
|
-
bytes = bytes.to_java_bytes if String
|
220
|
+
bytes = bytes.to_java_bytes if bytes.is_a? String
|
222
221
|
image = guard { with_bytes_impl(bytes) }
|
223
222
|
block_given? ? yield(image) : image
|
224
223
|
end
|
225
224
|
|
226
225
|
class << self
|
227
|
-
|
226
|
+
alias with_image_from_memory with_bytes
|
228
227
|
end
|
229
228
|
|
230
|
-
##
|
231
|
-
#
|
232
229
|
# *_impl providers only need provide the implementation if it can
|
233
230
|
# support it. Otherwise, this method will detect that the method is
|
234
231
|
# missing.
|
235
|
-
#
|
236
232
|
def self.guard(&block)
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
"Unimplemented Feature: #{e}"
|
241
|
-
end
|
233
|
+
block.call
|
234
|
+
rescue NoMethodError => e
|
235
|
+
"Unimplemented Feature: #{e}"
|
242
236
|
end
|
237
|
+
|
243
238
|
def guard(&block)
|
244
239
|
ImageVoodoo.guard(&block)
|
245
240
|
end
|
246
241
|
|
247
|
-
##
|
248
|
-
#
|
249
242
|
# Returns the height of the image, in pixels.
|
250
|
-
#
|
251
243
|
def height
|
252
244
|
@src.height
|
253
245
|
end
|
254
246
|
|
255
|
-
##
|
256
|
-
#
|
257
247
|
# Returns the width of the image, in pixels.
|
258
|
-
#
|
259
248
|
def width
|
260
249
|
@src.width
|
261
250
|
end
|
262
251
|
|
263
|
-
##
|
264
|
-
#
|
265
252
|
# Returns the underlying Java class associated with this object. Note:
|
266
253
|
# Depending on whether you are using AWT or GAE/J you will get a totally
|
267
254
|
# different Java class. So caveat emptor!
|
268
|
-
#
|
269
255
|
def to_java
|
270
256
|
@src
|
271
257
|
end
|
272
258
|
|
273
|
-
##
|
274
|
-
#
|
275
259
|
# Returns detected image format from binary representation of input data
|
276
260
|
# as upper case string. Eg. JPEG, BMP, PNG. For GWT image representation
|
277
261
|
# compatibility method name is :format. It also accepts block and returns
|
278
262
|
# format as first block argument. When format not detected or not set it
|
279
263
|
# returns nil
|
280
|
-
#
|
281
264
|
def format
|
282
265
|
@format && block_given? ? yield(@format) : @format
|
283
266
|
end
|
267
|
+
|
268
|
+
def to_radians(degrees)
|
269
|
+
degrees * Math::PI / 180
|
270
|
+
end
|
284
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
|