libis-format 1.2.9 → 2.0.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/.coveralls.yml +2 -0
- data/.gitignore +20 -0
- data/.travis.yml +70 -0
- data/Gemfile +0 -8
- data/README.md +2 -2
- data/Rakefile +8 -0
- data/base/Dockerfile +35 -0
- data/base/Dockerfile.alpine +20 -0
- data/base/Dockerfile.rvm +56 -0
- data/base/rework_path +20 -0
- data/data/PDFA_def.ps +3 -3
- data/data/eciRGB_v2.icc +0 -0
- data/data/types.yml +3 -16
- data/docker_cfg.yml +1 -0
- data/lib/libis/format/cli/convert.rb +4 -4
- data/lib/libis/format/cli/prompt_helper.rb +24 -32
- data/lib/libis/format/config.rb +4 -3
- data/lib/libis/format/converter/audio_converter.rb +31 -56
- data/lib/libis/format/converter/base.rb +21 -8
- data/lib/libis/format/converter/chain.rb +6 -18
- data/lib/libis/format/converter/fop_pdf_converter.rb +2 -0
- data/lib/libis/format/converter/image_assembler.rb +82 -0
- data/lib/libis/format/converter/image_converter.rb +21 -141
- data/lib/libis/format/converter/image_splitter.rb +80 -0
- data/lib/libis/format/converter/image_watermarker.rb +261 -0
- data/lib/libis/format/converter/jp2_converter.rb +4 -4
- data/lib/libis/format/converter/office_converter.rb +5 -3
- data/lib/libis/format/converter/pdf_assembler.rb +66 -0
- data/lib/libis/format/converter/pdf_converter.rb +31 -98
- data/lib/libis/format/converter/pdf_optimizer.rb +70 -0
- data/lib/libis/format/converter/pdf_splitter.rb +65 -0
- data/lib/libis/format/converter/pdf_watermarker.rb +110 -0
- data/lib/libis/format/converter/spreadsheet_converter.rb +5 -3
- data/lib/libis/format/converter/video_converter.rb +3 -6
- data/lib/libis/format/converter/xslt_converter.rb +14 -15
- data/lib/libis/format/identifier.rb +4 -4
- data/lib/libis/format/info.rb +27 -0
- data/lib/libis/format/library.rb +147 -0
- data/lib/libis/format/tool/extension_identification.rb +26 -24
- data/lib/libis/format/tool/{ff_mpeg.rb → ffmpeg.rb} +1 -10
- data/lib/libis/format/tool/fido.rb +27 -22
- data/lib/libis/format/tool/file_tool.rb +24 -11
- data/lib/libis/format/tool/fop_pdf.rb +14 -25
- data/lib/libis/format/tool/identification_tool.rb +40 -38
- data/lib/libis/format/tool/office_to_pdf.rb +18 -30
- data/lib/libis/format/tool/pdf_copy.rb +1 -11
- data/lib/libis/format/tool/pdf_merge.rb +1 -11
- data/lib/libis/format/tool/pdf_optimizer.rb +2 -11
- data/lib/libis/format/tool/pdf_split.rb +16 -25
- data/lib/libis/format/tool/pdf_to_pdfa.rb +32 -50
- data/lib/libis/format/tool/pdfa_validator.rb +30 -25
- data/lib/libis/format/tool/spreadsheet_to_ods.rb +2 -10
- data/lib/libis/format/tool.rb +1 -2
- data/lib/libis/format/version.rb +1 -3
- data/lib/libis/format/yaml_loader.rb +71 -0
- data/lib/libis/format.rb +5 -2
- data/libis-format.gemspec +18 -24
- metadata +78 -120
- data/data/AdobeRGB1998.icc +0 -0
- data/lib/libis/format/converter/email_converter.rb +0 -38
- data/lib/libis/format/tool/msg_to_pdf.rb +0 -270
- data/lib/libis/format/type_database.rb +0 -133
- data/lib/libis/format/type_database_impl.rb +0 -120
- data/tools/pdf2pdfa +0 -395
- /data/bin/{droid_tool → droid} +0 -0
- /data/bin/{fido_tool → fido} +0 -0
@@ -1,5 +1,3 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
require_relative 'base'
|
4
2
|
require 'libis/format/identifier'
|
5
3
|
require 'chromaprint'
|
@@ -9,19 +7,24 @@ require 'fileutils'
|
|
9
7
|
module Libis
|
10
8
|
module Format
|
11
9
|
module Converter
|
10
|
+
|
12
11
|
class AudioConverter < Libis::Format::Converter::Base
|
12
|
+
|
13
13
|
def self.input_types
|
14
|
-
|
14
|
+
[:MP3, :FLAC, :AC3, :AAC, :WMA, :ALAC, :WAV, :AIFF, :AMR, :AU, :M4A]
|
15
15
|
end
|
16
16
|
|
17
17
|
def self.output_types(format = nil)
|
18
|
-
return [] unless input_types.include?(format)
|
18
|
+
return [] unless format.nil? || input_types.include?(format)
|
19
|
+
[:MP3, :FLAC, :AC3, :AAC, :WMA, :ALAC, :WAV, :AIFF, :AMR, :AU, :M4A]
|
20
|
+
end
|
19
21
|
|
20
|
-
|
22
|
+
def initialize
|
23
|
+
super
|
21
24
|
end
|
22
25
|
|
23
|
-
def quiet(
|
24
|
-
@flags[:quiet] = !!
|
26
|
+
def quiet(v)
|
27
|
+
@flags[:quiet] = !!v
|
25
28
|
end
|
26
29
|
|
27
30
|
def format(format)
|
@@ -57,70 +60,38 @@ module Libis
|
|
57
60
|
end
|
58
61
|
|
59
62
|
def web_stream(value)
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
+
if value
|
64
|
+
@options[:codec] = 'mp3'
|
65
|
+
end
|
63
66
|
end
|
64
67
|
|
65
68
|
def preset(stream, name)
|
66
69
|
(@options[:preset] ||= {})[stream] = name
|
67
70
|
end
|
68
71
|
|
69
|
-
# def encoder(value)
|
70
|
-
# @options[:encoder] = value
|
71
|
-
# end
|
72
|
-
#
|
73
|
-
# def encoder_options(value)
|
74
|
-
# @options[:encoder_options] = value
|
75
|
-
# end
|
76
|
-
|
77
72
|
def convert(source, target, _format, opts = {})
|
78
73
|
super
|
79
74
|
|
80
75
|
FileUtils.mkpath(File.dirname(target))
|
81
76
|
|
82
|
-
|
83
|
-
|
84
|
-
assemble_and_convert(source, target)
|
85
|
-
|
86
|
-
elsif File.directory?(source)
|
87
|
-
|
88
|
-
sources = Dir[File.join(source, '**', '*')].reject { |p| File.directory? p }
|
89
|
-
assemble_and_convert(sources, target)
|
90
|
-
|
91
|
-
else
|
77
|
+
convert_file(source, target)
|
92
78
|
|
93
|
-
convert_file(source, target)
|
94
|
-
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
def assemble_and_convert(sources, target)
|
99
|
-
result = {}
|
100
|
-
Tempfile.create(%w[list .txt]) do |f|
|
101
|
-
sources.each { |src| f.puts src }
|
102
|
-
opts[:global] ||= []
|
103
|
-
opts[:global] += %w[-f concat]
|
104
|
-
f.close
|
105
|
-
result = convert_file(f.to_path, target)
|
106
|
-
end
|
107
|
-
result
|
108
79
|
end
|
109
80
|
|
110
81
|
def self.sounds_like(file1, file2, threshold, rate, channels)
|
111
|
-
rate ||=
|
82
|
+
rate ||= 96000
|
112
83
|
channels ||= 2
|
113
84
|
threshold ||= 0.85
|
114
85
|
|
115
|
-
if File.
|
86
|
+
if File.exists?(file1) && File.exists?(file2)
|
116
87
|
# Convert input files into raw 16-bit signed audio (WAV) to process with Chramaprint
|
117
|
-
file1_raw = File.join('', 'tmp',
|
118
|
-
file2_raw = File.join('', 'tmp',
|
88
|
+
file1_raw = File.join('', 'tmp', File.basename(file1) + '.wav')
|
89
|
+
file2_raw = File.join('', 'tmp', File.basename(file2) + '.wav')
|
119
90
|
FileUtils.rm(file1_raw, force: true)
|
120
91
|
FileUtils.rm(file2_raw, force: true)
|
121
92
|
cvt_cmd = Libis::Format::Config[:raw_audio_convert_cmd]
|
122
|
-
|
123
|
-
|
93
|
+
%x"#{cvt_cmd % [file1, file1_raw, rate, channels]}"
|
94
|
+
%x"#{cvt_cmd % [file2, file2_raw, rate, channels]}"
|
124
95
|
file1_audio = File.binread(file1_raw)
|
125
96
|
file2_audio = File.binread(file2_raw)
|
126
97
|
|
@@ -140,33 +111,37 @@ module Libis
|
|
140
111
|
else
|
141
112
|
false
|
142
113
|
end
|
114
|
+
|
143
115
|
rescue Exception => e
|
144
|
-
|
116
|
+
error "Error comparing sound file #{file1} and #{file2}: #{e.message} @ #{e.backtrace.first}"
|
145
117
|
false
|
146
118
|
end
|
147
119
|
|
148
120
|
protected
|
149
121
|
|
150
122
|
def convert_file(source, target)
|
151
|
-
opts = {
|
152
|
-
|
123
|
+
opts = {global: [], input: [], filter: [], output: []}
|
153
124
|
opts[:global] << '-hide_banner'
|
154
125
|
opts[:global] << '-loglevel' << (@options[:quiet] ? 'fatal' : 'warning')
|
155
126
|
opts[:output] << '-vn' # disable input video stream in case it exists
|
156
127
|
opts[:output] << '-codec:a' << @options[:codec] if @options[:codec]
|
157
128
|
opts[:output] << '-map_metadata:g' << '0:g' # Copy global metadata
|
158
129
|
opts[:output] << '-map_metadata:s:a' << '0:s:a' # Copy audio metadata
|
159
|
-
opts[:input] << '-accurate_seek' << (@options[:start].to_i
|
130
|
+
opts[:input] << '-accurate_seek' << (@options[:start].to_i < 0 ? '-sseof' : '-ss') << @options[:start] if @options[:start]
|
160
131
|
opts[:input] << '-t' << @options[:duration] if @options[:duration]
|
161
132
|
opts[:output] << '-q:a' << @options[:quality] if @options[:quality]
|
162
133
|
opts[:output] << '-b:a' << @options[:bit_rate] if @options[:bit_rate]
|
163
134
|
opts[:output] << '-ar' << @options[:sampling_freq] if @options[:sampling_freq]
|
164
135
|
opts[:output] << '-ac' << @options[:channels] if @options[:channels]
|
165
136
|
opts[:output] << '-f' << @options[:format] if @options[:format]
|
166
|
-
|
167
|
-
|
137
|
+
result = Libis::Format::Tool::FFMpeg.run(source, target, opts)
|
138
|
+
info "FFMpeg output: #{result}"
|
139
|
+
result
|
140
|
+
target
|
168
141
|
end
|
142
|
+
|
169
143
|
end
|
144
|
+
|
170
145
|
end
|
171
146
|
end
|
172
|
-
end
|
147
|
+
end
|
@@ -4,7 +4,7 @@
|
|
4
4
|
require 'tmpdir'
|
5
5
|
require 'libis/tools/logger'
|
6
6
|
require 'libis/tools/temp_file'
|
7
|
-
require 'libis/format/
|
7
|
+
require 'libis/format/library'
|
8
8
|
|
9
9
|
require_relative 'repository'
|
10
10
|
|
@@ -22,10 +22,23 @@ module Libis
|
|
22
22
|
@flags = {}
|
23
23
|
end
|
24
24
|
|
25
|
+
def self.category
|
26
|
+
:converter
|
27
|
+
end
|
28
|
+
|
29
|
+
def check_file_exist(file)
|
30
|
+
unless File.exist? file
|
31
|
+
error "Cannot find file '#{file}'."
|
32
|
+
return false
|
33
|
+
end
|
34
|
+
true
|
35
|
+
end
|
36
|
+
|
25
37
|
def convert(source, target, format, opts = {})
|
26
|
-
|
27
|
-
|
28
|
-
|
38
|
+
if source.is_a?(Array)
|
39
|
+
return nil unless source.map { |f| check_file_exist(f) }.reduce(:&)
|
40
|
+
else
|
41
|
+
return nil unless check_file_exist(source)
|
29
42
|
end
|
30
43
|
@options.merge!(opts[:options]) if opts[:options]
|
31
44
|
@flags.merge!(opts[:flags]) if opts[:flags]
|
@@ -51,7 +64,7 @@ module Libis
|
|
51
64
|
target
|
52
65
|
end
|
53
66
|
|
54
|
-
def Base.inherited(
|
67
|
+
def Base.inherited(klass)
|
55
68
|
|
56
69
|
Repository.register klass
|
57
70
|
|
@@ -73,12 +86,12 @@ module Libis
|
|
73
86
|
end
|
74
87
|
|
75
88
|
def input_mimetype?(mimetype)
|
76
|
-
type_id =
|
89
|
+
type_id = Libis::Format::Library.get_field_by(:mimetype, mimetype, :format)
|
77
90
|
input_type? type_id
|
78
91
|
end
|
79
92
|
|
80
93
|
def output_mimetype?(mimetype)
|
81
|
-
type_id =
|
94
|
+
type_id = Libis::Format::Library.get_field_by(:mimetype, mimetype, :format)
|
82
95
|
output_type? type_id
|
83
96
|
end
|
84
97
|
|
@@ -91,7 +104,7 @@ module Libis
|
|
91
104
|
end
|
92
105
|
|
93
106
|
def extension?(extension)
|
94
|
-
!
|
107
|
+
!Libis::Format::Library.get_field_by(:extension, extension, :format).nil?
|
95
108
|
end
|
96
109
|
|
97
110
|
end
|
@@ -5,7 +5,7 @@ require 'deep_dive'
|
|
5
5
|
|
6
6
|
require 'libis/tools/logger'
|
7
7
|
require 'libis/tools/extend/hash'
|
8
|
-
require 'libis/format/
|
8
|
+
require 'libis/format/library'
|
9
9
|
|
10
10
|
module Libis
|
11
11
|
module Format
|
@@ -68,18 +68,14 @@ module Libis
|
|
68
68
|
end
|
69
69
|
|
70
70
|
temp_files = []
|
71
|
-
xtra_files = []
|
72
|
-
|
73
|
-
result = { commands: [] }
|
74
71
|
|
75
72
|
# noinspection RubyParenthesesAroundConditionInspection
|
76
|
-
|
73
|
+
result = @converter_chain.each_with_index do |node, i|
|
77
74
|
|
78
75
|
target_type = node[:output]
|
79
76
|
converter_class = node[:converter]
|
80
77
|
converter = converter_class.new
|
81
78
|
|
82
|
-
|
83
79
|
node[:operations].each do |operation|
|
84
80
|
converter.send operation[:method], operation[:argument]
|
85
81
|
end if node[:operations]
|
@@ -87,32 +83,24 @@ module Libis
|
|
87
83
|
target = target_file
|
88
84
|
|
89
85
|
if i < size - 1
|
90
|
-
target += ".temp.#{
|
91
|
-
target += ".#{
|
86
|
+
target += ".temp.#{Libis::Format::Library.get_field(target_type, :extensions).first}"
|
87
|
+
target += ".#{Libis::Format::Library.get_field(target_type, :extensions).first}" while File.exist? target
|
92
88
|
temp_files << target
|
93
89
|
end
|
94
90
|
|
95
91
|
FileUtils.mkdir_p File.dirname(target)
|
96
92
|
|
97
|
-
|
93
|
+
src_file = converter.convert(src_file, target, target_type)
|
98
94
|
|
99
|
-
src_file = r[:files].first
|
100
|
-
xtra_files += r[:files][1..]
|
101
95
|
break :failed unless src_file
|
102
96
|
|
103
|
-
result[:commands] << r.merge(converter: converter_class.name)
|
104
|
-
|
105
|
-
:success
|
106
|
-
|
107
97
|
end
|
108
98
|
|
109
|
-
result[:files] = [src_file] + xtra_files
|
110
|
-
|
111
99
|
temp_files.each do |f|
|
112
100
|
FileUtils.rm(f, force: true)
|
113
101
|
end
|
114
102
|
|
115
|
-
|
103
|
+
result == :failed ? nil : target_file
|
116
104
|
|
117
105
|
end
|
118
106
|
|
@@ -0,0 +1,82 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require_relative 'base'
|
4
|
+
require 'libis/format/identifier'
|
5
|
+
|
6
|
+
require 'mini_magick'
|
7
|
+
|
8
|
+
MiniMagick.logger.level = ::Logger::UNKNOWN
|
9
|
+
|
10
|
+
MiniMagick.configure do |config|
|
11
|
+
# config.cli = :graphicsmagick
|
12
|
+
config.validate_on_create = false
|
13
|
+
config.validate_on_write = false
|
14
|
+
config.whiny = false
|
15
|
+
end
|
16
|
+
|
17
|
+
module Libis
|
18
|
+
module Format
|
19
|
+
module Converter
|
20
|
+
|
21
|
+
# noinspection RubyTooManyInstanceVariablesInspection,DuplicatedCode
|
22
|
+
class ImageAssembler < Libis::Format::Converter::Base
|
23
|
+
|
24
|
+
def self.input_types
|
25
|
+
[:TIFF, :JPG, :PNG, :BMP, :GIF, :PDF, :JP2]
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.output_types(format = nil)
|
29
|
+
return [] unless input_types.include?(format) if format
|
30
|
+
[:PDF, :TIFF, :GIF, :PBM, :PGM, :PPM]
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.category
|
34
|
+
:assembler
|
35
|
+
end
|
36
|
+
|
37
|
+
def image_assemble(_)
|
38
|
+
#force usage of this converter
|
39
|
+
end
|
40
|
+
|
41
|
+
def quiet(v)
|
42
|
+
@quiet = !!v
|
43
|
+
end
|
44
|
+
|
45
|
+
def convert(source, target, format, opts = {})
|
46
|
+
super
|
47
|
+
|
48
|
+
FileUtils.mkpath(File.dirname(target))
|
49
|
+
|
50
|
+
if source.is_a? Array
|
51
|
+
assemble(source, target, format)
|
52
|
+
elsif File.directory?(source)
|
53
|
+
source_list = Dir[File.join(source, '**', '*')].reject {|p| File.directory? p}
|
54
|
+
assemble(source_list, target, format)
|
55
|
+
else
|
56
|
+
image = MiniMagick::Image.open(source) {|b| b.quiet}
|
57
|
+
if image.pages.size > 1
|
58
|
+
assemble(image.pages.map {|page| page.path}, target, format)
|
59
|
+
else
|
60
|
+
assemble([source], target, format)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
target
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
def assemble(sources, target, format)
|
71
|
+
MiniMagick::Tool::Convert.new do |b|
|
72
|
+
sources.each {|source| b << source}
|
73
|
+
convert.format(format)
|
74
|
+
b << target
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -4,7 +4,6 @@ require_relative 'base'
|
|
4
4
|
require 'libis/format/identifier'
|
5
5
|
|
6
6
|
require 'mini_magick'
|
7
|
-
require 'fileutils'
|
8
7
|
|
9
8
|
MiniMagick.logger.level = ::Logger::UNKNOWN
|
10
9
|
|
@@ -23,11 +22,11 @@ module Libis
|
|
23
22
|
class ImageConverter < Libis::Format::Converter::Base
|
24
23
|
|
25
24
|
def self.input_types
|
26
|
-
[:TIFF, :JPG, :PNG, :BMP, :GIF, :PDF, :JP2]
|
25
|
+
[:TIFF, :JPG, :PNG, :BMP, :GIF, :PDF, :JP2, :PBM, :PGM, :PPM]
|
27
26
|
end
|
28
27
|
|
29
28
|
def self.output_types(format = nil)
|
30
|
-
return [] unless input_types.include?(format)
|
29
|
+
return [] unless input_types.include?(format) if format
|
31
30
|
[:TIFF, :JPG, :PNG, :BMP, :GIF, :PDF, :JP2]
|
32
31
|
end
|
33
32
|
|
@@ -46,109 +45,57 @@ module Libis
|
|
46
45
|
|
47
46
|
def quiet(v)
|
48
47
|
@quiet = !!v
|
48
|
+
self
|
49
49
|
end
|
50
50
|
|
51
51
|
def page(nr)
|
52
52
|
@page = nr
|
53
|
+
self
|
53
54
|
end
|
54
55
|
|
55
56
|
def scale(percent)
|
56
57
|
@options[:scale] = percent
|
58
|
+
self
|
57
59
|
end
|
58
60
|
|
59
61
|
def resize(geometry)
|
60
62
|
@options[:resize] = geometry
|
63
|
+
self
|
61
64
|
end
|
62
65
|
|
63
66
|
def quality(value)
|
64
67
|
@options[:quality] = value
|
68
|
+
self
|
65
69
|
end
|
66
70
|
|
67
71
|
def dpi(value)
|
68
72
|
@options[:density] = value
|
73
|
+
self
|
69
74
|
end
|
70
75
|
|
71
76
|
def resample(value)
|
72
77
|
@options[:resample] = value
|
78
|
+
self
|
73
79
|
end
|
74
80
|
|
75
81
|
def flatten(value = true)
|
76
|
-
@options[:flatten] =
|
82
|
+
@options[:flatten] = value
|
83
|
+
self
|
77
84
|
end
|
78
85
|
|
79
86
|
def colorspace(value)
|
80
87
|
@options[:colorspace] = value
|
88
|
+
self
|
81
89
|
end
|
82
90
|
|
83
91
|
def delete_date(value = true)
|
84
|
-
@delete_date =
|
92
|
+
@delete_date = value
|
93
|
+
self
|
85
94
|
end
|
86
95
|
|
87
96
|
def profile(icc)
|
88
97
|
@profile = icc
|
89
|
-
|
90
|
-
|
91
|
-
# Create or use a watermark image.
|
92
|
-
#
|
93
|
-
# The watermark options are:
|
94
|
-
# - file: watermark image to use
|
95
|
-
# - 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'
|
107
|
-
# If both options are given, the file will be used as-is if it exists and is a valid image file. Otherwise the
|
108
|
-
# file will be created or overwritten with a newly created watermark image.
|
109
|
-
#
|
110
|
-
# The created watermark file will be a PNG image with transparent background containing the supplied text
|
111
|
-
# slanted by 30 degrees counter-clockwise.
|
112
|
-
#
|
113
|
-
# @param [Hash] options Hash of options for watermark creation.
|
114
|
-
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
|
-
unless @wm_image && @wm_image.valid?
|
126
|
-
image = options[:file] || (Dir::Tmpname.create(%w(wm_image .png)) {|_|})
|
127
|
-
# noinspection RubyResolve
|
128
|
-
MiniMagick::Tool::Convert.new do |convert|
|
129
|
-
# noinspection RubyLiteralArrayInspection
|
130
|
-
convert.quiet
|
131
|
-
convert.background 'transparent'
|
132
|
-
convert.size('2000x2000')
|
133
|
-
convert.gravity 'Center'
|
134
|
-
convert.font('Helvetica').fill('black').pointsize(72) #.stroke('black').strokewidth(1)
|
135
|
-
convert << "label:#{text}"
|
136
|
-
convert.rotate rotation
|
137
|
-
convert.trim.repage.+
|
138
|
-
convert << image
|
139
|
-
end
|
140
|
-
if options[:file]
|
141
|
-
@wm_image = MiniMagick::Image.new(image)
|
142
|
-
else
|
143
|
-
@wm_image = MiniMagick::Image.open(image)
|
144
|
-
File.delete(image)
|
145
|
-
end
|
146
|
-
# noinspection RubyResolve
|
147
|
-
unless @wm_image.valid?
|
148
|
-
error "Problem creating watermark image '#{image}'."
|
149
|
-
@wm_image = nil
|
150
|
-
end
|
151
|
-
end
|
98
|
+
self
|
152
99
|
end
|
153
100
|
|
154
101
|
def convert(source, target, format, opts = {})
|
@@ -156,92 +103,25 @@ module Libis
|
|
156
103
|
|
157
104
|
FileUtils.mkpath(File.dirname(target))
|
158
105
|
|
159
|
-
|
160
|
-
|
161
|
-
assemble_and_convert(source, target, format)
|
162
|
-
|
163
|
-
elsif File.directory?(source)
|
164
|
-
source_list = Dir[File.join(source, '**', '*')].reject {|p| File.directory? p}
|
165
|
-
|
166
|
-
assemble_and_convert(source_list, target, format)
|
167
|
-
|
168
|
-
else
|
169
|
-
|
170
|
-
image = MiniMagick::Image.open(source) { |b| b.quiet }
|
171
|
-
|
172
|
-
if image.pages.size > 1
|
173
|
-
if @page
|
174
|
-
convert_image(image.pages[@page].path, target, format)
|
175
|
-
else
|
176
|
-
# noinspection RubyBlockToMethodReference
|
177
|
-
assemble_and_convert(image.pages.map {|page| page.path}, target, format)
|
178
|
-
end
|
179
|
-
else
|
180
|
-
convert_image(source, target, format)
|
181
|
-
end
|
182
|
-
end
|
183
|
-
|
184
|
-
{
|
185
|
-
files: [target],
|
186
|
-
converter: self.class.name
|
187
|
-
}
|
188
|
-
end
|
106
|
+
convert_image(source, target, format)
|
189
107
|
|
190
|
-
|
108
|
+
target
|
191
109
|
|
192
|
-
warn 'Received multiple images as input and single page format as target.' unless self.class.multipage?(format)
|
193
|
-
converted_pages = sources.inject([]) do |list, path|
|
194
|
-
# noinspection RubyArgCount
|
195
|
-
converted = Tempfile.new(['page-', ".#{Libis::Format::TypeDatabase.type_extentions(format).first}"])
|
196
|
-
convert_image(path, converted.path, format)
|
197
|
-
list << converted
|
198
|
-
end
|
199
|
-
MiniMagick::Tool::Convert.new do |b|
|
200
|
-
b.append unless self.class.multipage?(format)
|
201
|
-
converted_pages.each {|page| b << page.path}
|
202
|
-
b << target
|
203
|
-
end
|
204
|
-
converted_pages.each do |temp_file|
|
205
|
-
temp_file.close
|
206
|
-
temp_file.unlink
|
207
|
-
end
|
208
110
|
end
|
209
111
|
|
210
112
|
protected
|
211
113
|
|
212
114
|
def convert_image(source, target, format)
|
213
115
|
|
214
|
-
|
215
|
-
|
116
|
+
if @page
|
117
|
+
image = MiniMagick::Image.open(source) { |b| b.quiet }
|
118
|
+
source = image.pages[@page].path if image.pages.size > 1
|
119
|
+
end
|
216
120
|
|
217
121
|
MiniMagick::Tool::Convert.new do |convert|
|
218
|
-
convert.quiet if @quiet
|
219
|
-
if @wm_image
|
220
|
-
convert << @wm_image.path
|
221
|
-
convert.bordercolor('transparent').border("#{@wm_gap}%") if @wm_gap > 0
|
222
|
-
convert.filter('Lagrange')
|
223
|
-
convert.resize("#{image_info['width'] / @wm_tiles}x#{image_info['height'] / @wm_tiles}") if @wm_tiles > 0
|
224
|
-
convert.resize("#{@wm_resize}%") if @wm_resize
|
225
|
-
convert.write('mpr:watermark').delete.+
|
226
|
-
end
|
227
|
-
|
228
122
|
convert.quiet if @quiet
|
229
123
|
convert << source
|
230
124
|
convert.flatten if @options[:flatten].nil? && format == :JPG
|
231
|
-
if @wm_image
|
232
|
-
if @wm_tiles >= 0 and @wm_tiles <= 1
|
233
|
-
convert << 'mpr:watermark'
|
234
|
-
else
|
235
|
-
convert.stack do |stack|
|
236
|
-
stack.size("#{image_info['width']}x#{image_info['height']}")
|
237
|
-
stack << 'xc:transparent'
|
238
|
-
stack.tile('mpr:watermark')
|
239
|
-
stack.draw "rectangle 0,0,#{image_info['width']},#{image_info['height']}"
|
240
|
-
end
|
241
|
-
end
|
242
|
-
convert.compose(@wm_composition).gravity(@wm_gravity).define("compose:args=#{@wm_opacity}%").composite
|
243
|
-
end
|
244
|
-
|
245
125
|
@flags.each {|f, v| v.is_a?(TrueClass) ? convert.send(f).+ : convert.send(f)}
|
246
126
|
if @delete_date
|
247
127
|
convert << '+set' << 'modify-date' << '+set' << 'create-date'
|