assembly-image 2.0.0 → 2.1.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 +4 -4
- data/.circleci/config.yml +1 -1
- data/.gitignore +0 -1
- data/.rubocop.yml +121 -4
- data/.rubocop_todo.yml +7 -57
- data/.rvmrc.example +1 -1
- data/Gemfile.lock +118 -0
- data/README.md +12 -36
- data/assembly-image.gemspec +2 -3
- data/bin/console +1 -1
- data/config/boot.rb +2 -2
- data/lib/{assembly-image → assembly/image}/jp2_creator.rb +36 -42
- data/lib/assembly/image.rb +60 -0
- data/lib/assembly-image.rb +2 -3
- data/spec/assembly/image/jp2_creator_spec.rb +327 -34
- data/spec/assembly/image_spec.rb +25 -0
- data/spec/spec_helper.rb +4 -21
- metadata +15 -43
- data/lib/assembly-image/image.rb +0 -149
- data/lib/assembly-image/images.rb +0 -102
- data/spec/image_spec.rb +0 -324
- data/spec/images_spec.rb +0 -47
- data/spec/test_data/color_cmyk_tagged.tif +0 -0
- data/spec/test_data/color_cmyk_untagged.tif +0 -0
- data/spec/test_data/color_rgb_adobergb1998_lzw.tif +0 -0
- data/spec/test_data/color_rgb_srgb.jpg +0 -0
- data/spec/test_data/color_rgb_srgb.tif +0 -0
- data/spec/test_data/color_rgb_untagged.tif +0 -0
- data/spec/test_data/gray_gray_untagged.tif +0 -0
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'vips'
|
4
|
+
require 'assembly-objectfile'
|
5
|
+
require_relative 'image/jp2_creator'
|
6
|
+
|
7
|
+
module Assembly
|
8
|
+
# The Image class contains methods to operate on an image.
|
9
|
+
class Image < Assembly::ObjectFile
|
10
|
+
# @return [integer] image height in pixels
|
11
|
+
def height
|
12
|
+
vips_image.height
|
13
|
+
end
|
14
|
+
|
15
|
+
# @return [integer] image width in pixels
|
16
|
+
def width
|
17
|
+
vips_image.width
|
18
|
+
end
|
19
|
+
|
20
|
+
# @return [string] full default jp2 path and filename that will be created from the given image
|
21
|
+
# Example: given original file of '/dir/path_to_file.tif', gives '/dir/path_to_file.jp2'
|
22
|
+
def jp2_filename
|
23
|
+
# path is a property on Assembly::ObjectFile
|
24
|
+
File.extname(path).empty? ? "#{path}.jp2" : path.gsub(File.extname(path), '.jp2')
|
25
|
+
end
|
26
|
+
|
27
|
+
# Create a JP2 file for the current image.
|
28
|
+
# Important note: this will not work for multipage TIFFs.
|
29
|
+
#
|
30
|
+
# @param [String] output path to the output JP2 file (default: mirrors the source file name and path, but with a .jp2 extension)
|
31
|
+
# @param [Boolean] overwrite if set to false, an existing JP2 file with the same name won't be overwritten (default: false)
|
32
|
+
# @param [Dir] tmp_folder the temporary folder to use when creating the jp2 (default: '/tmp'); also used by imagemagick
|
33
|
+
# @return [Assembly::Image] object containing the generated JP2 file
|
34
|
+
#
|
35
|
+
# Example:
|
36
|
+
# source_img = Assembly::Image.new('/dir/path_to_file.tif')
|
37
|
+
# jp2_img = source_img.create_jp2(overwrite: true)
|
38
|
+
# jp2_img.mimetype # 'image/jp2'
|
39
|
+
# jp2_img.path # '/dir/path_to_file.jp2'
|
40
|
+
def create_jp2(**params)
|
41
|
+
Jp2Creator.create(self, **params)
|
42
|
+
end
|
43
|
+
|
44
|
+
def vips_image
|
45
|
+
# Disable cache. Otherwise, Vips gets confused by files with the same filename.
|
46
|
+
Vips.cache_set_max_files(0)
|
47
|
+
# autorot will only affect images that need rotation: https://www.libvips.org/API/current/libvips-conversion.html#vips-autorot
|
48
|
+
@vips_image ||= Vips::Image.new_from_file(path).autorot
|
49
|
+
end
|
50
|
+
|
51
|
+
def srgb?
|
52
|
+
vips_image.interpretation == :srgb
|
53
|
+
end
|
54
|
+
|
55
|
+
# Does the image include an ICC profile?
|
56
|
+
def has_profile?
|
57
|
+
vips_image.get_fields.include?('icc-profile-data')
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
data/lib/assembly-image.rb
CHANGED
@@ -2,11 +2,10 @@
|
|
2
2
|
|
3
3
|
module Assembly
|
4
4
|
# the path to the gem, used to access profiles stored with the gem
|
5
|
-
PATH_TO_IMAGE_GEM = File.expand_path(File.dirname(__FILE__)
|
5
|
+
PATH_TO_IMAGE_GEM = File.expand_path("#{File.dirname(__FILE__)}/..")
|
6
6
|
PATH_TO_PROFILES = File.join(Assembly::PATH_TO_IMAGE_GEM, 'profiles')
|
7
7
|
SRGB_ICC = File.join(PATH_TO_PROFILES, 'sRGBIEC6196621.icc')
|
8
8
|
CMYK_ICC = File.join(PATH_TO_PROFILES, 'cmyk.icc')
|
9
9
|
end
|
10
10
|
|
11
|
-
require 'assembly
|
12
|
-
require 'assembly-image/images'
|
11
|
+
require 'assembly/image'
|
@@ -3,52 +3,345 @@
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
5
|
RSpec.describe Assembly::Image::Jp2Creator do
|
6
|
-
|
6
|
+
let(:jp2creator) { described_class.new(assembly_image, output: jp2_output_file) }
|
7
|
+
let(:assembly_image) { Assembly::Image.new(input_path) }
|
8
|
+
let(:jp2_output_file) { File.join(TEST_OUTPUT_DIR, 'test.jp2') }
|
7
9
|
|
8
|
-
|
9
|
-
|
10
|
-
let(:creator) { described_class.new(ai, output: TEST_JP2_OUTPUT_FILE) }
|
10
|
+
describe '.create' do
|
11
|
+
subject(:result) { jp2creator.create }
|
11
12
|
|
12
|
-
|
13
|
+
let(:input_path) { TEST_TIF_INPUT_FILE }
|
13
14
|
|
14
|
-
|
15
|
-
|
16
|
-
|
15
|
+
before { cleanup }
|
16
|
+
|
17
|
+
context 'when input path is blank' do
|
18
|
+
let(:input_path) { '' }
|
19
|
+
|
20
|
+
it 'raises error' do
|
21
|
+
expect { assembly_image.create_jp2 }.to raise_error(RuntimeError, 'input file does not exist or is a directory')
|
22
|
+
end
|
17
23
|
end
|
18
24
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
expect(result.path).to eq TEST_JP2_OUTPUT_FILE
|
24
|
-
expect(TEST_JP2_OUTPUT_FILE).to be_a_jp2
|
25
|
+
context 'when tmp folder does not exist' do
|
26
|
+
before do
|
27
|
+
generate_test_image(input_path)
|
28
|
+
end
|
25
29
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
expect(jp2.width).to eq 43
|
30
|
+
it 'raises error' do
|
31
|
+
bogus_folder = '/nonexisting'
|
32
|
+
expect(File).not_to exist bogus_folder
|
33
|
+
expect { assembly_image.create_jp2(tmp_folder: bogus_folder) }.to raise_error(RuntimeError, 'tmp_folder /nonexisting does not exist')
|
34
|
+
end
|
32
35
|
end
|
33
|
-
end
|
34
36
|
|
35
|
-
|
36
|
-
|
37
|
-
|
37
|
+
context 'when no output file is specified' do
|
38
|
+
let(:jp2creator) { described_class.new(assembly_image) }
|
39
|
+
let(:jp2_output_file) { File.join(TEST_INPUT_DIR, File.basename(input_path).gsub('.tif', '.jp2')) }
|
40
|
+
|
41
|
+
before do
|
42
|
+
generate_test_image(input_path)
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'creates a jp2 of the same filename and in the same location as the input' do
|
46
|
+
expect(File).to exist input_path # test image was generated
|
47
|
+
expect(File).not_to exist jp2_output_file
|
48
|
+
expect(assembly_image.srgb?).to be true
|
49
|
+
expect(assembly_image.has_profile?).to be false
|
50
|
+
|
51
|
+
expect(result).to be_a_kind_of Assembly::Image
|
52
|
+
expect(result.path).to eq jp2_output_file
|
53
|
+
expect(result.mimetype).to eq 'image/jp2'
|
54
|
+
# check srgb on temporary tiff (due to CI libvips not speaking jp2)
|
55
|
+
tmp_tiff_image = Assembly::Image.new(jp2creator.send(:make_tmp_tiff))
|
56
|
+
expect(tmp_tiff_image.srgb?).to be true
|
57
|
+
expect(tmp_tiff_image.has_profile?).to be false
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'when the output file exists and no overwriting' do
|
62
|
+
before do
|
63
|
+
generate_test_image(input_path)
|
64
|
+
FileUtils.touch(jp2_output_file) # just need a file with this name, don't care what
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'raises error' do
|
68
|
+
expect(File).to exist input_path # test image was generated
|
69
|
+
expect { assembly_image.create_jp2(output: jp2_output_file) }.to raise_error(SecurityError, %r{spec/test_data/output/test.jp2 exists, cannot overwrite})
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context 'when the output file exists and overwriting allowed' do
|
74
|
+
before do
|
75
|
+
generate_test_image(input_path)
|
76
|
+
FileUtils.touch(jp2_output_file) # just need a file with this name, don't care what
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'recreates jp2' do
|
80
|
+
expect(File).to exist input_path # test image was generated
|
81
|
+
expect(File).to exist jp2_output_file
|
82
|
+
expect(assembly_image.srgb?).to be true
|
83
|
+
expect(assembly_image.has_profile?).to be false
|
84
|
+
|
85
|
+
result = assembly_image.create_jp2(output: jp2_output_file, overwrite: true)
|
86
|
+
expect(result).to be_a_kind_of Assembly::Image
|
87
|
+
expect(result.path).to eq jp2_output_file
|
88
|
+
expect(result.mimetype).to eq 'image/jp2'
|
89
|
+
# check srgb on temporary tiff (due to CI libvips not speaking jp2)
|
90
|
+
tmp_tiff_image = Assembly::Image.new(jp2creator.send(:make_tmp_tiff))
|
91
|
+
expect(tmp_tiff_image.srgb?).to be true
|
92
|
+
expect(tmp_tiff_image.has_profile?).to be false
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
context 'when the input file is a jp2' do
|
97
|
+
let(:input_path) { File.join(TEST_INPUT_DIR, 'for_jp2.tif') }
|
98
|
+
|
99
|
+
before do
|
100
|
+
generate_test_image(input_path)
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'raises error' do
|
104
|
+
expect(result.path).to eq jp2_output_file
|
105
|
+
expect(result.mimetype).to eq 'image/jp2'
|
106
|
+
|
107
|
+
expect { described_class.new(Assembly::Image.new(jp2_output_file)).create }.to raise_error(RuntimeError, 'input file is not a valid image, or is the wrong mimetype')
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
context 'when given a tiff' do
|
112
|
+
before do
|
113
|
+
generate_test_image(input_path)
|
114
|
+
end
|
115
|
+
|
116
|
+
it 'gets the correct image, creates and cleans up the temporary tiff' do
|
117
|
+
expect(File).to exist input_path # test image was generated
|
118
|
+
expect(File).not_to exist jp2_output_file
|
119
|
+
|
120
|
+
expect(result).to be_a_kind_of Assembly::Image
|
121
|
+
expect(result.path).to eq jp2_output_file
|
122
|
+
expect(result.mimetype).to eq 'image/jp2'
|
123
|
+
# check height and width on temporary tiff (due to CI libvips not speaking jp2)
|
124
|
+
tmp_tiff_image = Assembly::Image.new(jp2creator.send(:make_tmp_tiff))
|
125
|
+
expect(tmp_tiff_image.height).to eq 36
|
126
|
+
expect(tmp_tiff_image.width).to eq 43
|
127
|
+
|
128
|
+
expect(jp2creator.tmp_tiff_path).not_to be_nil # temporary tiff was created
|
129
|
+
expect(File).not_to exist jp2creator.tmp_tiff_path # the temporary tiff path is cleaned up
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
context 'when given an LZW compressed RGB tif' do
|
134
|
+
let(:input_path) { File.join(TEST_INPUT_DIR, 'lzw.tif') }
|
135
|
+
|
136
|
+
before do
|
137
|
+
generate_test_image(input_path, compress: 'lzw')
|
138
|
+
end
|
139
|
+
|
140
|
+
it 'creates the jp2' do
|
141
|
+
expect(File).to exist input_path
|
142
|
+
expect(File).not_to exist jp2_output_file
|
143
|
+
|
144
|
+
expect(result.path).to eq jp2_output_file
|
145
|
+
expect(result.mimetype).to eq 'image/jp2'
|
146
|
+
# check height and width on temporary tiff (due to CI libvips not speaking jp2)
|
147
|
+
tmp_tiff_image = Assembly::Image.new(jp2creator.send(:make_tmp_tiff))
|
148
|
+
expect(tmp_tiff_image.height).to eq 36
|
149
|
+
expect(tmp_tiff_image.width).to eq 43
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
context 'when given a cmyk tif' do
|
154
|
+
let(:input_path) { File.join(TEST_INPUT_DIR, 'test-cmyk.tif') }
|
155
|
+
|
156
|
+
before do
|
157
|
+
generate_test_image(input_path, color: 'cmyk', cg_type: 'cmyk', profile: 'cmyk', bands: 4)
|
158
|
+
end
|
159
|
+
|
160
|
+
it 'creates an srgb jp2' do
|
161
|
+
expect(File).to exist input_path
|
162
|
+
expect(File).not_to exist jp2_output_file
|
163
|
+
expect(assembly_image.srgb?).to be false
|
164
|
+
expect(assembly_image.vips_image.interpretation).to eq :cmyk
|
165
|
+
expect(assembly_image.has_profile?).to be true
|
166
|
+
|
167
|
+
expect(result.path).to eq jp2_output_file
|
168
|
+
expect(result.mimetype).to eq 'image/jp2'
|
169
|
+
|
170
|
+
# NOTE: we verify the CMYK has been converted to an SRGB JP2 correctly by using ruby-vips;
|
171
|
+
# we have to verify this on the *temporary tiff because lipvips pkg available for circleci does not speak JP2
|
172
|
+
tmp_tiff_image = Assembly::Image.new(jp2creator.send(:make_tmp_tiff))
|
173
|
+
expect(tmp_tiff_image.srgb?).to be true
|
174
|
+
expect(tmp_tiff_image.has_profile?).to be true
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
context 'when the input file is a JPEG' do
|
179
|
+
let(:input_path) { File.join(TEST_INPUT_DIR, 'test.jpg') }
|
180
|
+
|
181
|
+
before do
|
182
|
+
generate_test_image(input_path)
|
183
|
+
end
|
184
|
+
|
185
|
+
it 'creates jp2 when given a JPEG' do
|
186
|
+
expect(File).to exist input_path # test image was generated
|
187
|
+
expect(File).not_to exist jp2_output_file
|
188
|
+
|
189
|
+
expect(result.path).to eq jp2_output_file
|
190
|
+
expect(result.mimetype).to eq 'image/jp2'
|
191
|
+
# check height and width on temporary tiff (due to CI libvips not speaking jp2)
|
192
|
+
tmp_tiff_image = Assembly::Image.new(jp2creator.send(:make_tmp_tiff))
|
193
|
+
expect(tmp_tiff_image.height).to eq 36
|
194
|
+
expect(tmp_tiff_image.width).to eq 43
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
context 'when the source image has no profile' do
|
199
|
+
let(:input_path) { File.join(TEST_INPUT_DIR, 'no_profile.tif') }
|
200
|
+
|
201
|
+
before do
|
202
|
+
generate_test_image(input_path)
|
203
|
+
end
|
204
|
+
|
205
|
+
it 'creates color jp2 without ICC profile' do
|
206
|
+
expect(File).to exist input_path # test image was generated
|
207
|
+
expect(File).not_to exist jp2_output_file
|
208
|
+
expect(assembly_image.srgb?).to be true
|
209
|
+
expect(assembly_image.has_profile?).to be false
|
210
|
+
|
211
|
+
expect(result.path).to eq jp2_output_file
|
212
|
+
expect(result.mimetype).to eq 'image/jp2'
|
213
|
+
|
214
|
+
# check srgb on temporary tiff (due to CI libvips not speaking jp2)
|
215
|
+
tmp_tiff_image = Assembly::Image.new(jp2creator.send(:make_tmp_tiff))
|
216
|
+
expect(tmp_tiff_image.srgb?).to be true
|
217
|
+
expect(tmp_tiff_image.has_profile?).to be false
|
218
|
+
end
|
38
219
|
end
|
39
220
|
|
40
|
-
|
221
|
+
context 'when given a bitonal tif with bitonal image data' do
|
222
|
+
let(:input_path) { File.join(TEST_INPUT_DIR, 'bitonal.tif') }
|
223
|
+
|
224
|
+
before do
|
225
|
+
# depth of 1 says 1 bit per pixel.
|
226
|
+
generate_test_image(input_path, color: 'bin', bands: 1, depth: 1)
|
227
|
+
end
|
228
|
+
|
229
|
+
it 'creates bitonal jp2 without ICC profile' do
|
230
|
+
expect(File).to exist input_path # test image was generated
|
231
|
+
expect(File).not_to exist jp2_output_file
|
232
|
+
expect(assembly_image.srgb?).to be false
|
233
|
+
expect(assembly_image.vips_image.interpretation).to eq :'b-w'
|
234
|
+
expect(assembly_image.has_profile?).to be false
|
235
|
+
|
236
|
+
expect(result.path).to eq jp2_output_file
|
237
|
+
expect(result.mimetype).to eq 'image/jp2'
|
238
|
+
|
239
|
+
# check srgb on temporary tiff (due to CI libvips not speaking jp2)
|
240
|
+
tmp_tiff_image = Assembly::Image.new(jp2creator.send(:make_tmp_tiff))
|
241
|
+
expect(tmp_tiff_image.srgb?).to be false
|
242
|
+
expect(tmp_tiff_image.has_profile?).to be false
|
243
|
+
vips_for_tmp_tiff = tmp_tiff_image.vips_image
|
244
|
+
expect(vips_for_tmp_tiff.bands).to eq 1
|
245
|
+
expect(vips_for_tmp_tiff.interpretation).to eq :'b-w'
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
context 'when given a color tif but bitonal image data' do
|
250
|
+
# NOTE: this spec was created due to ImageMagick weirdness processing this wrinkle
|
251
|
+
let(:input_path) { File.join(TEST_INPUT_DIR, 'color.tif') }
|
252
|
+
|
253
|
+
before do
|
254
|
+
# from Tony Calavano:
|
255
|
+
# color: bin should threshold the pixel data to 0 or 255, bands: 3 forces it to be rgb.
|
256
|
+
# It should then create a 8 bits per pixel image
|
257
|
+
generate_test_image(input_path, color: 'bin', bands: 3)
|
258
|
+
end
|
259
|
+
|
260
|
+
it 'creates color jp2 without ICC profile' do
|
261
|
+
expect(File).to exist input_path # test image was generated
|
262
|
+
expect(File).not_to exist jp2_output_file
|
263
|
+
expect(assembly_image.srgb?).to be true
|
264
|
+
expect(assembly_image.has_profile?).to be false
|
265
|
+
|
266
|
+
expect(result.path).to eq jp2_output_file
|
267
|
+
expect(result.mimetype).to eq 'image/jp2'
|
268
|
+
|
269
|
+
# check srgb on temporary tiff (due to CI libvips not speaking jp2)
|
270
|
+
tmp_tiff_image = Assembly::Image.new(jp2creator.send(:make_tmp_tiff))
|
271
|
+
expect(tmp_tiff_image.srgb?).to be true
|
272
|
+
expect(tmp_tiff_image.has_profile?).to be false
|
273
|
+
expect(tmp_tiff_image.vips_image.bands).to eq 3
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
context 'when given a grayscale tif but with bitonal image data' do
|
278
|
+
# NOTE: this spec was created due to ImageMagick weirdness processing this wrinkle
|
279
|
+
let(:input_path) { File.join(TEST_INPUT_DIR, 'gray.tif') }
|
280
|
+
|
281
|
+
before do
|
282
|
+
# from Tony Calavano: color: grey, bands: 1 would be a normal grayscale image with 8 bits per pixel
|
283
|
+
generate_test_image(input_path, color: 'bin', bands: 1)
|
284
|
+
end
|
285
|
+
|
286
|
+
it 'creates grayscale jp2 without ICC profile' do
|
287
|
+
expect(File).to exist input_path # test image was generated
|
288
|
+
expect(File).not_to exist jp2_output_file
|
289
|
+
expect(assembly_image.srgb?).to be false
|
290
|
+
expect(assembly_image.has_profile?).to be false
|
291
|
+
expect(assembly_image.vips_image.interpretation).to eq :'b-w'
|
292
|
+
|
293
|
+
expect(result.path).to eq jp2_output_file
|
294
|
+
expect(result.mimetype).to eq 'image/jp2'
|
295
|
+
|
296
|
+
# check srgb on temporary tiff (due to CI libvips not speaking jp2)
|
297
|
+
tmp_tiff_image = Assembly::Image.new(jp2creator.send(:make_tmp_tiff))
|
298
|
+
expect(tmp_tiff_image.srgb?).to be false
|
299
|
+
expect(tmp_tiff_image.has_profile?).to be false
|
300
|
+
vips_for_tmp_tiff = tmp_tiff_image.vips_image
|
301
|
+
expect(vips_for_tmp_tiff.bands).to eq 1
|
302
|
+
expect(vips_for_tmp_tiff.interpretation).to eq :'b-w'
|
303
|
+
end
|
304
|
+
end
|
305
|
+
|
306
|
+
context 'when given a color tif but with grayscale image data (3 channels and 8 bits per pixel)' do
|
307
|
+
let(:input_path) { File.join(TEST_INPUT_DIR, 'color_gray.tif') }
|
308
|
+
|
309
|
+
before do
|
310
|
+
# this is bands: 3 with 8 bits per pixel
|
311
|
+
generate_test_image(input_path, color: 'grey')
|
312
|
+
end
|
313
|
+
|
314
|
+
it 'creates color jp2 without ICC profile' do
|
315
|
+
expect(File).to exist input_path # test image was generated
|
316
|
+
expect(File).not_to exist jp2_output_file
|
317
|
+
expect(assembly_image.srgb?).to be true
|
318
|
+
expect(assembly_image.has_profile?).to be false
|
319
|
+
|
320
|
+
expect(result.path).to eq jp2_output_file
|
321
|
+
expect(result.mimetype).to eq 'image/jp2'
|
322
|
+
|
323
|
+
# check srgb on temporary tiff (due to CI libvips not speaking jp2)
|
324
|
+
tmp_tiff_image = Assembly::Image.new(jp2creator.send(:make_tmp_tiff))
|
325
|
+
expect(tmp_tiff_image.srgb?).to be true
|
326
|
+
expect(tmp_tiff_image.has_profile?).to be false
|
327
|
+
vips_for_tmp_tiff = tmp_tiff_image.vips_image
|
328
|
+
expect(vips_for_tmp_tiff.bands).to eq 3
|
329
|
+
end
|
330
|
+
end
|
331
|
+
end
|
332
|
+
|
333
|
+
describe '#make_tmp_tiff' do
|
334
|
+
subject(:tiff_file) { jp2creator.send(:make_tmp_tiff) }
|
41
335
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
expect(result).to be_a_kind_of Assembly::Image
|
46
|
-
expect(result.path).to eq TEST_JP2_OUTPUT_FILE
|
47
|
-
expect(TEST_JP2_OUTPUT_FILE).to be_a_jp2
|
336
|
+
let(:input_path) { 'spec/test_data/color_rgb_srgb_rot90cw.tif' }
|
337
|
+
let(:vips_output) { Vips::Image.new_from_file(tiff_file) }
|
338
|
+
let(:plum) { [94.0, 58.0, 101.0] }
|
48
339
|
|
49
|
-
|
50
|
-
|
51
|
-
|
340
|
+
context 'when given a tiff with a rotation hint' do
|
341
|
+
it 'rotates it' do
|
342
|
+
expect(Vips::Image.new_from_file(input_path).getpoint(3, 3)).not_to eq plum
|
343
|
+
expect(vips_output.getpoint(3, 3)).to eq plum
|
344
|
+
end
|
52
345
|
end
|
53
346
|
end
|
54
347
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require 'fileutils'
|
5
|
+
|
6
|
+
RSpec.describe Assembly::Image do
|
7
|
+
let(:assembly_image) { described_class.new(input_path) }
|
8
|
+
let(:input_path) { TEST_TIF_INPUT_FILE }
|
9
|
+
|
10
|
+
before { cleanup }
|
11
|
+
|
12
|
+
describe '#jp2_filename' do
|
13
|
+
it 'indicates the default jp2 filename' do
|
14
|
+
expect(assembly_image.jp2_filename).to eq input_path.gsub('.tif', '.jp2')
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'with a file with no extension' do
|
18
|
+
let(:input_path) { '/path/to/a/file_with_no_extension' }
|
19
|
+
|
20
|
+
it 'indicates the default jp2 filename' do
|
21
|
+
expect(assembly_image.jp2_filename).to eq '/path/to/a/file_with_no_extension.jp2'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -5,20 +5,14 @@ SimpleCov.start do
|
|
5
5
|
add_filter 'spec'
|
6
6
|
end
|
7
7
|
|
8
|
-
bootfile = File.expand_path(File.dirname(__FILE__)
|
8
|
+
bootfile = File.expand_path("#{File.dirname(__FILE__)}/../config/boot")
|
9
9
|
require bootfile
|
10
|
-
require 'ruby-vips'
|
11
10
|
require 'pry-byebug'
|
12
11
|
|
13
12
|
TEST_INPUT_DIR = File.join(Assembly::PATH_TO_IMAGE_GEM, 'spec', 'test_data', 'input')
|
14
13
|
TEST_OUTPUT_DIR = File.join(Assembly::PATH_TO_IMAGE_GEM, 'spec', 'test_data', 'output')
|
15
14
|
TEST_TIF_INPUT_FILE = File.join(TEST_INPUT_DIR, 'test.tif')
|
16
15
|
TEST_JPEG_INPUT_FILE = File.join(TEST_INPUT_DIR, 'test.jpg')
|
17
|
-
TEST_JP2_INPUT_FILE = File.join(TEST_INPUT_DIR, 'test.jp2')
|
18
|
-
TEST_JP2_OUTPUT_FILE = File.join(TEST_OUTPUT_DIR, 'test.jp2')
|
19
|
-
TEST_PROFILE_DIR = File.join(Assembly::PATH_TO_IMAGE_GEM, 'profiles')
|
20
|
-
TEST_DATA_DIR = File.join(Assembly::PATH_TO_IMAGE_GEM, 'spec', 'test_data')
|
21
|
-
TEST_DRUID = 'nx288wh8889'
|
22
16
|
|
23
17
|
RSpec.configure do |config|
|
24
18
|
# rspec-expectations config goes here. You can use an alternate
|
@@ -175,10 +169,10 @@ def generate_test_image(file, params = {})
|
|
175
169
|
|
176
170
|
temp_array = color_gauge_values(cg_type)
|
177
171
|
temp_image = Vips::Image.black(width, height, bands: temp_array.first.size)
|
178
|
-
|
172
|
+
5.times do |i|
|
179
173
|
b = (box_size * i) + (line_size * (i + 1))
|
180
174
|
# d = b + box_size - line_size
|
181
|
-
|
175
|
+
6.times do |j|
|
182
176
|
a = (box_size * j) + (line_size * (j + 1))
|
183
177
|
# c = a + box_size - line_size
|
184
178
|
colors = temp_array.shift
|
@@ -204,7 +198,7 @@ def generate_test_image(file, params = {})
|
|
204
198
|
|
205
199
|
options = {}
|
206
200
|
unless profile.nil?
|
207
|
-
profile_file = File.join(
|
201
|
+
profile_file = File.join(Assembly::PATH_TO_IMAGE_GEM, 'profiles', "#{profile}.icc")
|
208
202
|
options.merge!(profile: profile_file)
|
209
203
|
end
|
210
204
|
|
@@ -235,14 +229,3 @@ def remove_files(dir)
|
|
235
229
|
File.delete(fn) if !File.directory?(fn) && File.basename(fn) != '.empty'
|
236
230
|
end
|
237
231
|
end
|
238
|
-
|
239
|
-
RSpec::Matchers.define :be_a_jp2 do
|
240
|
-
match do |actual|
|
241
|
-
if File.exist?(actual)
|
242
|
-
exif = MiniExiftool.new actual
|
243
|
-
exif['mimetype'] == 'image/jp2'
|
244
|
-
else
|
245
|
-
false
|
246
|
-
end
|
247
|
-
end
|
248
|
-
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: assembly-image
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Mangiafico
|
@@ -11,42 +11,36 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: exe
|
13
13
|
cert_chain: []
|
14
|
-
date:
|
14
|
+
date: 2023-09-21 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
|
-
name:
|
17
|
+
name: activesupport
|
18
18
|
requirement: !ruby/object:Gem::Requirement
|
19
19
|
requirements:
|
20
|
-
- - "
|
20
|
+
- - ">"
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version:
|
22
|
+
version: '6.1'
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
requirements:
|
27
|
-
- - "
|
27
|
+
- - ">"
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version:
|
29
|
+
version: '6.1'
|
30
30
|
- !ruby/object:Gem::Dependency
|
31
|
-
name:
|
31
|
+
name: assembly-objectfile
|
32
32
|
requirement: !ruby/object:Gem::Requirement
|
33
33
|
requirements:
|
34
34
|
- - ">="
|
35
35
|
- !ruby/object:Gem::Version
|
36
|
-
version:
|
37
|
-
- - "<"
|
38
|
-
- !ruby/object:Gem::Version
|
39
|
-
version: '3'
|
36
|
+
version: 1.6.4
|
40
37
|
type: :runtime
|
41
38
|
prerelease: false
|
42
39
|
version_requirements: !ruby/object:Gem::Requirement
|
43
40
|
requirements:
|
44
41
|
- - ">="
|
45
42
|
- !ruby/object:Gem::Version
|
46
|
-
version:
|
47
|
-
- - "<"
|
48
|
-
- !ruby/object:Gem::Version
|
49
|
-
version: '3'
|
43
|
+
version: 1.6.4
|
50
44
|
- !ruby/object:Gem::Dependency
|
51
45
|
name: ruby-vips
|
52
46
|
requirement: !ruby/object:Gem::Requirement
|
@@ -145,20 +139,6 @@ dependencies:
|
|
145
139
|
- - ">="
|
146
140
|
- !ruby/object:Gem::Version
|
147
141
|
version: '0'
|
148
|
-
- !ruby/object:Gem::Dependency
|
149
|
-
name: yard
|
150
|
-
requirement: !ruby/object:Gem::Requirement
|
151
|
-
requirements:
|
152
|
-
- - ">="
|
153
|
-
- !ruby/object:Gem::Version
|
154
|
-
version: '0'
|
155
|
-
type: :development
|
156
|
-
prerelease: false
|
157
|
-
version_requirements: !ruby/object:Gem::Requirement
|
158
|
-
requirements:
|
159
|
-
- - ">="
|
160
|
-
- !ruby/object:Gem::Version
|
161
|
-
version: '0'
|
162
142
|
description: Contains classes to create derivative image files and perform other image
|
163
143
|
operations
|
164
144
|
email:
|
@@ -175,6 +155,7 @@ files:
|
|
175
155
|
- ".rubocop_todo.yml"
|
176
156
|
- ".rvmrc.example"
|
177
157
|
- Gemfile
|
158
|
+
- Gemfile.lock
|
178
159
|
- LICENSE
|
179
160
|
- README.md
|
180
161
|
- Rakefile
|
@@ -182,25 +163,16 @@ files:
|
|
182
163
|
- bin/console
|
183
164
|
- config/boot.rb
|
184
165
|
- lib/assembly-image.rb
|
185
|
-
- lib/assembly
|
186
|
-
- lib/assembly
|
187
|
-
- lib/assembly-image/jp2_creator.rb
|
166
|
+
- lib/assembly/image.rb
|
167
|
+
- lib/assembly/image/jp2_creator.rb
|
188
168
|
- profiles/AdobeRGB1998.icc
|
189
169
|
- profiles/DotGain20.icc
|
190
170
|
- profiles/cmyk.icc
|
191
171
|
- profiles/sRGBIEC6196621.icc
|
192
172
|
- spec/assembly/image/jp2_creator_spec.rb
|
193
|
-
- spec/image_spec.rb
|
194
|
-
- spec/images_spec.rb
|
173
|
+
- spec/assembly/image_spec.rb
|
195
174
|
- spec/spec_helper.rb
|
196
|
-
- spec/test_data/color_cmyk_tagged.tif
|
197
|
-
- spec/test_data/color_cmyk_untagged.tif
|
198
|
-
- spec/test_data/color_rgb_adobergb1998_lzw.tif
|
199
|
-
- spec/test_data/color_rgb_srgb.jpg
|
200
|
-
- spec/test_data/color_rgb_srgb.tif
|
201
175
|
- spec/test_data/color_rgb_srgb_rot90cw.tif
|
202
|
-
- spec/test_data/color_rgb_untagged.tif
|
203
|
-
- spec/test_data/gray_gray_untagged.tif
|
204
176
|
- spec/test_data/input/.empty
|
205
177
|
- spec/test_data/output/.empty
|
206
178
|
homepage: ''
|
@@ -222,7 +194,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
222
194
|
- !ruby/object:Gem::Version
|
223
195
|
version: '0'
|
224
196
|
requirements: []
|
225
|
-
rubygems_version: 3.
|
197
|
+
rubygems_version: 3.3.7
|
226
198
|
signing_key:
|
227
199
|
specification_version: 4
|
228
200
|
summary: Ruby immplementation of image services needed to prepare objects to be accessioned
|