libis-format 1.3.3 → 1.3.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e8f7ecb168b9a5db9a47b91035c1f8988c8a079963ad0764e23ad00b2bde61b1
4
- data.tar.gz: 2fecf5a7eb4f0a74573d8182111dac6bb4abc05e9c8d22c248b79cc6533a93ef
3
+ metadata.gz: 5fb1b156976a67b10d6885880a0611ba8361671c24da8014e7e11d7840be6318
4
+ data.tar.gz: 1f5e6e9b1cd84031a5a1ae986a2d0de018bb021bb48d47d6d83c9feea1e8db59
5
5
  SHA512:
6
- metadata.gz: 4ea0eced4ca98790237cbb936cd347964693a0b5d627e9564fb184621d018868d69e6208c5afc2cbaf78db096e5a7342fa42af9604921bf411b3b2c70c4e8722
7
- data.tar.gz: 339f5f89b61747862d2f005ede140300f09ae8ab9aee4693d0214edac3bfba52b8f8b2eaa04b9e1e499debdee805403f1e8434c3ef7907d4ea0ae86e54bdc01f
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) }
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Libis
4
4
  module Format
5
- VERSION = '1.3.3'
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.3
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-09-07 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
@@ -352,7 +352,7 @@ homepage: ''
352
352
  licenses:
353
353
  - MIT
354
354
  metadata: {}
355
- post_install_message:
355
+ post_install_message:
356
356
  rdoc_options: []
357
357
  require_paths:
358
358
  - lib
@@ -368,7 +368,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
368
368
  version: '0'
369
369
  requirements: []
370
370
  rubygems_version: 3.5.18
371
- signing_key:
371
+ signing_key:
372
372
  specification_version: 4
373
373
  summary: LIBIS File format format services.
374
374
  test_files: []