libis-format 1.3.2 → 1.3.4

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: 68f64b7c012a051d6c25eb3cb02fb74d662c0f1da348d4b3b5b4af5b7004d543
4
- data.tar.gz: 62708947cef69d89540b2dd73b85a546eb012fae7e6565e329e989ab0573949b
3
+ metadata.gz: 5fb1b156976a67b10d6885880a0611ba8361671c24da8014e7e11d7840be6318
4
+ data.tar.gz: 1f5e6e9b1cd84031a5a1ae986a2d0de018bb021bb48d47d6d83c9feea1e8db59
5
5
  SHA512:
6
- metadata.gz: ed3dc449c70eb71f081a6c55f06d8a2b484afb0094a6988aad0ca018ae36e07beb1d9fae3a8fb0a3a026e90c13386f83686b7c66be34b8a028d588ef9412bd99
7
- data.tar.gz: 44bc49f3315e99974e5c7f992e1f496ec3e59dbd15839f93a0e2f8b20fc73dcbfba0f77e178514f0e78f0f561961f55f31895e843ba217e70e2a3cc79b47cdfb
6
+ metadata.gz: 364036443664fc6597d36456c554e25074926515c2b95c7475a93499a27389bc0a2d8749ba86f5cb29e47b50c41902780518b780abde202f0d69f2e3a550cf24
7
+ data.tar.gz: b7d5823c3da6b25a71b2d7c3a2b05a9b15042e562985775b357490ccadabc457e0784136c1e269030f7211c94e3926a2000857efa03472cb9ca05f013f25128c
@@ -9,10 +9,6 @@ require 'fileutils'
9
9
  MiniMagick.logger.level = ::Logger::UNKNOWN
10
10
 
11
11
  MiniMagick.configure do |config|
12
- # config.cli = :graphicsmagick
13
- config.validate_on_create = false
14
- config.validate_on_write = false
15
- config.whiny = false
16
12
  config.tmpdir = Libis::Format::Config[:tempdir] || Dir.tmpdir
17
13
  end
18
14
 
@@ -90,20 +86,15 @@ module Libis
90
86
 
91
87
  # Create or use a watermark image.
92
88
  #
93
- # The watermark options are:
94
- # - file: watermark image to use
89
+ # The watermark options are (use symbols):
95
90
  # - text: text to create a watermark from
96
- # - rotation: rotation of the watermark text (counter clockwise in degrees; integer number) - default 30
97
- # - tiles: number of tiles of the watermark - default 4
98
- # - 0: no tiling, so only 1 watermark will be placed with the original size
99
- # - 1: 1 tile, so the watermark will be scaled up to fill the image
100
- # - n > 1: minimum n tiles in both directions
101
- # - n < 0: tile without scaling the watermark
102
- # - size: same as tiles - for backwards compatibility
103
- # - resize: fraction 0.0 - 1.0
104
- # - gap: size of the gap between watermark instances. Fractions as percentage of widht/height. - default 0.2
105
- # - opacity: opacity of the watermark (fraction 0.0 - 1.0) - default 0.1
106
- # - gravity: center point of the overlay - default 'center'
91
+ # - file: watermark image to use
92
+ # - image: same as above
93
+ # - rotation: rotation of the watermark text (in degrees; integer number)
94
+ # - size: font size of the watermark text
95
+ # - opacity: opacity of the watermark (fraction 0.0 - 1.0)
96
+ # - gap: size of the gap between watermark instances. Integer value is absolute size in points (1/72 inch).
97
+ # Fractions are percentage of widht/height.
107
98
  # If both options are given, the file will be used as-is if it exists and is a valid image file. Otherwise the
108
99
  # file will be created or overwritten with a newly created watermark image.
109
100
  #
@@ -111,44 +102,95 @@ module Libis
111
102
  # slanted by 30 degrees counter-clockwise.
112
103
  #
113
104
  # @param [Hash] options Hash of options for watermark creation.
105
+
114
106
  def watermark(options = {})
