assembly-image 1.8.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.
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: 1.8.0
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Mangiafico
@@ -11,8 +11,22 @@ authors:
11
11
  autorequire:
12
12
  bindir: exe
13
13
  cert_chain: []
14
- date: 2022-06-03 00:00:00.000000000 Z
14
+ date: 2022-07-19 00:00:00.000000000 Z
15
15
  dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: activesupport
18
+ requirement: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ">"
21
+ - !ruby/object:Gem::Version
22
+ version: '6.1'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">"
28
+ - !ruby/object:Gem::Version
29
+ version: '6.1'
16
30
  - !ruby/object:Gem::Dependency
17
31
  name: assembly-objectfile
18
32
  requirement: !ruby/object:Gem::Requirement
@@ -28,25 +42,33 @@ dependencies:
28
42
  - !ruby/object:Gem::Version
29
43
  version: 1.6.4
30
44
  - !ruby/object:Gem::Dependency
31
- name: mini_exiftool
45
+ name: ruby-vips
32
46
  requirement: !ruby/object:Gem::Requirement
33
47
  requirements:
34
48
  - - ">="
35
49
  - !ruby/object:Gem::Version
36
- version: '1.6'
37
- - - "<"
38
- - !ruby/object:Gem::Version
39
- version: '3'
50
+ version: '2.0'
40
51
  type: :runtime
41
52
  prerelease: false
42
53
  version_requirements: !ruby/object:Gem::Requirement
43
54
  requirements:
44
55
  - - ">="
45
56
  - !ruby/object:Gem::Version
46
- version: '1.6'
47
- - - "<"
57
+ version: '2.0'
58
+ - !ruby/object:Gem::Dependency
59
+ name: pry-byebug
60
+ requirement: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
48
63
  - !ruby/object:Gem::Version
49
- version: '3'
64
+ version: '0'
65
+ type: :development
66
+ prerelease: false
67
+ version_requirements: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
50
72
  - !ruby/object:Gem::Dependency
51
73
  name: rake
52
74
  requirement: !ruby/object:Gem::Requirement
@@ -117,20 +139,6 @@ dependencies:
117
139
  - - ">="
118
140
  - !ruby/object:Gem::Version
119
141
  version: '0'
120
- - !ruby/object:Gem::Dependency
121
- name: yard
122
- requirement: !ruby/object:Gem::Requirement
123
- requirements:
124
- - - ">="
125
- - !ruby/object:Gem::Version
126
- version: '0'
127
- type: :development
128
- prerelease: false
129
- version_requirements: !ruby/object:Gem::Requirement
130
- requirements:
131
- - - ">="
132
- - !ruby/object:Gem::Version
133
- version: '0'
134
142
  description: Contains classes to create derivative image files and perform other image
135
143
  operations
136
144
  email:
@@ -147,25 +155,24 @@ files:
147
155
  - ".rubocop_todo.yml"
148
156
  - ".rvmrc.example"
149
157
  - Gemfile
158
+ - Gemfile.lock
150
159
  - LICENSE
151
160
  - README.md
152
161
  - Rakefile
153
162
  - assembly-image.gemspec
154
163
  - bin/console
155
- - bin/run_all_tests
156
164
  - config/boot.rb
157
165
  - lib/assembly-image.rb
158
- - lib/assembly-image/image.rb
159
- - lib/assembly-image/images.rb
160
- - lib/assembly-image/jp2_creator.rb
161
- - lib/assembly-image/version.rb
166
+ - lib/assembly/image.rb
167
+ - lib/assembly/image/jp2_creator.rb
162
168
  - profiles/AdobeRGB1998.icc
163
169
  - profiles/DotGain20.icc
170
+ - profiles/cmyk.icc
164
171
  - profiles/sRGBIEC6196621.icc
165
172
  - spec/assembly/image/jp2_creator_spec.rb
166
- - spec/image_spec.rb
167
- - spec/images_spec.rb
173
+ - spec/assembly/image_spec.rb
168
174
  - spec/spec_helper.rb
175
+ - spec/test_data/color_rgb_srgb_rot90cw.tif
169
176
  - spec/test_data/input/.empty
170
177
  - spec/test_data/output/.empty
171
178
  homepage: ''
@@ -192,10 +199,4 @@ signing_key:
192
199
  specification_version: 4
193
200
  summary: Ruby immplementation of image services needed to prepare objects to be accessioned
