assembly-image 2.0.0 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9379ec53a26a08578c11910512bd73045366fc337fcafb0c7eb1a247370566b1
4
- data.tar.gz: 316fbef312cb027f4061bbe74dc2f8dce993a095d6779da100abeeecbf24b9da
3
+ metadata.gz: '088a4b9c59b50f893f7b50c16898321770006b4ab22dc08a8ddd70cdba9a15da'
4
+ data.tar.gz: f22bf6d6acbd4d6885e2102526e7c5e0ac76b93af71eff0d2237d32334afd223
5
5
  SHA512:
6
- metadata.gz: 97cc720649bdc6e0bb6d7453afdefc7abe3f0931a45976d397f1f77fd2f2dacbcbd4991e64c0e4849a2ae61efa51d72d428ce9a8a15e9a125abdeefcb17b0d5b
7
- data.tar.gz: 8e6580aaade8302319e7cbf41d56d8ac0ebe1a05db5607bed8580cebe8a3c87b5795cb90f50e2b9eb4b081d9048a600799b0e373badf811ff9a084e5f9af3fcc
6
+ metadata.gz: 91f0be3622982ad69823a45eca8111d05756e0442cd7d7aa16cb8099e71ee2e95c21f17c7f14b7ccab04c11724233c9a9739e24f8b8302f07f42b16738c6400e
7
+ data.tar.gz: d1ab206c475413496a6add9376cb246705df18a3142bdc32189b202e31af698b8cfded84464d00e94357fc08396ab142270043b3b862cc0d68cd57834863b649
data/.circleci/config.yml CHANGED
@@ -1,6 +1,6 @@
1
1
  version: 2.1
2
2
  orbs:
3
- ruby-rails: sul-dlss/ruby-rails@3.0.1
3
+ ruby-rails: sul-dlss/ruby-rails@3.1.2
4
4
  workflows:
5
5
  build:
6
6
  jobs:
data/.gitignore CHANGED
@@ -2,7 +2,6 @@
2
2
  *.gem
3
3
  .DS_Store
4
4
  .bundle
5
- Gemfile.lock
6
5
  config/certs/*
7
6
  config/environments/*
8
7
  doc/*
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: true
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-06-16 22:15:07 UTC using RuboCop version 1.30.1.
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: 14
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: 5
46
- RSpec/UnspecifiedException:
47
- Exclude:
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.9.3@assembly-image --create
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 PreRequisites section below.
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 because color profiles can be extracted from images during the JP2
18
- creation process, and these profiles need to be stored as local files, and it
19
- is beneficial to cache them for later usage by images with the same color profile.
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
- input = Assembly::Image.new('/full/path/to/file.tif')
35
- puts input.exif # show exif header information for the TIF
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 rake
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. ImageMagick 6.5.4 or higher
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
- #### RHEL
58
+ #### Linux
83
59
  Download latest version from: http://www.sno.phy.queensu.ca/~phil/exiftool
84
60
 
85
61
  ```bash
@@ -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.0.0'
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
@@ -4,6 +4,6 @@
4
4
  require 'rubygems'
5
5
  require 'irb'
6
6
 
7
- require File.expand_path(File.dirname(__FILE__) + '/../config/boot')
7
+ require File.expand_path("#{File.dirname(__FILE__)}/../config/boot")
8
8
 
9
9
  IRB.start
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 + '/lib')
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 [Hash] params Optional parameters specified as a hash, using symbols for options:
18
- # * :output => path to the output JP2 file (default: mirrors the source file name and path, but with a .jp2 extension)
19
- # * :overwrite => if set to false, an existing JP2 file with the same name won't be overwritten (default: false)
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(:overwrite=>true)
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, params = {})
28
- new(image, params).create
27
+ def self.create(image, **args)
28
+ new(image, **args).create
29
29
  end
30
30
 
31
- def initialize(image, params)
31
+ def initialize(image, overwrite: false, output: image.jp2_filename, tmp_folder: Dir.tmpdir)
32
32
  @image = image
33
- @output_path = params.fetch(:output, image.jp2_filename)
34
- @tmp_folder = params[:tmp_folder]
35
- @overwrite = params[: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, :tmp_path
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
- # Using instance variable so that can check in tests.
46
- # We do this because we need to reliably compress the tiff and KDUcompress doesn’t support arbitrary image types
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: @tmp_path, output: output_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
- File.delete(output_path) if File.exist?(output_path)
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(@tmp_path) unless @tmp_path.nil?
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
- # TODO: Consider using ruby-vips to determine the colorspace instead of relying on exif (which is done below)
72
- options << '-jp2_space sRGB' if image.samples_per_pixel == 3
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(tmp_folder: nil)
111
- tmp_folder ||= Dir.tmpdir
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
- tmp_path = tmp_tiff_file.path
117
- vips_image = Vips::Image.new_from_file image.path
118
-
119
- vips_image = if vips_image.interpretation.eql?(:cmyk)
120
- vips_image.icc_transform(SRGB_ICC, input_profile: CMYK_ICC)
121
- elsif !image.profile.nil?
122
- vips_image.icc_transform(SRGB_ICC, embedded: true)
123
- else
124
- vips_image
125
- end
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
@@ -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-image/image'
12
- require 'assembly-image/images'
11
+ require 'assembly/image'