115
- text = options[:text] || '© LIBIS'
116
- @wm_tiles = (options[:tiles] || '4').to_i
117
- @wm_tiles ||= (options[:size] || '4').to_i
118
- @wm_resize = ((options[:resize]).to_f * 100).to_i if options[:resize]
119
- @wm_opacity = ((options[:opacity] || 0.1).to_f * 100).to_i
120
- @wm_composition = options[:composition] || 'modulate'
121
- @wm_gravity = options[:gravity] || 'center'
122
- @wm_gap = ((options[:gap] || 0.2).to_f * 100).to_i
123
- rotation = 360 - (options[:rotation] || 30).to_i
124
- @wm_image = MiniMagick::Image.new(options[:file]) if options[:file]
125
- return if @wm_image&.valid?
126
-
127
- image = options[:file] || (Dir::Tmpname.create(%w[wm_image .png]) { |_| })
128
- # noinspection RubyResolve
129
- MiniMagick::Tool::Convert.new do |convert|
130
- # noinspection RubyLiteralArrayInspection
131
- convert.quiet
132
- convert.background 'transparent'
133
- convert.size('2000x2000')
134
- convert.gravity 'Center'
135
- convert.font('Helvetica').fill('black').pointsize(72) # .stroke('black').strokewidth(1)
136
- convert << "label:#{text}"
137
- convert.rotate rotation
138
- convert.trim.repage.+ # rubocop:disable Lint/Void
139
- convert << image
140
- end
141
- if options[:file]
142
- @wm_image = MiniMagick::Image.new(image)
143
- else
144
- @wm_image = MiniMagick::Image.open(image)
145
- File.delete(image)
107
+ options.key_strings_to_symbols!
108
+ if options[:file] || options[:image]
109
+ watermark_image(options)
110
+ elsif options[:text]
111
+ watermark_text(options)
112
+ elsif options[:banner]
113
+ watermark_banner(options)
146
114
  end
147
- # noinspection RubyResolve
148
- return if @wm_image.valid?
115
+ end
149
116
 
150
- error "Problem creating watermark image '#{image}'."
151
- @wm_image = nil
117
+ # Use an image as watermark
118
+ #
119
+ # Next to the :file or :image option, this enables the following options:
120
+ # - tiles: number of tiles of the watermark - default 4
121
+ # 0: no tiling, so only 1 watermark will be placed with the original size
122
+ # 1: 1 tile, so the watermark will be scaled up to fill the image
123
+ # n > 1: minimum n tiles in both directions
124
+ # n < 0: tile without scaling the watermark
125
+ # - size: same as tiles - for backwards compatibility
126
+ # - resize: fraction 0.0 - 1.0
127
+ # - gap: size of the gap between watermark instances. Fractions as percentage of widht/height. - default 0.2
128
+ # - opacity: opacity of the watermark (fraction 0.0 - 1.0) - default 0.1
129
+ # - gravity: center point of the overlay - default 'center'
130
+ # - composition: algorithm to use to compose both images - default modulate
131
+ def watermark_image(options = {})
132
+ options.key_strings_to_symbols!
133
+ @options[:watermark] = {command: 'image'}
134
+ @options[:watermark][:data] = options[:file] || options[:image]
135
+ @options[:watermark][:tiles] = (options[:tiles] || options[:size] || 4).to_i
136
+ @options[:watermark][:resize] = ((options[:resize]).to_f * 100).to_i if options[:resize]
137
+ @options[:watermark][:gap] = ((options[:gap] || 0.2).to_f * 100).to_i
138
+ @options[:watermark][:opacity] = ((options[:opacity] || 0.1).to_f * 100).to_i
139
+ @options[:watermark][:gravity] = options[:gravity] || 'center'
140
+ @options[:watermark][:composition] = options[:composition] || 'modulate'
141
+ @options[:watermark][:rotation] = 360 - (options[:rotation] || 30).to_i
142
+ end
143
+
144
+ # Use text as watermark
145
+ #
146
+ # Next to the :text option, this enables the following options:
147
+ # - tiles: number of tiles of the watermark - default 4
148
+ # 0: no tiling, so only 1 watermark will be placed with the original size
149
+ # 1: 1 tile, so the watermark will be scaled up to fill the image
150
+ # n > 1: minimum n tiles in both directions
151
+ # n < 0: tile without scaling the watermark
152
+ # - size: same as tiles - for backwards compatibility
153
+ # - resize: fraction 0.0 - 1.0
154
+ # - gap: size of the gap between watermark instances. Fractions as percentage of widht/height. - default 0.2
155
+ # - opacity: opacity of the watermark (fraction 0.0 - 1.0) - default 0.1
156
+ # - gravity: center point of the overlay - default 'center'
157
+ # - composition: algorithm to use to compose both images - default modulate
158
+ # - rotation: rotation of the text
159
+ def watermark_text(options = {})
160
+ options.key_strings_to_symbols!
161
+ @options[:watermark] = {command: 'text'}
162
+ @options[:watermark][:data] = options[:text] || '© LIBIS'
163
+ @options[:watermark][:tiles] = (options[:tiles] || options[:size] || 4).to_i
164
+ @options[:watermark][:resize] = ((options[:resize]).to_f * 100).to_i if options[:resize]
165
+ @options[:watermark][:gap] = ((options[:gap] || 0.2).to_f * 100).to_i
166
+ @options[:watermark][:opacity] = ((options[:opacity] || 0.1).to_f * 100).to_i
167
+ @options[:watermark][:gravity] = options[:gravity] || 'center'
168
+ @options[:watermark][:composition] = options[:composition] || 'modulate'
169
+ @options[:watermark][:rotation] = 360 - (options[:rotation] || 30).to_i
170
+ end
171
+
172
+ # Create a vertical banner to the right side of each page
173
+ #
174
+ # The banner options are:
175
+ # - banner: text to put in the banner
176
+ # - add_filename: append filename to the text (use any value to enable)
177
+ # - fontsize: size of the font (in points) (default: autoscale)
178
+ # - width: width of the banner (default: 3% of image height). Not including a border of 30% of the banner width
179
+ # - background_color_(red|green|blue): color components of background (default: rgb(84,190,233))
180
+ # - text_color_(red|green|blue): color components of background (default: rgb(255,255,255))
181
+ def watermark_banner(options = {})
182
+ options.key_strings_to_symbols!
183
+ @options[:watermark] = {command: 'banner'}
184
+ @options[:watermark][:data] = options[:banner] || '© LIBIS'
185
+ @options[:watermark][:add_filename] = !!options[:add_filename]
186
+ @options[:watermark][:size] = options[:fontsize] if options[:fontsize]
187
+ @options[:watermark][:width] = options[:width] if options[:width]
188
+ @options[:watermark][:background_red] = options[:background_color_red] || 84
189
+ @options[:watermark][:background_green] = options[:background_color_green] || 190
190
+ @options[:watermark][:background_blue] = options[:background_color_blue] || 233
191
+ @options[:watermark][:text_red] = options[:text_color_red] || 255
192
+ @options[:watermark][:text_green] = options[:text_color_green] || 255
193
+ @options[:watermark][:text_blue] = options[:text_color_blue] || 255
152
194
  end
