ruby-vips 0.3.14 → 1.0.0
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 +4 -4
- data/.travis.yml +22 -0
- data/CHANGELOG.md +4 -0
- data/Gemfile +15 -0
- data/Gemfile.lock +46 -31
- data/{LICENSE → LICENSE.txt} +1 -1
- data/README.md +101 -145
- data/Rakefile +45 -0
- data/TODO +8 -32
- data/VERSION +1 -0
- data/example/annotate.rb +17 -0
- data/example/daltonize8.rb +75 -0
- data/example/example1.rb +84 -0
- data/example/example2.rb +31 -0
- data/example/example3.rb +19 -0
- data/example/example4.rb +18 -0
- data/example/example5.rb +31 -0
- data/example/trim8.rb +41 -0
- data/example/watermark.rb +44 -0
- data/example/wobble.rb +36 -0
- data/lib/vips.rb +151 -14
- data/lib/vips/access.rb +14 -0
- data/lib/vips/align.rb +11 -0
- data/lib/vips/angle.rb +12 -0
- data/lib/vips/angle45.rb +16 -0
- data/lib/vips/argument.rb +163 -0
- data/lib/vips/bandformat.rb +20 -0
- data/lib/vips/call.rb +302 -0
- data/lib/vips/coding.rb +14 -0
- data/lib/vips/demandstyle.rb +35 -0
- data/lib/vips/direction.rb +11 -0
- data/lib/vips/error.rb +30 -0
- data/lib/vips/extend.rb +22 -0
- data/lib/vips/foreignflags.rb +20 -0
- data/lib/vips/image.rb +1382 -0
- data/lib/vips/interpolate.rb +37 -0
- data/lib/vips/interpretation.rb +28 -0
- data/lib/vips/methods.rb +1807 -0
- data/lib/vips/operation.rb +19 -0
- data/ruby-vips8.gemspec +112 -0
- data/spec/image_spec.rb +515 -0
- data/spec/samples/balloon.v +0 -0
- data/spec/samples/ghost.ppm +405 -0
- data/spec/samples/huge.jpg +0 -0
- data/spec/samples/icc.jpg +0 -0
- data/spec/samples/lcd.icc +0 -0
- data/spec/samples/lion.svg +154 -0
- data/spec/samples/sample.csv +7 -0
- data/spec/samples/sample.exr +0 -0
- data/spec/samples/wagon.jpg +0 -0
- data/spec/samples/wagon.v +0 -0
- data/spec/spec_helper.rb +49 -0
- data/spec/vips_spec.rb +74 -0
- metadata +110 -70
- data/ext/extconf.rb +0 -31
- data/ext/header.c +0 -457
- data/ext/header.h +0 -9
- data/ext/image.c +0 -629
- data/ext/image.h +0 -72
- data/ext/image_arithmetic.c +0 -936
- data/ext/image_arithmetic.h +0 -38
- data/ext/image_boolean.c +0 -301
- data/ext/image_boolean.h +0 -8
- data/ext/image_colour.c +0 -590
- data/ext/image_colour.h +0 -36
- data/ext/image_conversion.c +0 -884
- data/ext/image_conversion.h +0 -38
- data/ext/image_convolution.c +0 -368
- data/ext/image_convolution.h +0 -13
- data/ext/image_freq_filt.c +0 -740
- data/ext/image_freq_filt.h +0 -27
- data/ext/image_histograms_lut.c +0 -643
- data/ext/image_histograms_lut.h +0 -28
- data/ext/image_morphology.c +0 -327
- data/ext/image_morphology.h +0 -13
- data/ext/image_mosaicing.c +0 -554
- data/ext/image_mosaicing.h +0 -15
- data/ext/image_relational.c +0 -384
- data/ext/image_relational.h +0 -8
- data/ext/image_resample.c +0 -249
- data/ext/image_resample.h +0 -9
- data/ext/interpolator.c +0 -106
- data/ext/interpolator.h +0 -7
- data/ext/mask.c +0 -347
- data/ext/mask.h +0 -18
- data/ext/reader.c +0 -261
- data/ext/reader.h +0 -2
- data/ext/ruby_vips.c +0 -188
- data/ext/ruby_vips.h +0 -72
- data/ext/tags +0 -450
- data/ext/writer.c +0 -371
- data/ext/writer.h +0 -2
- data/lib/vips/reader.rb +0 -272
- data/lib/vips/version.rb +0 -3
- data/lib/vips/writer.rb +0 -342
- data/ruby-vips.gemspec +0 -100
- data/ruby.supp +0 -134
@@ -0,0 +1,19 @@
|
|
1
|
+
module Vips
|
2
|
+
|
3
|
+
# add a conventience method to Operation
|
4
|
+
# @private
|
5
|
+
class Operation
|
6
|
+
# Fetch arg list, remove boring ones, sort into priority order.
|
7
|
+
def get_args
|
8
|
+
gobject_class = gtype.to_class
|
9
|
+
props = gobject_class.properties.select do |name|
|
10
|
+
flags = get_argument_flags name
|
11
|
+
io = ((flags & :input) | (flags & :output)) != 0
|
12
|
+
dep = (flags & :deprecated) != 0
|
13
|
+
io & (not dep)
|
14
|
+
end
|
15
|
+
args = props.map {|name| Argument.new self, name}
|
16
|
+
args.sort! {|a, b| a.priority - b.priority}
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/ruby-vips8.gemspec
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
# stub: ruby-vips8 0.1.0 ruby lib
|
6
|
+
|
7
|
+
Gem::Specification.new do |s|
|
8
|
+
s.name = "ruby-vips8"
|
9
|
+
s.version = "0.1.0"
|
10
|
+
|
11
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
12
|
+
s.require_paths = ["lib"]
|
13
|
+
s.authors = ["John Cupitt"]
|
14
|
+
s.date = "2016-01-25"
|
15
|
+
s.description = "ruby-vips8 is a ruby extension for vips8. It is extremely fast and it can process huge images without requiring the entire image to be loaded into memory."
|
16
|
+
s.email = "jcupitt@gmail.com"
|
17
|
+
s.extra_rdoc_files = [
|
18
|
+
"LICENSE.txt",
|
19
|
+
"README.md",
|
20
|
+
"TODO"
|
21
|
+
]
|
22
|
+
s.files = [
|
23
|
+
".rspec",
|
24
|
+
".yardopts",
|
25
|
+
"CHANGELOG.md",
|
26
|
+
"Gemfile",
|
27
|
+
"Gemfile.lock",
|
28
|
+
"LICENSE.txt",
|
29
|
+
"README.md",
|
30
|
+
"Rakefile",
|
31
|
+
"TODO",
|
32
|
+
"VERSION",
|
33
|
+
"example/annotate.rb",
|
34
|
+
"example/daltonize8.rb",
|
35
|
+
"example/example1.rb",
|
36
|
+
"example/example2.rb",
|
37
|
+
"example/example3.rb",
|
38
|
+
"example/example4.rb",
|
39
|
+
"example/example5.rb",
|
40
|
+
"example/trim8.rb",
|
41
|
+
"example/watermark.rb",
|
42
|
+
"example/wobble.rb",
|
43
|
+
"lib/vips8.rb",
|
44
|
+
"lib/vips8/access.rb",
|
45
|
+
"lib/vips8/align.rb",
|
46
|
+
"lib/vips8/angle.rb",
|
47
|
+
"lib/vips8/angle45.rb",
|
48
|
+
"lib/vips8/argument.rb",
|
49
|
+
"lib/vips8/bandformat.rb",
|
50
|
+
"lib/vips8/call.rb",
|
51
|
+
"lib/vips8/coding.rb",
|
52
|
+
"lib/vips8/demandstyle.rb",
|
53
|
+
"lib/vips8/direction.rb",
|
54
|
+
"lib/vips8/error.rb",
|
55
|
+
"lib/vips8/extend.rb",
|
56
|
+
"lib/vips8/foreignflags.rb",
|
57
|
+
"lib/vips8/image.rb",
|
58
|
+
"lib/vips8/interpolate.rb",
|
59
|
+
"lib/vips8/interpretation.rb",
|
60
|
+
"lib/vips8/methods.rb",
|
61
|
+
"lib/vips8/operation.rb",
|
62
|
+
"ruby-vips8.gemspec",
|
63
|
+
"spec/image_spec.rb",
|
64
|
+
"spec/samples/balloon.v",
|
65
|
+
"spec/samples/ghost.ppm",
|
66
|
+
"spec/samples/huge.jpg",
|
67
|
+
"spec/samples/icc.jpg",
|
68
|
+
"spec/samples/lcd.icc",
|
69
|
+
"spec/samples/lion.svg",
|
70
|
+
"spec/samples/sample.csv",
|
71
|
+
"spec/samples/sample.exr",
|
72
|
+
"spec/samples/wagon.jpg",
|
73
|
+
"spec/samples/wagon.v",
|
74
|
+
"spec/spec_helper.rb",
|
75
|
+
"spec/vips_spec.rb"
|
76
|
+
]
|
77
|
+
s.homepage = "http://github.com/jcupitt/ruby-vips8"
|
78
|
+
s.licenses = ["MIT"]
|
79
|
+
s.rubygems_version = "2.2.2"
|
80
|
+
s.summary = "Ruby extension for the vips8 image processing library."
|
81
|
+
|
82
|
+
if s.respond_to? :specification_version then
|
83
|
+
s.specification_version = 4
|
84
|
+
|
85
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
86
|
+
s.add_runtime_dependency(%q<gobject-introspection>, ["~> 3.0"])
|
87
|
+
s.add_development_dependency(%q<rspec>, ["~> 3.3"])
|
88
|
+
s.add_development_dependency(%q<yard>, ["~> 0.8"])
|
89
|
+
s.add_development_dependency(%q<redcarpet>, ["~> 3.3"])
|
90
|
+
s.add_development_dependency(%q<github-markup>, ["~> 1.4"])
|
91
|
+
s.add_development_dependency(%q<bundler>, ["~> 1.0"])
|
92
|
+
s.add_development_dependency(%q<jeweler>, ["~> 2.0"])
|
93
|
+
else
|
94
|
+
s.add_dependency(%q<gobject-introspection>, ["~> 3.0"])
|
95
|
+
s.add_dependency(%q<rspec>, ["~> 3.3"])
|
96
|
+
s.add_dependency(%q<yard>, ["~> 0.8"])
|
97
|
+
s.add_dependency(%q<redcarpet>, ["~> 3.3"])
|
98
|
+
s.add_dependency(%q<github-markup>, ["~> 1.4"])
|
99
|
+
s.add_dependency(%q<bundler>, ["~> 1.0"])
|
100
|
+
s.add_dependency(%q<jeweler>, ["~> 2.0"])
|
101
|
+
end
|
102
|
+
else
|
103
|
+
s.add_dependency(%q<gobject-introspection>, ["~> 3.0"])
|
104
|
+
s.add_dependency(%q<rspec>, ["~> 3.3"])
|
105
|
+
s.add_dependency(%q<yard>, ["~> 0.8"])
|
106
|
+
s.add_dependency(%q<redcarpet>, ["~> 3.3"])
|
107
|
+
s.add_dependency(%q<github-markup>, ["~> 1.4"])
|
108
|
+
s.add_dependency(%q<bundler>, ["~> 1.0"])
|
109
|
+
s.add_dependency(%q<jeweler>, ["~> 2.0"])
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
data/spec/image_spec.rb
ADDED
@@ -0,0 +1,515 @@
|
|
1
|
+
require 'spec_helper.rb'
|
2
|
+
|
3
|
+
def has_jpeg?
|
4
|
+
Vips::type_find("VipsOperation", "jpegload") != nil
|
5
|
+
end
|
6
|
+
|
7
|
+
RSpec.describe Vips::Image do
|
8
|
+
describe '#new' do
|
9
|
+
it 'can make an empty image' do
|
10
|
+
image = Vips::Image.new
|
11
|
+
|
12
|
+
expect(image.width).to eq(1)
|
13
|
+
expect(image.height).to eq(1)
|
14
|
+
expect(image.bands).to eq(1)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'can save an image to a file' do
|
18
|
+
filename = timg "x.v"
|
19
|
+
|
20
|
+
image = Vips::Image.black(16, 16) + 128
|
21
|
+
image.write_to_file filename
|
22
|
+
|
23
|
+
expect(File.exist?(filename)).to be true
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'can load an image from a file' do
|
27
|
+
filename = timg "x.v"
|
28
|
+
|
29
|
+
image = Vips::Image.black(16, 16) + 128
|
30
|
+
image.write_to_file(filename)
|
31
|
+
|
32
|
+
x = Vips::Image.new_from_file filename
|
33
|
+
expect(x.width).to eq(16)
|
34
|
+
expect(x.height).to eq(16)
|
35
|
+
expect(x.bands).to eq(1)
|
36
|
+
expect(x.avg).to eq(128)
|
37
|
+
end
|
38
|
+
|
39
|
+
if has_jpeg?
|
40
|
+
it 'can save an image to a buffer' do
|
41
|
+
image = Vips::Image.black(16, 16) + 128
|
42
|
+
buffer = image.write_to_buffer ".jpg"
|
43
|
+
expect(buffer.length).to be > 100
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
if has_jpeg?
|
48
|
+
it 'can load an image from a buffer' do
|
49
|
+
image = Vips::Image.black(16, 16) + 128
|
50
|
+
buffer = image.write_to_buffer ".jpg"
|
51
|
+
x = Vips::Image.new_from_buffer buffer, ""
|
52
|
+
expect(x.width).to eq(16)
|
53
|
+
expect(x.height).to eq(16)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'can make an image from a 2d array' do
|
58
|
+
image = Vips::Image.new_from_array [[1, 2], [3, 4]]
|
59
|
+
expect(image.width).to eq(2)
|
60
|
+
expect(image.height).to eq(2)
|
61
|
+
expect(image.bands).to eq(1)
|
62
|
+
expect(image.avg).to eq(2.5)
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'can make an image from a 1d array' do
|
66
|
+
image = Vips::Image.new_from_array [1, 2]
|
67
|
+
expect(image.width).to eq(2)
|
68
|
+
expect(image.height).to eq(1)
|
69
|
+
expect(image.bands).to eq(1)
|
70
|
+
expect(image.avg).to eq(1.5)
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'can use array consts for image args' do
|
74
|
+
r = Vips::Image.black(16, 16)
|
75
|
+
r = r.draw_rect 255, 10, 12, 1, 1
|
76
|
+
g = Vips::Image.black(16, 16)
|
77
|
+
g = g.draw_rect 255, 10, 11, 1, 1
|
78
|
+
b = Vips::Image.black(16, 16)
|
79
|
+
b = b.draw_rect 255, 10, 10, 1, 1
|
80
|
+
im = r.bandjoin([g, b])
|
81
|
+
|
82
|
+
expect(im.width).to eq(16)
|
83
|
+
expect(im.height).to eq(16)
|
84
|
+
expect(im.bands).to eq(3)
|
85
|
+
|
86
|
+
im = im.conv [
|
87
|
+
[0.11, 0.11, 0.11],
|
88
|
+
[0.11, 0.11, 0.11],
|
89
|
+
[0.11, 0.11, 0.11]
|
90
|
+
], :precision => :float
|
91
|
+
|
92
|
+
expect(im.width).to eq(16)
|
93
|
+
expect(im.height).to eq(16)
|
94
|
+
expect(im.bands).to eq(3)
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'can set scale and offset on a convolution mask' do
|
98
|
+
image = Vips::Image.new_from_array [1, 2], 8, 2
|
99
|
+
expect(image.width).to eq(2)
|
100
|
+
expect(image.height).to eq(1)
|
101
|
+
expect(image.bands).to eq(1)
|
102
|
+
expect(image.scale).to eq(8)
|
103
|
+
expect(image.offset).to eq(2)
|
104
|
+
expect(image.avg).to eq(1.5)
|
105
|
+
end
|
106
|
+
|
107
|
+
if has_jpeg?
|
108
|
+
it 'can load a sample jpg image' do
|
109
|
+
x = Vips::Image.new_from_file simg("wagon.jpg")
|
110
|
+
expect(x.width).to eq(685)
|
111
|
+
expect(x.height).to eq(478)
|
112
|
+
expect(x.bands).to eq(3)
|
113
|
+
expect(x.avg).to be_within(0.001).of(109.789)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
if has_jpeg?
|
118
|
+
it 'can extract an ICC profile from a jpg image' do
|
119
|
+
x = Vips::Image.new_from_file simg("icc.jpg")
|
120
|
+
expect(x.width).to eq(2800)
|
121
|
+
expect(x.height).to eq(2100)
|
122
|
+
expect(x.bands).to eq(3)
|
123
|
+
expect(x.avg).to be_within(0.001).of(109.189)
|
124
|
+
|
125
|
+
profile = x.get_value "icc-profile-data"
|
126
|
+
expect(profile.class).to eq(String)
|
127
|
+
expect(profile.length).to eq(2360)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
if has_jpeg?
|
132
|
+
it 'can set an ICC profile on a jpg image' do
|
133
|
+
x = Vips::Image.new_from_file simg("icc.jpg")
|
134
|
+
profile = File.open(simg("lcd.icc"), "rb").read
|
135
|
+
x.set_value "icc-profile-data", profile
|
136
|
+
x.write_to_file(timg("x.jpg"))
|
137
|
+
|
138
|
+
x = Vips::Image.new_from_file timg("x.jpg")
|
139
|
+
expect(x.width).to eq(2800)
|
140
|
+
expect(x.height).to eq(2100)
|
141
|
+
expect(x.bands).to eq(3)
|
142
|
+
expect(x.avg).to be_within(0.1).of(109.189)
|
143
|
+
|
144
|
+
profile = x.get_value "icc-profile-data"
|
145
|
+
expect(profile.class).to eq(String)
|
146
|
+
expect(profile.length).to eq(3048)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
if has_jpeg?
|
151
|
+
it 'can load a sample jpg image' do
|
152
|
+
x = Vips::Image.new_from_file simg("wagon.jpg")
|
153
|
+
expect(x.width).to eq(685)
|
154
|
+
expect(x.height).to eq(478)
|
155
|
+
expect(x.bands).to eq(3)
|
156
|
+
expect(x.avg).to be_within(0.001).of(109.789)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
it 'has binary arithmetic operator overloads with constants' do
|
161
|
+
image = Vips::Image.black(16, 16) + 128
|
162
|
+
|
163
|
+
image += 128
|
164
|
+
image -= 128
|
165
|
+
image *= 2
|
166
|
+
image /= 2
|
167
|
+
image %= 100
|
168
|
+
image += 100
|
169
|
+
image **= 2
|
170
|
+
image **= 0.5
|
171
|
+
image <<= 1
|
172
|
+
image >>= 1
|
173
|
+
image |= 64
|
174
|
+
image &= 32
|
175
|
+
image ^= 128
|
176
|
+
|
177
|
+
expect(image.avg).to eq(128)
|
178
|
+
end
|
179
|
+
|
180
|
+
it 'has binary arithmetic operator overloads with array constants' do
|
181
|
+
image = Vips::Image.black(16, 16, :bands => 3) + 128
|
182
|
+
|
183
|
+
image += [128, 0, 0]
|
184
|
+
image -= [128, 0, 0]
|
185
|
+
image *= [2, 1, 1]
|
186
|
+
image /= [2, 1, 1]
|
187
|
+
image %= [100, 99, 98]
|
188
|
+
image += [100, 99, 98]
|
189
|
+
image **= [2, 3, 4]
|
190
|
+
image **= [1.0 / 2.0, 1.0 / 3.0, 1.0 / 4.0]
|
191
|
+
image <<= [1, 2, 3]
|
192
|
+
image >>= [1, 2, 3]
|
193
|
+
image |= [64, 128, 256]
|
194
|
+
image &= [64, 128, 256]
|
195
|
+
image ^= [64 + 128, 0, 256 + 128]
|
196
|
+
|
197
|
+
expect(image.avg).to eq(128)
|
198
|
+
end
|
199
|
+
|
200
|
+
it 'has binary arithmetic operator overloads with image args' do
|
201
|
+
image = Vips::Image.black(16, 16) + 128
|
202
|
+
x = image
|
203
|
+
|
204
|
+
x += image
|
205
|
+
x -= image
|
206
|
+
x *= image
|
207
|
+
x /= image
|
208
|
+
x %= image
|
209
|
+
x += image
|
210
|
+
x |= image
|
211
|
+
x &= image
|
212
|
+
x ^= image
|
213
|
+
|
214
|
+
expect(image.avg).to eq(128)
|
215
|
+
end
|
216
|
+
|
217
|
+
it 'has relational operator overloads with constants' do
|
218
|
+
image = Vips::Image.black(16, 16) + 128
|
219
|
+
|
220
|
+
expect((image > 128).avg).to eq(0)
|
221
|
+
expect((image >= 128).avg).to eq(255)
|
222
|
+
expect((image < 128).avg).to eq(0)
|
223
|
+
expect((image <= 128).avg).to eq(255)
|
224
|
+
expect((image == 128).avg).to eq(255)
|
225
|
+
expect((image != 128).avg).to eq(0)
|
226
|
+
end
|
227
|
+
|
228
|
+
it 'has relational operator overloads with array constants' do
|
229
|
+
image = Vips::Image.black(16, 16, :bands => 3) + [100, 128, 130]
|
230
|
+
|
231
|
+
expect((image > [100, 128, 130]).avg).to eq(0)
|
232
|
+
expect((image >= [100, 128, 130]).avg).to eq(255)
|
233
|
+
expect((image < [100, 128, 130]).avg).to eq(0)
|
234
|
+
expect((image <= [100, 128, 130]).avg).to eq(255)
|
235
|
+
expect((image == [100, 128, 130]).avg).to eq(255)
|
236
|
+
expect((image != [100, 128, 130]).avg).to eq(0)
|
237
|
+
end
|
238
|
+
|
239
|
+
it 'has relational operator overloads with image args' do
|
240
|
+
image = Vips::Image.black(16, 16) + 128
|
241
|
+
|
242
|
+
expect((image > image).avg).to eq(0)
|
243
|
+
expect((image >= image).avg).to eq(255)
|
244
|
+
expect((image < image).avg).to eq(0)
|
245
|
+
expect((image <= image).avg).to eq(255)
|
246
|
+
expect((image == image).avg).to eq(255)
|
247
|
+
expect((image != image).avg).to eq(0)
|
248
|
+
end
|
249
|
+
|
250
|
+
it 'has band extract with numeric arg' do
|
251
|
+
image = Vips::Image.black(16, 16, :bands => 3) + [100, 128, 130]
|
252
|
+
x = image[1]
|
253
|
+
|
254
|
+
expect(x.width).to eq(16)
|
255
|
+
expect(x.height).to eq(16)
|
256
|
+
expect(x.bands).to eq(1)
|
257
|
+
expect(x.avg).to eq(128)
|
258
|
+
end
|
259
|
+
|
260
|
+
it 'has band extract with range arg' do
|
261
|
+
image = Vips::Image.black(16, 16, :bands => 3) + [100, 128, 130]
|
262
|
+
x = image[1..2]
|
263
|
+
|
264
|
+
expect(x.width).to eq(16)
|
265
|
+
expect(x.height).to eq(16)
|
266
|
+
expect(x.bands).to eq(2)
|
267
|
+
expect(x.avg).to eq(129)
|
268
|
+
end
|
269
|
+
|
270
|
+
it 'has rounding members' do
|
271
|
+
# need to avoid rounding down to 0.499999
|
272
|
+
image = Vips::Image.black(16, 16) + 0.500001
|
273
|
+
|
274
|
+
expect(image.floor.avg).to eq(0)
|
275
|
+
expect(image.ceil.avg).to eq(1)
|
276
|
+
expect(image.rint.avg).to eq(1)
|
277
|
+
end
|
278
|
+
|
279
|
+
it 'has bandsplit and bandjoin' do
|
280
|
+
image = Vips::Image.black(16, 16, :bands => 3) + [100, 128, 130]
|
281
|
+
|
282
|
+
split = image.bandsplit
|
283
|
+
x = split[0].bandjoin split[1..2]
|
284
|
+
|
285
|
+
expect(x[0].avg).to eq(100)
|
286
|
+
expect(x[1].avg).to eq(128)
|
287
|
+
expect(x[2].avg).to eq(130)
|
288
|
+
end
|
289
|
+
|
290
|
+
it 'can bandjoin constants' do
|
291
|
+
image = Vips::Image.black(16, 16, :bands => 3) + [100, 128, 130]
|
292
|
+
|
293
|
+
x = image.bandjoin 255
|
294
|
+
|
295
|
+
expect(x[0].avg).to eq(100)
|
296
|
+
expect(x[1].avg).to eq(128)
|
297
|
+
expect(x[2].avg).to eq(130)
|
298
|
+
expect(x[3].avg).to eq(255)
|
299
|
+
expect(x.bands).to eq(4)
|
300
|
+
|
301
|
+
x = image.bandjoin [1, 2]
|
302
|
+
|
303
|
+
expect(x[0].avg).to eq(100)
|
304
|
+
expect(x[1].avg).to eq(128)
|
305
|
+
expect(x[2].avg).to eq(130)
|
306
|
+
expect(x[3].avg).to eq(1)
|
307
|
+
expect(x[4].avg).to eq(2)
|
308
|
+
expect(x.bands).to eq(5)
|
309
|
+
|
310
|
+
end
|
311
|
+
|
312
|
+
it 'has minpos/maxpos' do
|
313
|
+
image = Vips::Image.black(16, 16) + 128
|
314
|
+
image = image.draw_rect 255, 10, 12, 1, 1
|
315
|
+
v, x, y = image.maxpos
|
316
|
+
|
317
|
+
expect(v).to eq(255)
|
318
|
+
expect(x).to eq(10)
|
319
|
+
expect(y).to eq(12)
|
320
|
+
|
321
|
+
image = Vips::Image.black(16, 16) + 128
|
322
|
+
image = image.draw_rect 12, 10, 12, 1, 1
|
323
|
+
v, x, y = image.minpos
|
324
|
+
|
325
|
+
expect(v).to eq(12)
|
326
|
+
expect(x).to eq(10)
|
327
|
+
expect(y).to eq(12)
|
328
|
+
|
329
|
+
end
|
330
|
+
|
331
|
+
it 'can form complex images' do
|
332
|
+
r = Vips::Image.black(16, 16) + 128
|
333
|
+
i = Vips::Image.black(16, 16) + 12
|
334
|
+
cmplx = r.complexform i
|
335
|
+
re = cmplx.real
|
336
|
+
im = cmplx.imag
|
337
|
+
|
338
|
+
expect(re.avg).to eq(128)
|
339
|
+
expect(im.avg).to eq(12)
|
340
|
+
end
|
341
|
+
|
342
|
+
it 'can convert complex polar <-> rectangular' do
|
343
|
+
r = Vips::Image.black(16, 16) + 128
|
344
|
+
i = Vips::Image.black(16, 16) + 12
|
345
|
+
cmplx = r.complexform i
|
346
|
+
|
347
|
+
cmplx = cmplx.rect.polar
|
348
|
+
|
349
|
+
expect(cmplx.real.avg).to be_within(0.001).of(128)
|
350
|
+
expect(cmplx.imag.avg).to be_within(0.001).of(12)
|
351
|
+
end
|
352
|
+
|
353
|
+
it 'can take complex conjugate' do
|
354
|
+
r = Vips::Image.black(16, 16) + 128
|
355
|
+
i = Vips::Image.black(16, 16) + 12
|
356
|
+
cmplx = r.complexform i
|
357
|
+
|
358
|
+
cmplx = cmplx.conj
|
359
|
+
|
360
|
+
expect(cmplx.real.avg).to be_within(0.001).of(128)
|
361
|
+
expect(cmplx.imag.avg).to be_within(0.001).of(-12)
|
362
|
+
end
|
363
|
+
|
364
|
+
it 'has working trig functions' do
|
365
|
+
image = Vips::Image.black(16, 16) + 67
|
366
|
+
|
367
|
+
image = image.sin.cos.tan
|
368
|
+
image = image.atan.acos.asin
|
369
|
+
|
370
|
+
expect(image.avg).to be_within(0.01).of(67)
|
371
|
+
end
|
372
|
+
|
373
|
+
it 'has working log functions' do
|
374
|
+
image = Vips::Image.black(16, 16) + 67
|
375
|
+
|
376
|
+
image = image.log.exp.log10.exp10
|
377
|
+
|
378
|
+
expect(image.avg).to be_within(0.01).of(67)
|
379
|
+
end
|
380
|
+
|
381
|
+
it 'can flip' do
|
382
|
+
a = Vips::Image.black(16, 16)
|
383
|
+
a = a.draw_rect 255, 10, 12, 1, 1
|
384
|
+
b = Vips::Image.black(16, 16)
|
385
|
+
b = b.draw_rect 255, 15 - 10, 12, 1, 1
|
386
|
+
|
387
|
+
expect((a - b.fliphor).abs.max).to eq(0.0)
|
388
|
+
|
389
|
+
a = Vips::Image.black(16, 16)
|
390
|
+
a = a.draw_rect 255, 10, 15 - 12, 1, 1
|
391
|
+
b = Vips::Image.black(16, 16)
|
392
|
+
b = b.draw_rect 255, 10, 12, 1, 1
|
393
|
+
|
394
|
+
expect((a - b.flipver).abs.max).to eq(0.0)
|
395
|
+
end
|
396
|
+
|
397
|
+
it 'can getpoint' do
|
398
|
+
a = Vips::Image.black(16, 16)
|
399
|
+
a = a.draw_rect 255, 10, 12, 1, 1
|
400
|
+
b = Vips::Image.black(16, 16)
|
401
|
+
b = b.draw_rect 255, 10, 10, 1, 1
|
402
|
+
im = a.bandjoin(b)
|
403
|
+
|
404
|
+
expect(im.getpoint(10, 12)).to eq([255, 0])
|
405
|
+
expect(im.getpoint(10, 10)).to eq([0, 255])
|
406
|
+
end
|
407
|
+
|
408
|
+
it 'can median' do
|
409
|
+
a = Vips::Image.black(16, 16)
|
410
|
+
a = a.draw_rect 255, 10, 12, 1, 1
|
411
|
+
im = a.median
|
412
|
+
|
413
|
+
expect(im.max).to eq(0)
|
414
|
+
end
|
415
|
+
|
416
|
+
it 'can erode' do
|
417
|
+
a = Vips::Image.black(16, 16)
|
418
|
+
a = a.draw_rect 255, 10, 12, 1, 1
|
419
|
+
mask = Vips::Image.new_from_array [
|
420
|
+
[128, 255, 128],
|
421
|
+
[255, 255, 255],
|
422
|
+
[128, 255, 128]
|
423
|
+
]
|
424
|
+
im = a.erode mask
|
425
|
+
|
426
|
+
expect(im.max).to eq(0)
|
427
|
+
end
|
428
|
+
|
429
|
+
it 'can dilate' do
|
430
|
+
a = Vips::Image.black(16, 16)
|
431
|
+
a = a.draw_rect 255, 10, 12, 1, 1
|
432
|
+
mask = Vips::Image.new_from_array [
|
433
|
+
[128, 255, 128],
|
434
|
+
[255, 255, 255],
|
435
|
+
[128, 255, 128]
|
436
|
+
]
|
437
|
+
im = a.dilate mask
|
438
|
+
|
439
|
+
expect(im.getpoint(10, 12)).to eq([255])
|
440
|
+
expect(im.getpoint(11, 12)).to eq([255])
|
441
|
+
expect(im.getpoint(12, 12)).to eq([0])
|
442
|
+
end
|
443
|
+
|
444
|
+
it 'can rot' do
|
445
|
+
a = Vips::Image.black(16, 16)
|
446
|
+
a = a.draw_rect 255, 10, 12, 1, 1
|
447
|
+
|
448
|
+
im = a.rot90.rot90.rot90.rot90
|
449
|
+
expect((a - im).abs.max).to eq(0.0)
|
450
|
+
|
451
|
+
im = a.rot180.rot180
|
452
|
+
expect((a - im).abs.max).to eq(0.0)
|
453
|
+
|
454
|
+
im = a.rot270.rot270.rot270.rot270
|
455
|
+
expect((a - im).abs.max).to eq(0.0)
|
456
|
+
end
|
457
|
+
|
458
|
+
it 'can bandbool' do
|
459
|
+
a = Vips::Image.black(16, 16)
|
460
|
+
a = a.draw_rect 255, 10, 12, 1, 1
|
461
|
+
b = Vips::Image.black(16, 16)
|
462
|
+
b = b.draw_rect 255, 10, 10, 1, 1
|
463
|
+
im = a.bandjoin(b)
|
464
|
+
|
465
|
+
expect(im.bandand.getpoint(10, 12)).to eq([0])
|
466
|
+
expect(im.bandor.getpoint(10, 12)).to eq([255])
|
467
|
+
expect(im.bandeor.getpoint(10, 12)).to eq([255])
|
468
|
+
end
|
469
|
+
|
470
|
+
it 'ifthenelse with image arguments' do
|
471
|
+
image = Vips::Image.black(16, 16)
|
472
|
+
image = image.draw_rect 255, 10, 12, 1, 1
|
473
|
+
black = Vips::Image.black(16, 16)
|
474
|
+
white = Vips::Image.black(16, 16) + 255
|
475
|
+
|
476
|
+
result = image.ifthenelse black, white
|
477
|
+
|
478
|
+
v, x, y = result.minpos
|
479
|
+
|
480
|
+
expect(v).to eq(0)
|
481
|
+
expect(x).to eq(10)
|
482
|
+
expect(y).to eq(12)
|
483
|
+
end
|
484
|
+
|
485
|
+
it 'ifthenelse with constant arguments' do
|
486
|
+
image = Vips::Image.black(16, 16)
|
487
|
+
image = image.draw_rect 255, 10, 12, 1, 1
|
488
|
+
|
489
|
+
result = image.ifthenelse 0, 255
|
490
|
+
|
491
|
+
v, x, y = result.minpos
|
492
|
+
|
493
|
+
expect(v).to eq(0)
|
494
|
+
expect(x).to eq(10)
|
495
|
+
expect(y).to eq(12)
|
496
|
+
end
|
497
|
+
|
498
|
+
it 'ifthenelse with vector arguments' do
|
499
|
+
image = Vips::Image.black(16, 16)
|
500
|
+
image = image.draw_rect 255, 10, 12, 1, 1
|
501
|
+
white = Vips::Image.black(16, 16) + 255
|
502
|
+
|
503
|
+
result = image.ifthenelse [255, 0, 0], white
|
504
|
+
|
505
|
+
v, x, y = result.minpos
|
506
|
+
|
507
|
+
expect(v).to eq(0)
|
508
|
+
expect(x).to eq(10)
|
509
|
+
expect(y).to eq(12)
|
510
|
+
end
|
511
|
+
|
512
|
+
end
|
513
|
+
|
514
|
+
end
|
515
|
+
|