194
201
  in SULAIR digital library
195
- test_files:
196
- - spec/assembly/image/jp2_creator_spec.rb
197
- - spec/image_spec.rb
198
- - spec/images_spec.rb
199
- - spec/spec_helper.rb
200
- - spec/test_data/input/.empty
201
- - spec/test_data/output/.empty
202
+ test_files: []
data/bin/run_all_tests DELETED
@@ -1,3 +0,0 @@
1
- #! /bin/bash
2
-
3
- bundle exec rspec spec
@@ -1,162 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'assembly-objectfile'
4
- require_relative 'jp2_creator'
5
-
6
- module Assembly
7
- # The Image class contains methods to operate on an image.
8
- class Image
9
- # include common behaviors from assembly-objectfile gem
10
- include Assembly::ObjectFileable
11
-
12
- # Examines the input image for validity. Used to determine if image is correct and if JP2 generation is likely to succeed.
13
- # This method is automatically called before you create a jp2 but it can be called separately earlier as a sanity check.
14
- #
15
- # @return [boolean] true if image is valid, false if not.
16
- #
17
- # Example:
18
- # source_img=Assembly::ObjectFile.new('/input/path_to_file.tif')
19
- # puts source_img.valid? # gives true
20
- def valid?
21
- valid_image? # behavior is defined in assembly-objectfile gem
22
- end
23
-
24
- # Get the image color profile
25
- #
26
- # @return [string] image color profile
27
- # Example:
28
- # source_img=Assembly::Image.new('/input/path_to_file.tif')
29
- # puts source_img.profile # gives 'Adobe RGB 1998'
30
- def profile
31
- exif.nil? ? nil : exif['profiledescription']
32
- end
33
-
34
- # Get the image height from exif data
35
- #
36
- # @return [integer] image height in pixels
37
- # Example:
38
- # source_img=Assembly::Image.new('/input/path_to_file.tif')
39
- # puts source_img.height # gives 100
40
- def height
41
- exif.imageheight
42
- end
43
-
44
- # Get the image width from exif data
45
- # @return [integer] image height in pixels
46
- # Example:
47
- # source_img=Assembly::Image.new('/input/path_to_file.tif')
48
- # puts source_img.width # gives 100
49
- def width
50
- exif.imagewidth
51
- end
52
-
53
- # Examines the input image to determine if it is compressed.
54
- #
55
- # @return [boolean] true if image is compressed, false if not.
56
- #
57
- # Example:
58
- # source_img=Assembly::ObjectFile.new('/input/path_to_file.tif')
59
- # puts source_img.compressed? # gives true
60
- # def compressed?
61
- # exif.compression != 'Uncompressed'
62
- # end
63
-
64
- # Add an exif color profile descriptions to the image.
65
- # This is useful if your source TIFFs do not have color profile descriptions in the EXIF data, but you know what it should be.
66
- # This will allow the images to pass the validaty check and have JP2s created successfully.
67
- #
68
- # Note you will need full read/write access to the source path so that new EXIF data can be saved.
69
- #
70
- # @param [String] profile_name profile name to be added, current options are 'Adobe RBG 1998','Dot Gain 20%','sRGB IEC61966-2.1'
71
- #
72
- # @param [String] force if set to true, force overwrite a color profile description even if it already exists (default: false)
73
- #
74
- # Example:
75
- # source_img=Assembly::Image.new('/input/path_to_file.tif')
76
- # source_img.add_exif_profile_description('Adobe RGB 1998')
77
- def add_exif_profile_description(profile_name, force = false)
78
- if profile.nil? || force
79
- input_profile = profile_name.gsub(/[^[:alnum:]]/, '') # remove all non alpha-numeric characters, so we can get to a filename
80
- path_to_profiles = File.join(Assembly::PATH_TO_IMAGE_GEM, 'profiles')
81
- input_profile_file = File.join(path_to_profiles, "#{input_profile}.icc")
82
- command = "exiftool '-icc_profile<=#{input_profile_file}' #{path}"
83
- result = `#{command} 2>&1`
84
- raise "profile addition command failed: #{command} with result #{result}" unless $CHILD_STATUS.success?
85
- end
86
- rescue StandardError => e
87
- puts "** Error for #{filename}: #{e.message}"
88
- end
89
-
90
- # Returns the full default jp2 path and filename that will be created from the given image
91
- #
92
- # @return [string] full default jp2 path and filename that will be created from the given image
93
- # Example:
94
- # source_img=Assembly::Image.new('/input/path_to_file.tif')
95
- # puts source_img.jp2_filename # gives /input/path_to_file.jp2
96
- def jp2_filename
97
- File.extname(path).empty? ? "#{path}.jp2" : path.gsub(File.extname(path), '.jp2')
98
- end
99
-
100
- # Returns the full DPG equivalent jp2 path and filename that would match with the given image
101
- #
102
- # @return [string] full DPG equivalent jp2 path and filename
103
- # Example:
104
- # source_img=Assembly::Image.new('/input/path_to_file.tif')
105
- # puts source_img.jp2_filename # gives /input/path_to_file.jp2
106
- def dpg_jp2_filename
107
- jp2_filename.gsub('_00_', '_05_')
108
- end
109
-
110
- # Create a JP2 file for the current image.
111
- # Important note: this will not work for multipage TIFFs.
112
- #
113
- # @return [Assembly::Image] object containing the generated JP2 file
114
- #
115
- # @param [Hash] params Optional parameters specified as a hash, using symbols for options:
116
- # * :output => path to the output JP2 file (default: mirrors the source file name and path, but with a .jp2 extension)
117
- # * :overwrite => if set to false, an existing JP2 file with the same name won't be overwritten (default: false)
118
- # * :tmp_folder => the temporary folder to use when creating the jp2 (default: '/tmp'); also used by imagemagick
119
- #
120
- # Example:
121
- # source_img=Assembly::Image.new('/input/path_to_file.tif')
122
- # derivative_img=source_img.create_jp2(:overwrite=>true)
123
- # puts derivative_img.mimetype # 'image/jp2'
124
- # puts derivative_image.path # '/input/path_to_file.jp2'
125
- # rubocop:disable Metrics/CyclomaticComplexity:
126
- def create_jp2(params = {})
127
- Jp2Creator.create(self, params)
128
- end
129
-
130
- def samples_per_pixel
131
- if exif['samplesperpixel']
132
- exif['samplesperpixel'].to_i
133
- else
134
- case mimetype
135
- when 'image/tiff'
136
- 1
137
- when 'image/jpeg'
138
- 3
139
- end
140
- end
141
- end
142
-
143
- # Get size of image data in bytes
144
- def image_data_size
145
- (samples_per_pixel * height * width * bits_per_sample) / 8
146
- end
147
-
148
- private
149
-
150
- # rubocop:enable Metrics/CyclomaticComplexity
151
- def bits_per_sample
152
- if exif['bitspersample']
153
- exif['bitspersample'].to_i
154
- else
155
- case mimetype
156
- when 'image/tiff'
157
- 1
158
- end
159
- end
160
- end
161
- end
162
- end
@@ -1,107 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'logger'
4
- module Assembly
5
- # The Images class contains methods to operate on multiple images in batch.
6
- class Images
7
- def self.logger
8
- @logger ||= Logger.new(STDERR)
9
- end
10
-
11
- class << self
12
- attr_writer :logger
13
- end
14
-
15
- # Pass in a source path and have exif color profile descriptions added to all images contained.
16
- # This is useful if your source TIFFs do not have color profile descriptions in the EXIF data, but you know what it should be.
17
- # This will allow the images to pass the validty check and have JP2s created successfully.
18
- #
19
- # Note you will need full read/write access to the source path so that new EXIF data can be saved.
20
- #
21
- # @param [String] source path full path to the directory containing TIFFs
22
- # @param [String] profile_name profile name to be added, current options are 'Adobe RBG 1998','Dot Gain 20%','sRGB IEC61966-2.1'
23
- #
24
- # @param [Hash] params Optional parameters specified as a hash, using symbols for options:
25
- # * :force => if set to true, force overwrite a color profile description even if it already exists (default: false)
26
- # * :recusrive => if set to true, directories will be searched recursively for TIFFs from the source specified, false searches the top level only (default: false)
27
- # * :extension => defines the types of files that will be processed (default '.tif')
28
- #
29
- # Example:
30
- # Assembly::Images.batch_add_exif_profile_description('/full_path_to_tifs','Adobe RGB 1998')
31
- # rubocop:disable Metrics/MethodLength
32
- # rubocop:disable Metrics/AbcSize
33
- def self.batch_add_exif_profile_descr(source, profile_name, params = {})
34
- extension = params[:extension] || 'tif'
35
- recursive = params[:recursive] || false
36
- force = params[:force] || false
37
-
38
- raise 'Input path does not exist' unless File.directory?(source)
39
-
40
- logger.debug "Source: #{source}"
41
-
42
- # iterate over input directory looking for tifs
43
- pattern = recursive ? "**/*.#{extension}" : "*.#{extension}*"
44
- Dir.glob(File.join(source, pattern)).each do |file|
45
- img = Assembly::Image.new(file)
46
- logger.debug "Processing #{file}"
47
- img.add_exif_profile_description(profile_name, force)
48
- end
49
- 'Complete'
50
- end
51
- # rubocop:enable Metrics/MethodLength
52
- # rubocop:enable Metrics/AbcSize
53
-
54
- # Pass in a source path and get JP2s generate for each tiff that is in the source path
55
- #
56
- # If not passed in, the destination will be a "jp2" subfolder within the source folder.
57
- # Note you will need read access to the source path, and write access to the destination path.
58
- #
59
- # @param [String] source path full path to the directory containing TIFFs to be converted to JP2
60
- #
61
- # @param [Hash] params Optional parameters specified as a hash, using symbols for options:
62
- # * :output=>'/full/path_to_jp2' # specifies full path to folder where jp2s will be created (default: jp2 subdirectory from source path)
63
- # * :overwrite => if set to false, an existing JP2 file with the same name won't be overwritten (default: false)
64
- # * :recursive => if set to true, directories will be searched recursively for TIFFs from the source specified, false searches the top level only (default: false)
65
- # * :extension => defines the types of files that will be processed (default '.tif')
66
- #
67
- # Example:
68
- # Assembly::Images.batch_generate_jp2('/full_path_to_tifs')
69
- # rubocop:disable Metrics/MethodLength
70
- # rubocop:disable Metrics/AbcSize
71
- # rubocop:disable Metrics/CyclomaticComplexity
72
- # rubocop:disable Metrics/PerceivedComplexity
73
- def self.batch_generate_jp2(source, params = {})
74
- raise 'Input path does not exist' unless File.directory?(source)
75
-
76
- output = params[:output] || File.join(source, 'jp2') # default output directgory is jp2 sub-directory from source
77
- extension = params[:extension] || 'tif'
78
- overwrite = params[:overwrite] || false
79
- recursive = params[:recursive] || false
80
-
81
- Dir.mkdir(output) unless File.directory?(output) # attemp to make output directory
82
- raise 'Output path does not exist or could not be created' unless File.directory?(output)
83
-
84
- logger.debug "Source: #{source}"
85
- logger.debug "Destination: #{output}"
86
-
87
- pattern = recursive ? "**/*.#{extension}" : "*.#{extension}*"
88
-
89
- # iterate over input directory looking for tifs
90
- Dir.glob(File.join(source, pattern)).each do |file|
91
- source_img = Assembly::Image.new(file)
92
- output_img = File.join(output, File.basename(file, File.extname(file)) + '.jp2') # output image gets same file name as source, but with a jp2 extension and in the correct output directory
93
- begin
94
- source_img.create_jp2(overwrite: overwrite, output: output_img)
95
- logger.debug "Generated jp2 for #{File.basename(file)}"
96
- rescue StandardError => e
97
- logger.debug "** Error for #{File.basename(file)}: #{e.message}"
98
- end
99
- end
100
- 'Complete'
101
- end
102
- # rubocop:enable Metrics/MethodLength
103
- # rubocop:enable Metrics/AbcSize
104
- # rubocop:enable Metrics/CyclomaticComplexity
105
- # rubocop:enable Metrics/PerceivedComplexity
106
- end
107
- end
@@ -1,182 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'tempfile'
4
- require 'English' # see https://github.com/rubocop-hq/rubocop/issues/1747 (not #MAGA related)
5
-
6
- module Assembly
7
- class Image
8
- # Creates jp2 derivatives
9
- class Jp2Creator # rubocop:disable Metrics/ClassLength
10
- # Create a JP2 file for the current image.
11
- # Important note: this will not work for multipage TIFFs.
12
- #
13
- # @return [Assembly::Image] object containing the generated JP2 file
14
- #
15
- # @param [Assembly::Image] the image file
16
- # @param [Hash] params Optional parameters specified as a hash, using symbols for options:
17
- # * :output => path to the output JP2 file (default: mirrors the source file name and path, but with a .jp2 extension)
18
- # * :overwrite => if set to false, an existing JP2 file with the same name won't be overwritten (default: false)
19
- # * :tmp_folder => the temporary folder to use when creating the jp2 (default: '/tmp'); also used by imagemagick
20
- #
21
- # Example:
22
- # source_img = Assembly::Image.new('/input/path_to_file.tif')
23
- # derivative_img = source_img.create_jp2(:overwrite=>true)
24
- # puts derivative_img.mimetype # 'image/jp2'
25
- # puts derivative_image.path # '/input/path_to_file.jp2'
26
- def self.create(image, params = {})
27
- new(image, params).create
28
- end
29
-
30
- def initialize(image, params)
31
- @image = image
32
- @output_path = params.fetch(:output, image.jp2_filename)
33
- @tmp_folder = params[:tmp_folder]
34
- @overwrite = params[:overwrite]
35
- @params = params
36
- end
37
-
38
- attr_reader :image, :output_path, :tmp_folder, :tmp_path
39
-
40
- # @return [Assembly::Image] object containing the generated JP2 file
41
- def create
42
- create_jp2_checks
43
-
44
- # Using instance variable so that can check in tests.
45
- @tmp_path = make_tmp_tiff(tmp_folder: tmp_folder)
46
-
47
- jp2_command = jp2_create_command(source_path: @tmp_path, output: output_path)
48
- result = `#{jp2_command}`
49
- unless $CHILD_STATUS.success?
50
- # Clean up any partial result
51
- File.delete(output_path) if File.exist?(output_path)
52
- raise "JP2 creation command failed: #{jp2_command} with result #{result}"
53
- end
54
-
55
- File.delete(@tmp_path) unless @tmp_path.nil?
56
-
57
- # create output response object, which is an Assembly::Image type object
58
- Image.new(output_path)
59
- end
60
-
61
- private
62
-
63
- def overwrite?
64
- @overwrite
65
- end
66
-
67
- def jp2_create_command(source_path:, output:)
68
- options = []
69
- options << '-jp2_space sRGB' if image.samples_per_pixel == 3
70
- options += KDU_COMPRESS_DEFAULT_OPTIONS
71
- options << "Clayers=#{layers}"
72
- "kdu_compress #{options.join(' ')} -i '#{source_path}' -o '#{output}' 2>&1"
73
- end
74
-
75
- # Get the number of JP2 layers to generate
76
- def layers
77
- pixdem = [image.width, image.height].max
78
- ((Math.log(pixdem) / Math.log(2)) - (Math.log(96) / Math.log(2))).ceil + 1
79
- end
80
-
81
- KDU_COMPRESS_DEFAULT_OPTIONS = [
82
- '-num_threads 2', # forces Kakadu to only use 2 threads
83
- '-precise', # forces the use of 32-bit representations
84
- '-no_weights', # minimization of the MSE over all reconstructed colour components
85
- '-quiet', # suppress informative messages.
86
- 'Creversible=no', # Disable reversible compression
87
- 'Cmodes=BYPASS', #
88
- 'Corder=RPCL', # R=resolution P=position C=component L=layer
89
- 'Cblk=\\{64,64\\}', # code-block dimensions; 64x64 happens to also be the default
90
- 'Cprecincts=\\{256,256\\},\\{256,256\\},\\{128,128\\}', # Precinct dimensions; 256x256 for the 2 highest resolution levels, defaults to 128x128 for the rest
91
- 'ORGgen_plt=yes', # Insert packet length information
92
- '-rate 1.5', # Ratio of compressed bits to the image size
93
- 'Clevels=5' # Number of wavelet decomposition levels, or stages
94
- ].freeze
95
-
96
- # rubocop:disable Metrics/AbcSize
97
- def create_jp2_checks
98
- image.send(:check_for_file)
99
- raise 'input file is not a valid image, or is the wrong mimetype' unless image.jp2able?
100
-
101
- raise SecurityError, "output #{output_path} exists, cannot overwrite" if !overwrite? && File.exist?(output_path)
102
- raise SecurityError, 'cannot recreate jp2 over itself' if overwrite? && image.mimetype == 'image/jp2' && output_path == image.path
103
- end
104
-
105
- # rubocop:disable Metrics/MethodLength
106
- def profile_conversion_switch(profile, tmp_folder:)
107
- path_to_profiles = File.join(Assembly::PATH_TO_IMAGE_GEM, 'profiles')
108
- # eventually we may allow the user to specify the output_profile...when we do, you can just uncomment this code
109
- # and update the tests that check for this
110
- output_profile = 'sRGBIEC6196621' # params[:output_profile] || 'sRGBIEC6196621'
111
- output_profile_file = File.join(path_to_profiles, "#{output_profile}.icc")
112
-
113
- raise "output profile #{output_profile} invalid" unless File.exist?(output_profile_file)
114
-
115
- return '' if image.profile.nil?
116
-
117
- # if the input color profile exists, contract paths to the profile and setup the command
118
-
119
- input_profile = profile.gsub(/[^[:alnum:]]/, '') # remove all non alpha-numeric characters, so we can get to a filename
120
-
121
- # construct a path to the input profile, which might exist either in the gem itself or in the tmp folder
122
- input_profile_file_gem = File.join(path_to_profiles, "#{input_profile}.icc")
123
- input_profile_file_tmp = File.join(tmp_folder, "#{input_profile}.icc")
124
- input_profile_file = File.exist?(input_profile_file_gem) ? input_profile_file_gem : input_profile_file_tmp
125
-
126
- # if input profile was extracted and does not matches an existing known profile either in the gem or in the tmp folder,
127
- # we'll issue an imagicmagick command to extract the profile to the tmp folder
128
- unless File.exist?(input_profile_file)
129
- input_profile_extract_command = "MAGICK_TEMPORARY_PATH=#{tmp_folder} convert '#{image.path}'[0] #{input_profile_file}" # extract profile from input image
130
- result = `#{input_profile_extract_command} 2>&1`
131
- raise "input profile extraction command failed: #{input_profile_extract_command} with result #{result}" unless $CHILD_STATUS.success?
132
- # if extraction failed or we cannot write the file, throw exception
133
- raise 'input profile is not a known profile and could not be extracted from input file' unless File.exist?(input_profile_file)
134
- end
135
-
136
- "-profile #{input_profile_file} -profile #{output_profile_file}"
137
- end
138
-
139
- # Bigtiff needs to be used if size of image exceeds 2^32 bytes.
140
- def need_bigtiff?
141
- image.image_data_size >= 2**32
142
- end
143
-
144
- def make_tmp_tiff(tmp_folder: nil)
145
- tmp_folder ||= Dir.tmpdir
146
- raise "tmp_folder #{tmp_folder} does not exists" unless File.exist?(tmp_folder)
147
-
148
- # make temp tiff filename
149
- tmp_tiff_file = Tempfile.new(['assembly-image', '.tif'], tmp_folder)
150
- tmp_path = tmp_tiff_file.path
151
-
152
- options = []
153
-
154
- # Limit the amount of memory ImageMagick is able to use.
155
- options << '-limit memory 1GiB -limit map 1GiB'
156
-
157
- case image.samples_per_pixel
158
- when 3
159
- options << '-type TrueColor'
160
- when 1
161
- options << '-depth 8' # force the production of a grayscale access derivative
162
- options << '-type Grayscale'
163
- end
164
-
165
- options << profile_conversion_switch(image.profile, tmp_folder: tmp_folder)
166
-
167
- # The output in the covnert command needs to be prefixed by the image type. By default ImageMagick
168
- # will assume TIFF: when the file extension is .tif/.tiff. TIFF64: Needs to be forced when image will
169
- # exceed 2^32 bytes in size
170
- tiff_type = need_bigtiff? ? 'TIFF64:' : ''
171
-
172
- tiff_command = "MAGICK_TEMPORARY_PATH=#{tmp_folder} convert -quiet -compress none #{options.join(' ')} '#{image.path}[0]' #{tiff_type}'#{tmp_path}'"
173
- result = `#{tiff_command} 2>&1`
174
- raise "tiff convert command failed: #{tiff_command} with result #{result}" unless $CHILD_STATUS.success?
175
-
176
- tmp_path
177
- end
178
- # rubocop:enable Metrics/MethodLength
179
- # rubocop:enable Metrics/AbcSize
180
- end
181
- end
182
- end
@@ -1,10 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Main Assembly namespace
4
- module Assembly
5
- # Main Image class
6
- class Image
7
- # Gem version
8
- VERSION = '1.8.0'
9
- end
10
- end