153
195
 
154
196
  def convert(source, target, format, opts = {})
@@ -195,7 +237,7 @@ module Libis
195
237
  convert_image(path, converted.path, format)
196
238
  list << converted
197
239
  end
198
- MiniMagick::Tool::Convert.new do |b|
240
+ MiniMagick.convert do |b|
199
241
  b.append unless self.class.multipage?(format)
200
242
  converted_pages.each { |page| b << page.path }
201
243
  b << target
@@ -210,34 +252,84 @@ module Libis
210
252
 
211
253
  def convert_image(source, target, format)
212
254
  image_info = nil
213
- image_info = MiniMagick::Image::Info.new(source) { |b| b.quiet } if @wm_image # rubocop:disable Style/SymbolProc
214
255
 
215
- MiniMagick::Tool::Convert.new do |convert|
256
+ MiniMagick.convert do |convert|
257
+ # Make converter silent
216
258
  convert.quiet if @quiet
217
- if @wm_image
218
- convert << @wm_image.path
219
- convert.bordercolor('transparent').border("#{@wm_gap}%") if @wm_gap.positive?
220
- convert.filter('Lagrange')
221
- convert.resize("#{image_info['width'] / @wm_tiles}x#{image_info['height'] / @wm_tiles}") if @wm_tiles.positive?
222
- convert.resize("#{@wm_resize}%") if @wm_resize
259
+
260
+ # Build watermark image in buffer
261
+ wm = @options.delete(:watermark)
262
+ if wm
263
+ image_info = MiniMagick::Image::Info.new(source) { |b| b.quiet }
264
+ case wm[:command]
265
+ when 'text'
266
+ convert.background 'transparent'
267
+ convert.size('2000x2000')
268
+ convert.gravity 'Center'
269
+ convert.font('Helvetica').fill('black').pointsize(72) # .stroke('black').strokewidth(1)
270
+ convert << "label:#{wm[:data]}"
271
+ convert.rotate wm[:rotation]
272
+ convert.trim.repage.+ # rubocop:disable Lint/Void
273
+ convert.bordercolor('transparent').border("#{wm[:gap]}%") if wm[:gap].positive?
274
+ convert.filter('Lagrange')
275
+ convert.resize("#{image_info['width'] / wm[:tiles]}x#{image_info['height'] / wm[:tiles]}") if wm[:tiles].positive?
276
+ convert.resize("#{wm[:resize]}%") if wm[:resize]
277
+ when 'image'
278
+ convert << wm[:data]
279
+ convert.background 'transparent'
280
+ convert.bordercolor('transparent').border("#{wm[:gap]}%") if wm[:gap].positive?
281
+ convert.rotate wm[:rotation]
282
+ convert.filter('Lagrange')
283
+ convert.resize("#{image_info['width'] / wm[:tiles]}x#{image_info['height'] / wm[:tiles]}") if wm[:tiles].positive?
284
+ convert.resize("#{wm[:resize]}%") if wm[:resize]
285
+ when 'banner'
286
+ banner_width = wm[:width] || [0.03 * image_info['height'], 20].max.round(0)
287
+ banner_border = banner_width / 3
288
+ convert.background "rgb(#{wm[:background_red]},#{wm[:background_green]},#{wm[:background_blue]})"
289
+ convert.size("#{image_info['height']}x#{banner_width}")
290
+ convert.bordercolor "rgb(#{wm[:background_red]},#{wm[:background_green]},#{wm[:background_blue]})"
291
+ convert.border "0x#{banner_border}"
292
+ convert.fill "rgb(#{wm[:text_red]},#{wm[:text_green]},#{wm[:text_blue]})"
293
+ convert.font "Liberation-Sans"
294
+ convert.pointsize wm[:size] if wm[:size]
295
+ convert.gravity 'Center'
296
+ convert << "label:#{wm[:data]}#{wm[:add_filename] ? File.basename(source, '.*') : ''}"
297
+ end
298
+
299
+ # Save watermark image to buffer
223
300
  convert.write('mpr:watermark').delete.+
