assembly-image 2.0.0 → 2.1.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/.circleci/config.yml +1 -1
- data/.gitignore +0 -1
- data/.rubocop.yml +21 -3
- data/.rubocop_todo.yml +5 -55
- data/.rvmrc.example +1 -1
- data/Gemfile.lock +105 -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 +58 -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 +2 -19
- metadata +14 -42
- 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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '088a4b9c59b50f893f7b50c16898321770006b4ab22dc08a8ddd70cdba9a15da'
|
4
|
+
data.tar.gz: f22bf6d6acbd4d6885e2102526e7c5e0ac76b93af71eff0d2237d32334afd223
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 91f0be3622982ad69823a45eca8111d05756e0442cd7d7aa16cb8099e71ee2e95c21f17c7f14b7ccab04c11724233c9a9739e24f8b8302f07f42b16738c6400e
|
7
|
+
data.tar.gz: d1ab206c475413496a6add9376cb246705df18a3142bdc32189b202e31af698b8cfded84464d00e94357fc08396ab142270043b3b862cc0d68cd57834863b649
|
data/.circleci/config.yml
CHANGED
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
@@ -22,11 +22,16 @@ Naming/FileName:
|
|
22
22
|
Exclude:
|
23
23
|
- lib/assembly-image.rb
|
24
24
|
|
25
|
+
Naming/PredicateName:
|
26
|
+
ForbiddenPrefixes:
|
27
|
+
- is_
|
28
|
+
|
29
|
+
RSpec/MultipleMemoizedHelpers:
|
30
|
+
Enabled: false
|
31
|
+
|
25
32
|
Style/WordArray:
|
26
33
|
Enabled: false
|
27
34
|
|
28
|
-
Gemspec/DateAssignment: # new in 1.10
|
29
|
-
Enabled: true
|
30
35
|
Gemspec/RequireMFA: # new in 1.23
|
31
36
|
Enabled: true
|
32
37
|
Layout/LineEndStringConcatenationIndentation: # new in 1.18
|
@@ -141,7 +146,7 @@ RSpec/SubjectDeclaration: # new in 2.5
|
|
141
146
|
RSpec/FactoryBot/SyntaxMethods: # new in 2.7
|
142
147
|
Enabled: true
|
143
148
|
RSpec/Rails/AvoidSetupHook: # new in 2.4
|
144
|
-
Enabled:
|
149
|
+
Enabled: false
|
145
150
|
|
146
151
|
Lint/RefinementImportMethods: # new in 1.27
|
147
152
|
Enabled: true
|
@@ -166,3 +171,16 @@ RSpec/VerifiedDoubleReference: # new in 2.10.0
|
|
166
171
|
|
167
172
|
Gemspec/DeprecatedAttributeAssignment: # new in 1.30
|
168
173
|
Enabled: true
|
174
|
+
Layout/LineContinuationLeadingSpace: # new in 1.31
|
175
|
+
Enabled: true
|
176
|
+
Layout/LineContinuationSpacing: # new in 1.31
|
177
|
+
Enabled: true
|
178
|
+
Lint/ConstantOverwrittenInRescue: # new in 1.31
|
179
|
+
Enabled: true
|
180
|
+
Lint/NonAtomicFileOperation: # new in 1.31
|
181
|
+
Enabled: true
|
182
|
+
|
183
|
+
RSpec/Capybara/SpecificMatcher: # new in 2.12
|
184
|
+
Enabled: true
|
185
|
+
RSpec/Rails/HaveHttpStatus: # new in 2.12
|
186
|
+
Enabled: false
|
data/.rubocop_todo.yml
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# This configuration was generated by
|
2
2
|
# `rubocop --auto-gen-config`
|
3
|
-
# on 2022-
|
3
|
+
# on 2022-07-19 17:18:47 UTC using RuboCop version 1.31.2.
|
4
4
|
# The point is for the user to remove these configuration records
|
5
5
|
# one by one as the offenses are removed from the code base.
|
6
6
|
# Note that changes in the inspected code, or installation of new
|
@@ -13,66 +13,16 @@ Gemspec/RequiredRubyVersion:
|
|
13
13
|
Exclude:
|
14
14
|
- 'assembly-image.gemspec'
|
15
15
|
|
16
|
-
# Offense count: 2
|
17
|
-
# This cop supports safe autocorrection (--autocorrect).
|
18
|
-
Lint/RedundantCopDisableDirective:
|
19
|
-
Exclude:
|
20
|
-
- 'lib/assembly-image/image.rb'
|
21
|
-
- 'lib/assembly-image/images.rb'
|
22
|
-
|
23
16
|
# Offense count: 2
|
24
17
|
# Configuration parameters: IgnoredMethods, CountRepeatedAttributes.
|
25
18
|
Metrics/AbcSize:
|
26
19
|
Max: 20
|
27
20
|
|
28
|
-
# Offense count:
|
21
|
+
# Offense count: 11
|
29
22
|
# Configuration parameters: CountAsOne.
|
30
23
|
RSpec/ExampleLength:
|
31
|
-
Max: 15
|
32
|
-
|
33
|
-
# Offense count: 2
|
34
|
-
# Configuration parameters: Include, CustomTransform, IgnoreMethods, SpecSuffixOnly.
|
35
|
-
# Include: **/*_spec*rb*, **/spec/**/*
|
36
|
-
RSpec/FilePath:
|
37
|
-
Exclude:
|
38
|
-
- 'spec/image_spec.rb'
|
39
|
-
- 'spec/images_spec.rb'
|
40
|
-
|
41
|
-
# Offense count: 21
|
42
|
-
RSpec/MultipleExpectations:
|
43
24
|
Max: 13
|
44
25
|
|
45
|
-
# Offense count:
|
46
|
-
RSpec/
|
47
|
-
|
48
|
-
- 'spec/image_spec.rb'
|
49
|
-
- 'spec/images_spec.rb'
|
50
|
-
|
51
|
-
# Offense count: 3
|
52
|
-
Style/CombinableLoops:
|
53
|
-
Exclude:
|
54
|
-
- 'spec/images_spec.rb'
|
55
|
-
|
56
|
-
# Offense count: 1
|
57
|
-
# This cop supports unsafe autocorrection (--autocorrect-all).
|
58
|
-
Style/GlobalStdStream:
|
59
|
-
Exclude:
|
60
|
-
- 'lib/assembly-image/images.rb'
|
61
|
-
|
62
|
-
# Offense count: 1
|
63
|
-
# Configuration parameters: AllowedMethods.
|
64
|
-
# AllowedMethods: respond_to_missing?
|
65
|
-
Style/OptionalBooleanParameter:
|
66
|
-
Exclude:
|
67
|
-
- 'lib/assembly-image/image.rb'
|
68
|
-
|
69
|
-
# Offense count: 7
|
70
|
-
# This cop supports unsafe autocorrection (--autocorrect-all).
|
71
|
-
# Configuration parameters: Mode.
|
72
|
-
Style/StringConcatenation:
|
73
|
-
Exclude:
|
74
|
-
- 'bin/console'
|
75
|
-
- 'config/boot.rb'
|
76
|
-
- 'lib/assembly-image.rb'
|
77
|
-
- 'lib/assembly-image/images.rb'
|
78
|
-
- 'spec/spec_helper.rb'
|
26
|
+
# Offense count: 15
|
27
|
+
RSpec/MultipleExpectations:
|
28
|
+
Max: 11
|
data/.rvmrc.example
CHANGED
@@ -1 +1 @@
|
|
1
|
-
rvm use 1.
|
1
|
+
rvm use 3.1.0@assembly-image --create
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
assembly-image (2.1.0)
|
5
|
+
activesupport (> 6.1)
|
6
|
+
assembly-objectfile (>= 1.6.4)
|
7
|
+
ruby-vips (>= 2.0)
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: http://rubygems.org/
|
11
|
+
specs:
|
12
|
+
activesupport (7.0.3.1)
|
13
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
14
|
+
i18n (>= 1.6, < 2)
|
15
|
+
minitest (>= 5.1)
|
16
|
+
tzinfo (~> 2.0)
|
17
|
+
assembly-objectfile (2.1.0)
|
18
|
+
activesupport (>= 5.2.0)
|
19
|
+
mime-types (> 3)
|
20
|
+
mini_exiftool
|
21
|
+
ast (2.4.2)
|
22
|
+
byebug (11.1.3)
|
23
|
+
coderay (1.1.3)
|
24
|
+
concurrent-ruby (1.1.10)
|
25
|
+
diff-lcs (1.5.0)
|
26
|
+
docile (1.4.0)
|
27
|
+
ffi (1.15.5)
|
28
|
+
i18n (1.12.0)
|
29
|
+
concurrent-ruby (~> 1.0)
|
30
|
+
json (2.6.2)
|
31
|
+
method_source (1.0.0)
|
32
|
+
mime-types (3.4.1)
|
33
|
+
mime-types-data (~> 3.2015)
|
34
|
+
mime-types-data (3.2022.0105)
|
35
|
+
mini_exiftool (2.10.2)
|
36
|
+
minitest (5.16.2)
|
37
|
+
parallel (1.22.1)
|
38
|
+
parser (3.1.2.0)
|
39
|
+
ast (~> 2.4.1)
|
40
|
+
pry (0.13.1)
|
41
|
+
coderay (~> 1.1)
|
42
|
+
method_source (~> 1.0)
|
43
|
+
pry-byebug (3.9.0)
|
44
|
+
byebug (~> 11.0)
|
45
|
+
pry (~> 0.13.0)
|
46
|
+
rainbow (3.1.1)
|
47
|
+
rake (13.0.6)
|
48
|
+
regexp_parser (2.5.0)
|
49
|
+
rexml (3.2.5)
|
50
|
+
rspec (3.11.0)
|
51
|
+
rspec-core (~> 3.11.0)
|
52
|
+
rspec-expectations (~> 3.11.0)
|
53
|
+
rspec-mocks (~> 3.11.0)
|
54
|
+
rspec-core (3.11.0)
|
55
|
+
rspec-support (~> 3.11.0)
|
56
|
+
rspec-expectations (3.11.0)
|
57
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
58
|
+
rspec-support (~> 3.11.0)
|
59
|
+
rspec-mocks (3.11.1)
|
60
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
61
|
+
rspec-support (~> 3.11.0)
|
62
|
+
rspec-support (3.11.0)
|
63
|
+
rubocop (1.31.2)
|
64
|
+
json (~> 2.3)
|
65
|
+
parallel (~> 1.10)
|
66
|
+
parser (>= 3.1.0.0)
|
67
|
+
rainbow (>= 2.2.2, < 4.0)
|
68
|
+
regexp_parser (>= 1.8, < 3.0)
|
69
|
+
rexml (>= 3.2.5, < 4.0)
|
70
|
+
rubocop-ast (>= 1.18.0, < 2.0)
|
71
|
+
ruby-progressbar (~> 1.7)
|
72
|
+
unicode-display_width (>= 1.4.0, < 3.0)
|
73
|
+
rubocop-ast (1.19.1)
|
74
|
+
parser (>= 3.1.1.0)
|
75
|
+
rubocop-rspec (2.12.1)
|
76
|
+
rubocop (~> 1.31)
|
77
|
+
ruby-progressbar (1.11.0)
|
78
|
+
ruby-vips (2.1.4)
|
79
|
+
ffi (~> 1.12)
|
80
|
+
simplecov (0.21.2)
|
81
|
+
docile (~> 1.1)
|
82
|
+
simplecov-html (~> 0.11)
|
83
|
+
simplecov_json_formatter (~> 0.1)
|
84
|
+
simplecov-html (0.12.3)
|
85
|
+
simplecov_json_formatter (0.1.4)
|
86
|
+
tzinfo (2.0.5)
|
87
|
+
concurrent-ruby (~> 1.0)
|
88
|
+
unicode-display_width (2.2.0)
|
89
|
+
|
90
|
+
PLATFORMS
|
91
|
+
x86_64-darwin-19
|
92
|
+
x86_64-darwin-21
|
93
|
+
x86_64-linux
|
94
|
+
|
95
|
+
DEPENDENCIES
|
96
|
+
assembly-image!
|
97
|
+
pry-byebug
|
98
|
+
rake
|
99
|
+
rspec (~> 3.0)
|
100
|
+
rubocop
|
101
|
+
rubocop-rspec
|
102
|
+
simplecov
|
103
|
+
|
104
|
+
BUNDLED WITH
|
105
|
+
2.3.17
|
data/README.md
CHANGED
@@ -6,24 +6,16 @@
|
|
6
6
|
# Assembly Image Gem
|
7
7
|
|
8
8
|
## Overview
|
9
|
-
This gem contains classes used by the Stanford University Digital Library to
|
10
|
-
perform image operations necessary for accessioning of content.
|
9
|
+
This gem contains classes used by the Stanford University Digital Library to create JP2 image derivatives.
|
11
10
|
|
12
|
-
Requires image processing software - see
|
11
|
+
Requires image processing software - see [prerequisites section](#prerequisites) below.
|
13
12
|
|
14
13
|
## Notes
|
15
14
|
|
16
15
|
1. The gem assumes that the user context in which it is executed has write access to the 'tmp' folder.
|
17
|
-
This is
|
18
|
-
|
19
|
-
is
|
20
|
-
If you know there are color profiles which are commonly used, it is better to
|
21
|
-
capture them in the gem itself in the profile folder so they can be re-used
|
22
|
-
and do not need to be extracted.
|
23
|
-
1. If any errors occur during JP2 generation for any reason, a runtime exception will be thrown with a description of the error.
|
24
|
-
2. If an image is passed in with a color profile that cannot be determined by examining the exif header data, an exception will be thrown.
|
25
|
-
|
26
|
-
This can commonly occur in basic test TIFs that are black/white and have no profile, so beware during testing.
|
16
|
+
This is to create the temporary tiffs used; we need temporary tiffs to reliably compress the image using KDUcompress, which doesn’t support arbitrary image types
|
17
|
+
2. If any errors occur during JP2 generation for any reason, a runtime exception will be thrown with a description of the error.
|
18
|
+
3. If an image is passed in with a color profile that cannot be determined, an exception will be thrown. This can commonly occur in basic test TIFs that are black/white and have no profile, so beware during testing.
|
27
19
|
|
28
20
|
## Usage
|
29
21
|
|
@@ -31,45 +23,29 @@ To use the JP2 creation method, you first instantiate the image object with an i
|
|
31
23
|
|
32
24
|
```ruby
|
33
25
|
require 'assembly-image'
|
34
|
-
|
35
|
-
|
36
|
-
output = input.create_jp2(:output=>'/full/path/to/output.jp2') # generate a new JP2 in the specified location
|
37
|
-
puts output.exif # show exif header information for the JP2
|
26
|
+
input_image = Assembly::Image.new('/full/path/to/file.tif')
|
27
|
+
output = input_image.create_jp2(output: '/full/path/to/output.jp2') # generate a new JP2 in the specified location
|
38
28
|
```
|
39
29
|
|
40
30
|
## Running tests
|
41
31
|
|
42
32
|
```bash
|
43
|
-
bundle exec
|
44
|
-
```
|
45
|
-
|
46
|
-
## Generate documentation
|
47
|
-
To generate documentation into the "doc" folder:
|
48
|
-
|
49
|
-
```bash
|
50
|
-
yard
|
51
|
-
```
|
52
|
-
|
53
|
-
To keep a local server running with up to date code documentation that you can view in your browser:
|
54
|
-
|
55
|
-
```bash
|
56
|
-
yard server --reload
|
33
|
+
bundle exec rspec
|
57
34
|
```
|
58
35
|
|
59
36
|
## Prerequisites
|
60
37
|
|
61
38
|
1. Kakadu Proprietary Software Binaries - for JP2 generation
|
62
|
-
1.
|
63
|
-
1. Exiftool
|
39
|
+
1. Libvips
|
40
|
+
1. Exiftool - upstream dependency of assembly-objectfile (used by specs to check mimetype of produced jp2, and because there is no libvips package available for circleci that speaks jp2)
|
64
41
|
|
65
42
|
### Kakadu
|
66
43
|
|
67
44
|
Download and install demonstration binaries from Kakadu:
|
68
45
|
http://kakadusoftware.com/downloads/
|
69
46
|
|
70
|
-
NOTE: If you have upgrade to El Capitan on OS X, you will need to donwload and re-install the latest version of Kakadu, due to changes made with SIP. These changes moved the old executable binaries to an inaccessible location.
|
71
|
-
|
72
47
|
### Libvips
|
48
|
+
Note: libvips may require a significant amount of space for temporary files. The location for this can be controlled by the TMPDIR environment variable.
|
73
49
|
|
74
50
|
#### Mac
|
75
51
|
|
@@ -79,7 +55,7 @@ brew install libvips
|
|
79
55
|
|
80
56
|
### Exiftool
|
81
57
|
|
82
|
-
####
|
58
|
+
#### Linux
|
83
59
|
Download latest version from: http://www.sno.phy.queensu.ca/~phil/exiftool
|
84
60
|
|
85
61
|
```bash
|
data/assembly-image.gemspec
CHANGED
@@ -4,7 +4,7 @@ $LOAD_PATH.push File.expand_path('lib', __dir__)
|
|
4
4
|
|
5
5
|
Gem::Specification.new do |s|
|
6
6
|
s.name = 'assembly-image'
|
7
|
-
s.version = '2.
|
7
|
+
s.version = '2.1.0'
|
8
8
|
s.authors = ['Peter Mangiafico', 'Renzo Sanchez-Silva', 'Monty Hindman', 'Tony Calavano']
|
9
9
|
s.email = ['pmangiafico@stanford.edu']
|
10
10
|
s.homepage = ''
|
@@ -17,8 +17,8 @@ Gem::Specification.new do |s|
|
|
17
17
|
s.executables = s.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
18
18
|
s.require_paths = ['lib']
|
19
19
|
|
20
|
+
s.add_dependency 'activesupport', '> 6.1'
|
20
21
|
s.add_dependency 'assembly-objectfile', '>= 1.6.4'
|
21
|
-
s.add_dependency 'mini_exiftool', '>= 1.6', '< 3'
|
22
22
|
s.add_dependency 'ruby-vips', '>= 2.0'
|
23
23
|
|
24
24
|
s.add_development_dependency 'pry-byebug'
|
@@ -27,5 +27,4 @@ Gem::Specification.new do |s|
|
|
27
27
|
s.add_development_dependency 'rubocop'
|
28
28
|
s.add_development_dependency 'rubocop-rspec'
|
29
29
|
s.add_development_dependency 'simplecov'
|
30
|
-
s.add_development_dependency 'yard'
|
31
30
|
end
|
data/bin/console
CHANGED
data/config/boot.rb
CHANGED
@@ -2,9 +2,9 @@
|
|
2
2
|
|
3
3
|
require 'rubygems'
|
4
4
|
|
5
|
-
project_root = File.expand_path(File.dirname(__FILE__)
|
5
|
+
project_root = File.expand_path("#{File.dirname(__FILE__)}/..")
|
6
6
|
|
7
7
|
# Load config for current environment.
|
8
|
-
$LOAD_PATH.unshift(project_root
|
8
|
+
$LOAD_PATH.unshift("#{project_root}/lib")
|
9
9
|
|
10
10
|
require 'assembly-image'
|
@@ -3,6 +3,7 @@
|
|
3
3
|
require 'assembly-objectfile'
|
4
4
|
require 'tempfile'
|
5
5
|
require 'English' # see https://github.com/rubocop-hq/rubocop/issues/1747 (not #MAGA related)
|
6
|
+
require 'active_support/core_ext/module/delegation'
|
6
7
|
|
7
8
|
module Assembly
|
8
9
|
class Image < Assembly::ObjectFile
|
@@ -14,47 +15,46 @@ module Assembly
|
|
14
15
|
# @return [Assembly::Image] object containing the generated JP2 file
|
15
16
|
#
|
16
17
|
# @param [Assembly::Image] the image file
|
17
|
-
# @param [
|
18
|
-
#
|
19
|
-
#
|
20
|
-
# * :tmp_folder => the temporary folder to use when creating the jp2 (default: '/tmp'); also used by imagemagick
|
18
|
+
# @param [String] output path to the output JP2 file (default: mirrors the source file name and path, but with a .jp2 extension)
|
19
|
+
# @param [Boolean] overwrite if set to false, an existing JP2 file with the same name won't be overwritten (default: false)
|
20
|
+
# @param [Dir] tmp_folder the temporary folder to use when creating the jp2 (default: '/tmp'); also used by imagemagick
|
21
21
|
#
|
22
22
|
# Example:
|
23
23
|
# source_img = Assembly::Image.new('/input/path_to_file.tif')
|
24
|
-
# derivative_img = source_img.create_jp2(:
|
24
|
+
# derivative_img = source_img.create_jp2(overwrite: true)
|
25
25
|
# puts derivative_img.mimetype # 'image/jp2'
|
26
26
|
# puts derivative_image.path # '/input/path_to_file.jp2'
|
27
|
-
def self.create(image,
|
28
|
-
new(image,
|
27
|
+
def self.create(image, **args)
|
28
|
+
new(image, **args).create
|
29
29
|
end
|
30
30
|
|
31
|
-
def initialize(image,
|
31
|
+
def initialize(image, overwrite: false, output: image.jp2_filename, tmp_folder: Dir.tmpdir)
|
32
32
|
@image = image
|
33
|
-
@output_path =
|
34
|
-
@tmp_folder =
|
35
|
-
@overwrite =
|
36
|
-
@params = params
|
33
|
+
@output_path = output
|
34
|
+
@tmp_folder = tmp_folder
|
35
|
+
@overwrite = overwrite
|
37
36
|
end
|
38
37
|
|
39
|
-
attr_reader :image, :output_path, :tmp_folder, :
|
38
|
+
attr_reader :image, :output_path, :tmp_folder, :tmp_tiff_path
|
39
|
+
|
40
|
+
delegate :vips_image, to: :image
|
40
41
|
|
41
42
|
# @return [Assembly::Image] object containing the generated JP2 file
|
42
43
|
def create
|
43
44
|
create_jp2_checks
|
44
45
|
|
45
|
-
#
|
46
|
-
|
47
|
-
@tmp_path = make_tmp_tiff(tmp_folder: tmp_folder)
|
46
|
+
# KDUcompress doesn’t support arbitrary image types, so we make a temporary tiff
|
47
|
+
@tmp_tiff_path = make_tmp_tiff
|
48
48
|
|
49
|
-
jp2_command = jp2_create_command(source_path:
|
49
|
+
jp2_command = jp2_create_command(source_path: tmp_tiff_path, output: output_path)
|
50
50
|
result = `#{jp2_command}`
|
51
51
|
unless $CHILD_STATUS.success?
|
52
52
|
# Clean up any partial result
|
53
|
-
|
53
|
+
FileUtils.rm_rf(output_path)
|
54
54
|
raise "JP2 creation command failed: #{jp2_command} with result #{result}"
|
55
55
|
end
|
56
56
|
|
57
|
-
File.delete(
|
57
|
+
File.delete(tmp_tiff_path) unless tmp_tiff_path.nil?
|
58
58
|
|
59
59
|
# create output response object, which is an Assembly::Image type object
|
60
60
|
Image.new(output_path)
|
@@ -68,8 +68,10 @@ module Assembly
|
|
68
68
|
|
69
69
|
def jp2_create_command(source_path:, output:)
|
70
70
|
options = []
|
71
|
-
#
|
72
|
-
|
71
|
+
# CMYK becomes sRGB in make_tmp_tiff, so jp2_space option will be set for sRGB and CMYK
|
72
|
+
# TODO: we're not sure at this time what happens for grayscale (or what Tony C. wants for grayscale)
|
73
|
+
# see https://github.com/sul-dlss/assembly-image/issues/98
|
74
|
+
options << '-jp2_space sRGB' if image.srgb?
|
73
75
|
options += KDU_COMPRESS_DEFAULT_OPTIONS
|
74
76
|
options << "Clayers=#{layers}"
|
75
77
|
"kdu_compress #{options.join(' ')} -i '#{source_path}' -o '#{output}' 2>&1"
|
@@ -100,32 +102,24 @@ module Assembly
|
|
100
102
|
raise SecurityError, 'cannot recreate jp2 over itself' if overwrite? && image.mimetype == 'image/jp2' && output_path == image.path
|
101
103
|
end
|
102
104
|
|
103
|
-
# Bigtiff needs to be used if size of image exceeds 2^32 bytes.
|
104
|
-
def need_bigtiff?
|
105
|
-
image.image_data_size >= 2**32
|
106
|
-
end
|
107
|
-
|
108
105
|
# We do this because we need to reliably compress the tiff and KDUcompress doesn’t support arbitrary image types
|
109
106
|
# rubocop:disable Metrics/MethodLength
|
110
|
-
def make_tmp_tiff
|
111
|
-
tmp_folder
|
112
|
-
raise "tmp_folder #{tmp_folder} does not exists" unless File.exist?(tmp_folder)
|
107
|
+
def make_tmp_tiff
|
108
|
+
raise "tmp_folder #{tmp_folder} does not exist" unless File.exist?(tmp_folder)
|
113
109
|
|
114
110
|
# make temp tiff filename
|
115
111
|
tmp_tiff_file = Tempfile.new(['assembly-image', '.tif'], tmp_folder)
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
vips_image.tiffsave(tmp_path, bigtiff: need_bigtiff?)
|
128
|
-
tmp_path
|
112
|
+
result_path = tmp_tiff_file.path
|
113
|
+
tmp_tiff_image = if vips_image.interpretation.eql?(:cmyk)
|
114
|
+
vips_image.icc_transform(SRGB_ICC, input_profile: CMYK_ICC)
|
115
|
+
elsif image.has_profile?
|
116
|
+
vips_image.icc_transform(SRGB_ICC, embedded: true)
|
117
|
+
else
|
118
|
+
vips_image
|
119
|
+
end
|
120
|
+
|
121
|
+
tmp_tiff_image.tiffsave(result_path, bigtiff: true) # Use bigtiff so we can support images > 4GB
|
122
|
+
result_path
|
129
123
|
end
|
130
124
|
# rubocop:enable Metrics/MethodLength
|
131
125
|
end
|
@@ -0,0 +1,58 @@
|
|
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
|
+
# autorot will only affect images that need rotation: https://www.libvips.org/API/current/libvips-conversion.html#vips-autorot
|
46
|
+
@vips_image ||= Vips::Image.new_from_file(path).autorot
|
47
|
+
end
|
48
|
+
|
49
|
+
def srgb?
|
50
|
+
vips_image.interpretation == :srgb
|
51
|
+
end
|
52
|
+
|
53
|
+
# Does the image include an ICC profile?
|
54
|
+
def has_profile?
|
55
|
+
vips_image.get_fields.include?('icc-profile-data')
|
56
|
+
end
|
57
|
+
end
|
58
|
+
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'
|