224
301
  end
225
302
 
226
- convert.quiet if @quiet
303
+ # load source image
227
304
  convert << source
305
+
306
+ # force flatten image if necessary
228
307
  convert.flatten if @options[:flatten].nil? && format == :JPG
229
- if @wm_image
230
- if (@wm_tiles >= 0) && (@wm_tiles <= 1)
308
+
309
+ # add watermark image
310
+ if wm
311
+ if wm[:command] == 'banner'
312
+ convert.rotate '-90'
231
313
  convert << 'mpr:watermark'
314
+ convert.rotate '180'
315
+ convert.append
316
+ convert.rotate '-90'
232
317
  else
233
- convert.stack do |stack|
234
- stack.size("#{image_info['width']}x#{image_info['height']}")
235
- stack << 'xc:transparent'
236
- stack.tile('mpr:watermark')
237
- stack.draw "rectangle 0,0,#{image_info['width']},#{image_info['height']}"
318
+ if (0..1).include? wm[:tiles]
319
+ convert << 'mpr:watermark'
320
+ else
321
+ convert.stack do |stack|
322
+ stack.size("#{image_info['width']}x#{image_info['height']}")
323
+ stack << 'xc:transparent'
324
+ stack.tile('mpr:watermark')
325
+ stack.draw "rectangle 0,0,#{image_info['width']},#{image_info['height']}"
326
+ end
327
+ convert.compose(wm[:composition])
328
+ convert.gravity(wm[:gravity])
329
+ convert.define("compose:args=#{wm[:opacity]}%")
330
+ convert.composite
238
331
  end
239
332
  end
240
- convert.compose(@wm_composition).gravity(@wm_gravity).define("compose:args=#{@wm_opacity}%").composite
241
333
  end
242
334
 
243
335
  @flags.each { |f, v| v.is_a?(TrueClass) ? convert.send(f).+ : convert.send(f) }
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'os'
4
+
5
+ require 'libis/tools/extend/string'
6
+ require 'libis/tools/logger'
7
+ require 'libis/tools/command'
8
+
9
+ require 'libis/format/config'
10
+
11
+ module Libis
12
+ module Format
13
+ module Tool
14
+ class PdfMerge
15
+ include ::Libis::Tools::Logger
16
+
17
+ def self.installed?
18
+ result = Libis::Tools::Command.run(Libis::Format::Config[:java_cmd], '-version')
19
+ return false unless (result[:status]).zero?
20
+
21
+ File.exist?(Libis::Format::Config[:pdf_tool])
22
+ end
23
+
24
+ def self.run(source, target, *options)
25
+ new.run source, target, options
26
+ end
27
+
28
+ def run(source, target, *options)
29
+ source = [source] unless source.is_a?(Array)
30
+
31
+ if OS.java?
32
+ # TODO: import library and execute in current VM. For now do exactly as in MRI.
33
+ end
34
+
35
+ timeout = Libis::Format::Config[:timeouts][:pdf_tool]
36
+ args = [
37
+ Libis::Format::Config[:java_cmd],
38
+ '-jar', Libis::Format::Config[:pdf_tool],
39
+ 'merge',
40
+ '-o', target,
41
+ options,
42
+ source
43
+ ].flatten
44
+
45
+ result = Libis::Tools::Command.run(*args, timeout: , kill_after: timeout * 2)
46
+
47
+ result[:err] << "#{self.class} took too long (> #{timeout} seconds) to complete" if result[:timeout]
48
+
49
+ result
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'libis/format/tool/pdf_tool'
4
+
5
+ module Libis
6
+ module Format
7
+ module Tool
8
+ class PdfSplit
9
+
10
+ def self.run(source, target, *options)
11
+ PdfTool.run('split', source, target, *options)
12
+ end
13
+
14
+ def run(source, target, *options)
15
+ PdfTool.run('split', source, target, *options)
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Libis
4
4
  module Format
5
- VERSION = '1.3.2'
5
+ VERSION = '1.3.4'
6
6
  end
7
7
  end
data/libis-format.gemspec CHANGED
@@ -29,7 +29,7 @@ Gem::Specification.new do |spec|
29
29
  spec.add_runtime_dependency 'deep_dive', '~> 0.3'
30
30
  spec.add_runtime_dependency 'libis-mapi', '~> 0.3'
31
31
  spec.add_runtime_dependency 'libis-tools', '~> 1.1'
32
- spec.add_runtime_dependency 'mini_magick', '~> 4.12'
32
+ spec.add_runtime_dependency 'mini_magick', '~> 5.0.1'
33
33
  spec.add_runtime_dependency 'naturally', '~> 2.2'
34
34
  spec.add_runtime_dependency 'new_rfc_2047', '~> 1.0'
35
35
  spec.add_runtime_dependency 'os', '~> 1.1'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: libis-format
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.2
4
+ version: 1.3.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kris Dekeyser
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-08-30 00:00:00.000000000 Z
11
+ date: 2024-10-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: chromaprint
@@ -72,14 +72,14 @@ dependencies:
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: '4.12'
75
+ version: 5.0.1
76
76
  type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: '4.12'
82
+ version: 5.0.1
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: naturally
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -281,7 +281,9 @@ files:
281
281
  - lib/libis/format/tool/identification_tool.rb
282
282
  - lib/libis/format/tool/msg_to_pdf.rb
283
283
  - lib/libis/format/tool/office_to_pdf.rb
284
+ - lib/libis/format/tool/pdf_merge.rb
284
285
  - lib/libis/format/tool/pdf_optimizer.rb
286
+ - lib/libis/format/tool/pdf_split.rb
285
287
  - lib/libis/format/tool/pdf_to_pdfa.rb
286
288
  - lib/libis/format/tool/pdf_tool.rb
287
289
  - lib/libis/format/tool/pdfa_validator.rb
@@ -350,7 +352,7 @@ homepage: ''
350
352
  licenses:
351
353
  - MIT
352
354
  metadata: {}
353
- post_install_message:
355
+ post_install_message:
354
356
  rdoc_options: []
355
357
  require_paths:
356
358
  - lib
@@ -366,7 +368,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
366
368
  version: '0'
367
369
  requirements: []
368
370
  rubygems_version: 3.5.18
369
- signing_key:
371
+ signing_key:
370
372
  specification_version: 4
371
373
  summary: LIBIS File format format services.
372
374
  test_files: []