libis-format 1.0.2 → 2.0.1
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 +5 -5
- data/.gitignore +5 -1
- data/.travis.yml +43 -25
- data/README.md +2 -2
- data/base/Dockerfile +35 -0
- data/base/Dockerfile.alpine +20 -0
- data/base/Dockerfile.rvm +56 -0
- data/base/rework_path +20 -0
- data/bin/libis_format +8 -0
- data/docker_cfg.yml +1 -0
- data/lib/libis/format.rb +12 -2
- data/lib/libis/format/cli/convert.rb +310 -0
- data/lib/libis/format/cli/format.rb +77 -0
- data/lib/libis/format/cli/prompt_helper.rb +87 -0
- data/lib/libis/format/cli/sub_command.rb +22 -0
- data/lib/libis/format/command_line.rb +25 -0
- data/lib/libis/format/config.rb +15 -10
- data/lib/libis/format/converter/audio_converter.rb +3 -37
- data/lib/libis/format/converter/base.rb +22 -8
- data/lib/libis/format/converter/chain.rb +3 -3
- data/lib/libis/format/converter/image_assembler.rb +82 -0
- data/lib/libis/format/converter/image_converter.rb +32 -127
- data/lib/libis/format/converter/image_splitter.rb +84 -0
- data/lib/libis/format/converter/image_watermarker.rb +261 -0
- data/lib/libis/format/converter/jp2_converter.rb +2 -2
- data/lib/libis/format/converter/office_converter.rb +2 -2
- data/lib/libis/format/converter/pdf_assembler.rb +66 -0
- data/lib/libis/format/converter/pdf_converter.rb +10 -134
- data/lib/libis/format/converter/pdf_metadata.rb +82 -0
- data/lib/libis/format/converter/pdf_optimizer.rb +67 -0
- data/lib/libis/format/converter/pdf_protecter.rb +147 -0
- data/lib/libis/format/converter/pdf_selecter.rb +77 -0
- data/lib/libis/format/converter/pdf_splitter.rb +70 -0
- data/lib/libis/format/converter/pdf_watermarker_header.rb +71 -0
- data/lib/libis/format/converter/pdf_watermarker_image.rb +76 -0
- data/lib/libis/format/converter/pdf_watermarker_text.rb +93 -0
- data/lib/libis/format/converter/spreadsheet_converter.rb +2 -2
- data/lib/libis/format/converter/video_converter.rb +1 -1
- data/lib/libis/format/identifier.rb +7 -7
- data/lib/libis/format/info.rb +27 -0
- data/lib/libis/format/library.rb +147 -0
- data/lib/libis/format/tool.rb +4 -1
- data/lib/libis/format/tool/droid.rb +2 -2
- data/lib/libis/format/tool/extension_identification.rb +4 -4
- data/lib/libis/format/tool/ffmpeg.rb +1 -1
- data/lib/libis/format/tool/fido.rb +1 -1
- data/lib/libis/format/tool/fop_pdf.rb +1 -1
- data/lib/libis/format/tool/identification_tool.rb +6 -6
- data/lib/libis/format/tool/office_to_pdf.rb +1 -1
- data/lib/libis/format/tool/pdf_merge.rb +4 -4
- data/lib/libis/format/tool/{pdf_copy.rb → pdf_metadata.rb} +6 -6
- data/lib/libis/format/tool/pdf_protect.rb +47 -0
- data/lib/libis/format/tool/pdf_select.rb +47 -0
- data/lib/libis/format/tool/pdf_split.rb +5 -5
- data/lib/libis/format/tool/pdf_to_pdfa.rb +1 -2
- data/lib/libis/format/tool/pdf_watermark.rb +47 -0
- data/lib/libis/format/tool/pdfa_validator.rb +3 -4
- data/lib/libis/format/tool/spreadsheet_to_ods.rb +2 -1
- data/lib/libis/format/version.rb +1 -1
- data/lib/libis/format/yaml_loader.rb +71 -0
- data/libis-format.gemspec +5 -5
- data/tools/PdfTool.jar +0 -0
- data/tools/bcpkix-jdk15on-167.jar +0 -0
- data/tools/bcprov-jdk15on-167.jar +0 -0
- data/tools/fop/build/fop.jar +0 -0
- data/tools/fop/conf/fop.xconf +466 -0
- data/tools/fop/fop +258 -0
- data/tools/fop/fop.bat +75 -0
- data/tools/fop/fop.cmd +31 -0
- data/tools/fop/fop.js +341 -0
- data/tools/fop/lib/README.txt +243 -0
- data/tools/fop/lib/avalon-framework-api-4.3.1.jar +0 -0
- data/tools/fop/lib/avalon-framework-impl-4.3.1.jar +0 -0
- data/tools/fop/lib/avalon-framework.LICENSE.txt +175 -0
- data/tools/fop/lib/avalon-framework.NOTICE.TXT +11 -0
- data/tools/fop/lib/batik-all-1.10.jar +0 -0
- data/tools/fop/lib/batik.LICENSE.txt +201 -0
- data/tools/fop/lib/batik.NOTICE.txt +18 -0
- data/tools/fop/lib/commons-io-1.3.1.jar +0 -0
- data/tools/fop/lib/commons-io.LICENSE.txt +203 -0
- data/tools/fop/lib/commons-io.NOTICE.txt +6 -0
- data/tools/fop/lib/commons-logging-1.0.4.jar +0 -0
- data/tools/fop/lib/commons-logging.LICENSE.txt +202 -0
- data/tools/fop/lib/commons-logging.NOTICE.txt +3 -0
- data/tools/fop/lib/fontbox-2.0.7.jar +0 -0
- data/tools/fop/lib/serializer-2.7.2.jar +0 -0
- data/tools/fop/lib/serializer.LICENSE.txt +201 -0
- data/tools/fop/lib/serializer.NOTICE.txt +15 -0
- data/tools/fop/lib/xalan-2.7.2.jar +0 -0
- data/tools/fop/lib/xalan.BCEL.LICENSE.txt +52 -0
- data/tools/fop/lib/xalan.LICENSE.txt +202 -0
- data/tools/fop/lib/xalan.NOTICE.txt +44 -0
- data/tools/fop/lib/xalan.regexp.LICENSE.txt +52 -0
- data/tools/fop/lib/xalan.runtime.LICENSE.txt +20 -0
- data/tools/fop/lib/xerces.LICENSE.txt +56 -0
- data/tools/fop/lib/xercesImpl-2.9.1.jar +0 -0
- data/tools/fop/lib/xercesImpl.LICENSE.txt +201 -0
- data/tools/fop/lib/xercesImpl.NOTICE.txt +14 -0
- data/tools/fop/lib/xml-apis-1.3.04.jar +0 -0
- data/tools/fop/lib/xml-apis-ext-1.3.04.jar +0 -0
- data/tools/fop/lib/xml-apis-ext.LICENSE.dom-documentation.txt +73 -0
- data/tools/fop/lib/xml-apis-ext.LICENSE.dom-software.txt +61 -0
- data/tools/fop/lib/xml-apis-ext.LICENSE.sac.html +75 -0
- data/tools/fop/lib/xml-apis-ext.LICENSE.txt +202 -0
- data/tools/fop/lib/xml-apis-ext.NOTICE.txt +16 -0
- data/tools/fop/lib/xml-apis-ext.README.dom.txt +56 -0
- data/tools/fop/lib/xml-apis.LICENSE-SAX.html +17 -0
- data/tools/fop/lib/xml-apis.LICENSE.DOM-documentation.html +74 -0
- data/tools/fop/lib/xml-apis.LICENSE.DOM-software.html +66 -0
- data/tools/fop/lib/xml-apis.LICENSE.txt +201 -0
- data/tools/fop/lib/xml-apis.NOTICE.txt +13 -0
- data/tools/fop/lib/xmlgraphics-commons-2.3.jar +0 -0
- data/tools/fop/lib/xmlgraphics-commons.LICENSE.txt +202 -0
- data/tools/fop/lib/xmlgraphics-commons.NOTICE.txt +5 -0
- data/tools/pdfbox/pdfbox-app-2.0.13.jar +0 -0
- data/tools/pdfbox/{pdfbox-app-1.8.10.jar → preflight-app-2.0.13.jar} +0 -0
- metadata +93 -259
- data/lib/libis/format/type_database.rb +0 -201
- data/spec/converter_audio_spec.rb +0 -66
- data/spec/converter_fop_spec.rb +0 -37
- data/spec/converter_image_spec.rb +0 -166
- data/spec/converter_office_spec.rb +0 -84
- data/spec/converter_pdf_spec.rb +0 -30
- data/spec/converter_repository_spec.rb +0 -97
- data/spec/converter_spreadsheet_spec.rb +0 -39
- data/spec/converter_video_spec.rb +0 -97
- data/spec/converter_xsl_spec.rb +0 -56
- data/spec/data/Cevennes2.bmp +0 -0
- data/spec/data/Cevennes2.jp2 +0 -0
- data/spec/data/Cevennes2.ppm +0 -22492
- data/spec/data/NikonRaw-CameraRaw.TIF +0 -0
- data/spec/data/NikonRaw-CaptureOne.tif +0 -0
- data/spec/data/audio/carlin_disappointed.aac +0 -0
- data/spec/data/audio/carlin_disappointed.ac3 +0 -0
- data/spec/data/audio/carlin_disappointed.aiff +0 -0
- data/spec/data/audio/carlin_disappointed.au +0 -0
- data/spec/data/audio/carlin_disappointed.flac +0 -0
- data/spec/data/audio/carlin_disappointed.m4a +0 -0
- data/spec/data/audio/carlin_disappointed.mka +0 -0
- data/spec/data/audio/carlin_disappointed.mp3 +0 -0
- data/spec/data/audio/carlin_disappointed.ogg +0 -0
- data/spec/data/audio/carlin_disappointed.ra +0 -0
- data/spec/data/audio/carlin_disappointed.voc +0 -0
- data/spec/data/audio/carlin_disappointed.wav +0 -0
- data/spec/data/audio/carlin_disappointed.wma +0 -0
- data/spec/data/audio/greensleeves.aac +0 -0
- data/spec/data/audio/greensleeves.ac3 +0 -0
- data/spec/data/audio/greensleeves.aiff +0 -0
- data/spec/data/audio/greensleeves.au +0 -0
- data/spec/data/audio/greensleeves.flac +0 -0
- data/spec/data/audio/greensleeves.m4a +0 -0
- data/spec/data/audio/greensleeves.mka +0 -0
- data/spec/data/audio/greensleeves.mp3 +0 -0
- data/spec/data/audio/greensleeves.ogg +0 -0
- data/spec/data/audio/greensleeves.ra +0 -0
- data/spec/data/audio/greensleeves.voc +0 -0
- data/spec/data/audio/greensleeves.wav +0 -0
- data/spec/data/audio/greensleeves.wma +0 -0
- data/spec/data/audio/king_nonviolence.aac +0 -0
- data/spec/data/audio/king_nonviolence.ac3 +0 -0
- data/spec/data/audio/king_nonviolence.aiff +0 -0
- data/spec/data/audio/king_nonviolence.au +0 -0
- data/spec/data/audio/king_nonviolence.flac +0 -0
- data/spec/data/audio/king_nonviolence.m4a +0 -0
- data/spec/data/audio/king_nonviolence.mka +0 -0
- data/spec/data/audio/king_nonviolence.mp3 +0 -0
- data/spec/data/audio/king_nonviolence.ogg +0 -0
- data/spec/data/audio/king_nonviolence.ra +0 -0
- data/spec/data/audio/king_nonviolence.voc +0 -0
- data/spec/data/audio/king_nonviolence.wav +0 -0
- data/spec/data/audio/king_nonviolence.wma +0 -0
- data/spec/data/audio/top_gun_secret.aac +0 -0
- data/spec/data/audio/top_gun_secret.ac3 +0 -0
- data/spec/data/audio/top_gun_secret.aiff +0 -0
- data/spec/data/audio/top_gun_secret.au +0 -0
- data/spec/data/audio/top_gun_secret.flac +0 -0
- data/spec/data/audio/top_gun_secret.m4a +0 -0
- data/spec/data/audio/top_gun_secret.mka +0 -0
- data/spec/data/audio/top_gun_secret.mp3 +0 -0
- data/spec/data/audio/top_gun_secret.ogg +0 -0
- data/spec/data/audio/top_gun_secret.ra +0 -0
- data/spec/data/audio/top_gun_secret.voc +0 -0
- data/spec/data/audio/top_gun_secret.wav +0 -0
- data/spec/data/audio/top_gun_secret.wma +0 -0
- data/spec/data/multipage.tif +0 -0
- data/spec/data/multipage.tif.jp2 +0 -0
- data/spec/data/test-ead.xml +0 -392
- data/spec/data/test-jpg.tif +0 -0
- data/spec/data/test-lzw.tif +0 -0
- data/spec/data/test-options.jpg +0 -0
- data/spec/data/test-options.png +0 -0
- data/spec/data/test.bmp +0 -0
- data/spec/data/test.doc +0 -0
- data/spec/data/test.docx +0 -0
- data/spec/data/test.gif +0 -0
- data/spec/data/test.jpg +0 -0
- data/spec/data/test.ods +0 -0
- data/spec/data/test.odt +0 -0
- data/spec/data/test.pdf +0 -0
- data/spec/data/test.pdf.tif +0 -0
- data/spec/data/test.png +0 -0
- data/spec/data/test.ps +0 -8631
- data/spec/data/test.psd +0 -0
- data/spec/data/test.rtf +0 -1455
- data/spec/data/test.tif +0 -0
- data/spec/data/test.txt +0 -12
- data/spec/data/test.xcf +0 -0
- data/spec/data/test.xls +0 -0
- data/spec/data/test.xlsx +0 -0
- data/spec/data/test.xml +0 -4
- data/spec/data/test_pdfa.pdf +0 -0
- data/spec/data/video/SampleVideo_1080x720_2mb.flv +0 -0
- data/spec/data/video/SampleVideo_1080x720_2mb.mkv +0 -0
- data/spec/data/video/SampleVideo_1080x720_2mb.mp4 +0 -0
- data/spec/data/video/SampleVideo_176x144_2mb.3gp +0 -0
- data/spec/data/video/SampleVideo_320x240_2mb.3gp +0 -0
- data/spec/data/video/SampleVideo_360x240_2mb.flv +0 -0
- data/spec/data/video/SampleVideo_360x240_2mb.mkv +0 -0
- data/spec/data/video/SampleVideo_360x240_2mb.mp4 +0 -0
- data/spec/data/video/copyright.png +0 -0
- data/spec/data/xml/134476_ead.XML +0 -1
- data/spec/data/xml/134476_ead.pdf +0 -0
- data/spec/data/xml/134476_fo.XML +0 -383
- data/spec/data/xml/134476_raw.XML +0 -141
- data/spec/data/xml/ead2fo_pdf.xsl +0 -1453
- data/spec/data/xml/header_nolink_pdf.xsl +0 -120
- data/spec/data/xml/lookupLists.xsl +0 -488
- data/spec/data/xml/scope_eadToHTML.xsl +0 -2376
- data/spec/data/xml/scope_xmlToEAD_dom.xsl +0 -952
- data/spec/identifier_spec.rb +0 -161
- data/spec/spec_helper.rb +0 -58
- data/spec/test_types.yml +0 -12
- data/spec/type_database_spec.rb +0 -140
- data/tools/bcpkix-jdk15on-1.49.jar +0 -0
- data/tools/bcprov-jdk15on-1.49.jar +0 -0
- data/tools/pdfbox/preflight-app-1.8.10.jar +0 -0
|
@@ -4,28 +4,29 @@ require_relative 'base'
|
|
|
4
4
|
require 'libis/format/identifier'
|
|
5
5
|
|
|
6
6
|
require 'mini_magick'
|
|
7
|
-
require 'fileutils'
|
|
8
7
|
|
|
9
|
-
MiniMagick.logger.level = ::Logger::
|
|
8
|
+
MiniMagick.logger.level = ::Logger::UNKNOWN
|
|
10
9
|
|
|
11
10
|
MiniMagick.configure do |config|
|
|
12
11
|
# config.cli = :graphicsmagick
|
|
13
12
|
config.validate_on_create = false
|
|
14
13
|
config.validate_on_write = false
|
|
14
|
+
config.whiny = false
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
module Libis
|
|
18
18
|
module Format
|
|
19
19
|
module Converter
|
|
20
20
|
|
|
21
|
+
# noinspection RubyTooManyInstanceVariablesInspection
|
|
21
22
|
class ImageConverter < Libis::Format::Converter::Base
|
|
22
23
|
|
|
23
24
|
def self.input_types
|
|
24
|
-
[:TIFF, :JPG, :PNG, :BMP, :GIF, :PDF, :JP2]
|
|
25
|
+
[:TIFF, :JPG, :PNG, :BMP, :GIF, :PDF, :JP2, :PBM, :PGM, :PPM]
|
|
25
26
|
end
|
|
26
27
|
|
|
27
28
|
def self.output_types(format = nil)
|
|
28
|
-
return [] unless input_types.include?(format)
|
|
29
|
+
return [] unless input_types.include?(format) if format
|
|
29
30
|
[:TIFF, :JPG, :PNG, :BMP, :GIF, :PDF, :JP2]
|
|
30
31
|
end
|
|
31
32
|
|
|
@@ -43,101 +44,58 @@ module Libis
|
|
|
43
44
|
end
|
|
44
45
|
|
|
45
46
|
def quiet(v)
|
|
46
|
-
@
|
|
47
|
+
@quiet = !!v
|
|
48
|
+
self
|
|
47
49
|
end
|
|
48
50
|
|
|
49
51
|
def page(nr)
|
|
50
52
|
@page = nr
|
|
53
|
+
self
|
|
51
54
|
end
|
|
52
55
|
|
|
53
56
|
def scale(percent)
|
|
54
57
|
@options[:scale] = percent
|
|
58
|
+
self
|
|
55
59
|
end
|
|
56
60
|
|
|
57
61
|
def resize(geometry)
|
|
58
62
|
@options[:resize] = geometry
|
|
63
|
+
self
|
|
59
64
|
end
|
|
60
65
|
|
|
61
66
|
def quality(value)
|
|
62
67
|
@options[:quality] = value
|
|
68
|
+
self
|
|
63
69
|
end
|
|
64
70
|
|
|
65
71
|
def dpi(value)
|
|
66
72
|
@options[:density] = value
|
|
73
|
+
self
|
|
67
74
|
end
|
|
68
75
|
|
|
69
76
|
def resample(value)
|
|
70
77
|
@options[:resample] = value
|
|
78
|
+
self
|
|
71
79
|
end
|
|
72
80
|
|
|
73
|
-
def flatten
|
|
74
|
-
@
|
|
81
|
+
def flatten(value = true)
|
|
82
|
+
@options[:flatten] = value
|
|
83
|
+
self
|
|
75
84
|
end
|
|
76
85
|
|
|
77
86
|
def colorspace(value)
|
|
78
87
|
@options[:colorspace] = value
|
|
88
|
+
self
|
|
79
89
|
end
|
|
80
90
|
|
|
81
|
-
def delete_date
|
|
82
|
-
@delete_date =
|
|
91
|
+
def delete_date(value = true)
|
|
92
|
+
@delete_date = value
|
|
93
|
+
self
|
|
83
94
|
end
|
|
84
95
|
|
|
85
96
|
def profile(icc)
|
|
86
97
|
@profile = icc
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
# Create or use a watermark image.
|
|
90
|
-
#
|
|
91
|
-
# The watermark options are:
|
|
92
|
-
# - file: watermark image to use
|
|
93
|
-
# - text: text to create a watermark from
|
|
94
|
-
# - rotation: rotation of the watermark text (counter clockwise in degrees; integer number) - default 30
|
|
95
|
-
# - size: size of the watermark (integer > 0, 1/n of image size) - default 4
|
|
96
|
-
# - opacity: opacity of the watermark (fraction 0.0 - 1.0) - default 0.3
|
|
97
|
-
# - gap: size of the gap between watermark instances. Fractions as percentage of widht/height. - default 0.2
|
|
98
|
-
# If both options are given, the file will be used as-is if it exists and is a valid image file. Otherwise the
|
|
99
|
-
# file will be created or overwritten with a newly created watermark image.
|
|
100
|
-
#
|
|
101
|
-
# The created watermark file will be a PNG image with transparent background containing the supplied text
|
|
102
|
-
# slanted by 30 degrees counter-clockwise.
|
|
103
|
-
#
|
|
104
|
-
# @param [Hash] options Hash of options for watermark creation.
|
|
105
|
-
def watermark(options = {})
|
|
106
|
-
text = options[:text] || '© LIBIS'
|
|
107
|
-
@wm_size = (options[:size] || '4').to_i
|
|
108
|
-
@wm_opacity = ((options[:opacity] || 0.1).to_f * 100).to_i
|
|
109
|
-
@wm_composition = options[:composition] || 'modulate'
|
|
110
|
-
gap = ((options[:gap] || 0.2).to_f * 100).to_i
|
|
111
|
-
rotation = 360 - (options[:rotation] || 30).to_i
|
|
112
|
-
@wm_image = MiniMagick::Image.new(options[:file]) if options[:file]
|
|
113
|
-
unless @wm_image && @wm_image.valid?
|
|
114
|
-
image = options[:file] || (Dir::Tmpname.create(%w(wm_image .png)) { |_|})
|
|
115
|
-
# noinspection RubyResolve
|
|
116
|
-
MiniMagick::Tool::Convert.new do |convert|
|
|
117
|
-
# noinspection RubyLiteralArrayInspection
|
|
118
|
-
convert.quiet
|
|
119
|
-
convert.background 'transparent'
|
|
120
|
-
convert.size('2000x2000')
|
|
121
|
-
convert.gravity 'Center'
|
|
122
|
-
convert.font('Helvetica').fill('black').pointsize(72) #.stroke('black').strokewidth(1)
|
|
123
|
-
convert << "label:#{text}"
|
|
124
|
-
convert.rotate rotation
|
|
125
|
-
convert.trim.repage.+
|
|
126
|
-
convert.bordercolor('transparent').border("#{gap}%")
|
|
127
|
-
convert << image
|
|
128
|
-
end
|
|
129
|
-
if options[:file]
|
|
130
|
-
@wm_image = MiniMagick::Image.new(image)
|
|
131
|
-
else
|
|
132
|
-
@wm_image = MiniMagick::Image.open(image)
|
|
133
|
-
File.delete(image)
|
|
134
|
-
end
|
|
135
|
-
# noinspection RubyResolve
|
|
136
|
-
unless @wm_image.valid?
|
|
137
|
-
error "Problem creating watermark image '#{image}'."
|
|
138
|
-
@wm_image = nil
|
|
139
|
-
end
|
|
140
|
-
end
|
|
98
|
+
self
|
|
141
99
|
end
|
|
142
100
|
|
|
143
101
|
def convert(source, target, format, opts = {})
|
|
@@ -145,81 +103,26 @@ module Libis
|
|
|
145
103
|
|
|
146
104
|
FileUtils.mkpath(File.dirname(target))
|
|
147
105
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
assemble_and_convert(source, target, format)
|
|
151
|
-
|
|
152
|
-
elsif File.directory?(source)
|
|
153
|
-
source_list = Dir[File.join(source, '**', '*')].reject { |p| File.directory? p }
|
|
154
|
-
|
|
155
|
-
assemble_and_convert(source_list, target, format)
|
|
156
|
-
|
|
157
|
-
else
|
|
158
|
-
|
|
159
|
-
image = MiniMagick::Image.new(source)
|
|
160
|
-
|
|
161
|
-
if image.pages.size > 1
|
|
162
|
-
if @page
|
|
163
|
-
convert_image(image.pages[@page].path, target, format)
|
|
164
|
-
else
|
|
165
|
-
assemble_and_convert(image.pages.map { |page| page.path }, target, format)
|
|
166
|
-
end
|
|
167
|
-
else
|
|
168
|
-
convert_image(source, target, format)
|
|
169
|
-
end
|
|
170
|
-
end
|
|
106
|
+
convert_image(source, target, format)
|
|
171
107
|
|
|
172
108
|
target
|
|
173
109
|
|
|
174
110
|
end
|
|
175
111
|
|
|
176
|
-
def assemble_and_convert(sources, target, format)
|
|
177
|
-
|
|
178
|
-
warn 'Received multiple images as input and single page format as target.' unless self.class.multipage?(format)
|
|
179
|
-
converted_pages = sources.inject([]) do |list, path|
|
|
180
|
-
converted = Tempfile.new(['page-', ".#{Libis::Format::TypeDatabase.type_extentions(format).first}"])
|
|
181
|
-
convert_image(path, converted.path, format)
|
|
182
|
-
list << converted
|
|
183
|
-
end
|
|
184
|
-
MiniMagick::Tool::Convert.new do |b|
|
|
185
|
-
b.append unless self.class.multipage?(format)
|
|
186
|
-
converted_pages.each { |page| b << page.path }
|
|
187
|
-
b << target
|
|
188
|
-
end
|
|
189
|
-
converted_pages.each do |temp_file|
|
|
190
|
-
temp_file.close
|
|
191
|
-
temp_file.unlink
|
|
192
|
-
end
|
|
193
|
-
end
|
|
194
|
-
|
|
195
112
|
protected
|
|
196
113
|
|
|
197
114
|
def convert_image(source, target, format)
|
|
198
115
|
|
|
199
|
-
|
|
200
|
-
|
|
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
|
|
201
120
|
|
|
202
121
|
MiniMagick::Tool::Convert.new do |convert|
|
|
203
|
-
if @
|
|
204
|
-
convert << @wm_image.path
|
|
205
|
-
convert.filter('Lagrange')
|
|
206
|
-
convert.resize("#{image_info['width'] / @wm_size}x#{image_info['height'] / @wm_size}").write('mpr:watermark').delete.+
|
|
207
|
-
end
|
|
208
|
-
|
|
122
|
+
convert.quiet if @quiet
|
|
209
123
|
convert << source
|
|
210
|
-
convert.flatten if format == :JPG
|
|
211
|
-
|
|
212
|
-
# noinspection RubyResolve
|
|
213
|
-
convert.stack do |stack|
|
|
214
|
-
stack.size("#{image_info['width']}x#{image_info['height']}")
|
|
215
|
-
stack << 'xc:transparent'
|
|
216
|
-
stack.tile('mpr:watermark')
|
|
217
|
-
stack.draw "rectangle 0,0,#{image_info['width']},#{image_info['height']}"
|
|
218
|
-
end
|
|
219
|
-
convert.compose(@wm_composition).define("compose:args=#{@wm_opacity}").composite
|
|
220
|
-
end
|
|
221
|
-
|
|
222
|
-
@flags.each { |f, v| v.is_a?(FalseClass) ? convert.send(f).+ : convert.send(f) }
|
|
124
|
+
convert.flatten if @options[:flatten].nil? && format == :JPG
|
|
125
|
+
@flags.each {|f, v| v.is_a?(TrueClass) ? convert.send(f).+ : convert.send(f)}
|
|
223
126
|
if @delete_date
|
|
224
127
|
convert << '+set' << 'modify-date' << '+set' << 'create-date'
|
|
225
128
|
end
|
|
@@ -227,13 +130,15 @@ module Libis
|
|
|
227
130
|
colorspace = @options.delete(:colorspace) || 'sRGB'
|
|
228
131
|
unless @options.empty?
|
|
229
132
|
convert.colorspace('RGB')
|
|
230
|
-
@options.each {
|
|
133
|
+
@options.each {|o, v| convert.send(o, v)}
|
|
231
134
|
end
|
|
232
135
|
convert.colorspace(colorspace)
|
|
233
136
|
convert.profile @profile if @profile
|
|
234
137
|
|
|
235
138
|
convert.format(format)
|
|
236
139
|
convert << target
|
|
140
|
+
|
|
141
|
+
debug "ImageMagick command: '#{convert.command.join(' ')}'"
|
|
237
142
|
end
|
|
238
143
|
|
|
239
144
|
target
|
|
@@ -0,0 +1,84 @@
|
|
|
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
|
+
class ImageSplitter < Libis::Format::Converter::Base
|
|
22
|
+
|
|
23
|
+
def self.input_types
|
|
24
|
+
[:PDF, :TIFF, :GIF, :PBM, :PGM, :PPM]
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def self.output_types(format = nil)
|
|
28
|
+
return [] unless input_types.include?(format) if format
|
|
29
|
+
[:TIFF, :JPG, :PNG, :BMP, :GIF, :PDF, :JP2]
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def self.multipage?(format)
|
|
33
|
+
[:PDF, :TIFF, :GIF, :PBM, :PGM, :PPM].include?(format)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def self.category
|
|
37
|
+
:splitter
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def image_split(_)
|
|
41
|
+
#force usage of this converter
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def quiet(v)
|
|
45
|
+
@quiet = !!v
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def convert(source, target, format, opts = {})
|
|
49
|
+
super
|
|
50
|
+
|
|
51
|
+
FileUtils.mkpath(File.dirname(target))
|
|
52
|
+
|
|
53
|
+
if self.class.multipage?(format)
|
|
54
|
+
target = File.join(File.dirname(target), "#{File.basename(target, '.*')}-%d#{File.extname(target)}")
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
result = split_image(source, target, format)
|
|
58
|
+
return nil unless result
|
|
59
|
+
target
|
|
60
|
+
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
private
|
|
64
|
+
|
|
65
|
+
def split_image(source, target, format)
|
|
66
|
+
|
|
67
|
+
MiniMagick::Tool::Convert.new do |convert|
|
|
68
|
+
convert.quiet if @quiet
|
|
69
|
+
convert << source
|
|
70
|
+
convert.format(format)
|
|
71
|
+
convert << target
|
|
72
|
+
|
|
73
|
+
debug "ImageMagick command: '#{convert.command.join(' ')}'"
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
target
|
|
77
|
+
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require_relative 'base'
|
|
4
|
+
require 'libis/format/identifier'
|
|
5
|
+
|
|
6
|
+
require 'mini_magick'
|
|
7
|
+
# noinspection RubyResolve
|
|
8
|
+
require 'fileutils'
|
|
9
|
+
|
|
10
|
+
MiniMagick.logger.level = ::Logger::UNKNOWN
|
|
11
|
+
|
|
12
|
+
MiniMagick.configure do |config|
|
|
13
|
+
# config.cli = :graphicsmagick
|
|
14
|
+
config.validate_on_create = false
|
|
15
|
+
config.validate_on_write = false
|
|
16
|
+
config.whiny = false
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
module Libis
|
|
20
|
+
module Format
|
|
21
|
+
module Converter
|
|
22
|
+
|
|
23
|
+
# noinspection RubyTooManyInstanceVariablesInspection
|
|
24
|
+
class ImageWatermarker < Libis::Format::Converter::Base
|
|
25
|
+
|
|
26
|
+
def self.input_types
|
|
27
|
+
[:TIFF, :JPG, :PNG, :BMP, :GIF, :PDF, :JP2]
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def self.output_types(format = nil)
|
|
31
|
+
return [] unless input_types.include?(format) if format
|
|
32
|
+
[format]
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def self.multipage?(format)
|
|
36
|
+
[:PDF, :TIFF, :GIF, :PBM, :PGM, :PPM].include?(format)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def initialize
|
|
40
|
+
super
|
|
41
|
+
@quiet = true
|
|
42
|
+
@wm_image = nil
|
|
43
|
+
@wm_file = nil
|
|
44
|
+
@wm_text = '© LIBIS'
|
|
45
|
+
@wm_tiles = 4
|
|
46
|
+
@wm_resize = nil
|
|
47
|
+
@wm_gap = 20
|
|
48
|
+
@wm_gravity = 'Center'
|
|
49
|
+
@wm_rotation = 30
|
|
50
|
+
@wm_composition ='modulate'
|
|
51
|
+
@wm_composition_args = '10'
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def image_watermark(_)
|
|
55
|
+
#force usage of this converter
|
|
56
|
+
self
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def quiet(v)
|
|
60
|
+
@quiet = !!v
|
|
61
|
+
self
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def page(v)
|
|
65
|
+
@page = v.to_i
|
|
66
|
+
self
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# watermark image to use
|
|
70
|
+
def file(v)
|
|
71
|
+
@wm_file = v.blank? ? nil : v
|
|
72
|
+
self
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# text to create a watermark from
|
|
76
|
+
def text(v)
|
|
77
|
+
@wm_text = v.blank? ? nil : v
|
|
78
|
+
self
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# rotation of the watermark text (counter clockwise in degrees; integer number)
|
|
82
|
+
# default 30
|
|
83
|
+
def rotation(v)
|
|
84
|
+
@wm_rotation = v.to_i
|
|
85
|
+
self
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# number of tiles of the watermark
|
|
89
|
+
# default 4
|
|
90
|
+
# 0: no tiling, so only 1 watermark will be placed with the original size
|
|
91
|
+
# 1: 1 tile, so the watermark will be scaled up to fill the image
|
|
92
|
+
# n > 1: minimum n tiles in both directions
|
|
93
|
+
# n < 0: tile without scaling the watermark
|
|
94
|
+
def tiles(v)
|
|
95
|
+
@wm_tiles = v.to_i
|
|
96
|
+
self
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# fraction 0.0 - 1.0
|
|
100
|
+
def resize(v)
|
|
101
|
+
@wm_resize = (v.to_f * 100).to_i
|
|
102
|
+
self
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# size of the gap between watermark instances. Fractions as percentage of widht/height
|
|
106
|
+
# default 0.2
|
|
107
|
+
def gap(v)
|
|
108
|
+
@wm_gap = (v.to_f * 100).to_i
|
|
109
|
+
self
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# center point for the watermark overlay
|
|
113
|
+
# default 'center'
|
|
114
|
+
def gravity(v)
|
|
115
|
+
@wm_gravity = v.blank? ? nil : v
|
|
116
|
+
self
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# the image composition method for merging the watermark image
|
|
120
|
+
# default 'modulate'
|
|
121
|
+
# See https://imagemagick.org/script/compose.php for more information
|
|
122
|
+
def composition(v)
|
|
123
|
+
@wm_composition = v.blank? ? nil : v
|
|
124
|
+
self
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# arguments for the composition method
|
|
128
|
+
# default '10'
|
|
129
|
+
# See https://imagemagick.org/script/compose.php for more information
|
|
130
|
+
def composition_args(v)
|
|
131
|
+
@wm_composition_args = v.blank? ? nil : v
|
|
132
|
+
self
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def convert(source, target, format, opts = {})
|
|
137
|
+
super
|
|
138
|
+
|
|
139
|
+
FileUtils.mkpath(File.dirname(target))
|
|
140
|
+
|
|
141
|
+
if source.is_a?(Array) || File.directory?(source)
|
|
142
|
+
error 'Only a single image file is allowed for input'
|
|
143
|
+
else
|
|
144
|
+
image = MiniMagick::Image.open(source) { |b| b.quiet }
|
|
145
|
+
|
|
146
|
+
if image.pages.size > 1
|
|
147
|
+
if @page
|
|
148
|
+
convert_image(image.pages[@page].path, target, format)
|
|
149
|
+
else
|
|
150
|
+
error 'multipage input file detecte; you need to supply a page number'
|
|
151
|
+
end
|
|
152
|
+
else
|
|
153
|
+
convert_image(source, target, format)
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
target
|
|
158
|
+
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
protected
|
|
162
|
+
|
|
163
|
+
# noinspection DuplicatedCode
|
|
164
|
+
def convert_image(source, target, format)
|
|
165
|
+
|
|
166
|
+
wm_image = watermark_image
|
|
167
|
+
return nil unless wm_image
|
|
168
|
+
image_info = MiniMagick::Image::Info.new(source) {|b| b.quiet}
|
|
169
|
+
|
|
170
|
+
MiniMagick::Tool::Convert.new do |convert|
|
|
171
|
+
convert.quiet if @quiet
|
|
172
|
+
|
|
173
|
+
# adapt watermark image to tile size and apply gap and resize if necessary
|
|
174
|
+
convert << @wm_image.path
|
|
175
|
+
# noinspection RubyResolve
|
|
176
|
+
convert.bordercolor('transparent').border("#{@wm_gap}%") if @wm_gap > 0
|
|
177
|
+
convert.filter('Lagrange')
|
|
178
|
+
convert.resize("#{image_info['width'] / @wm_tiles}x#{image_info['height'] / @wm_tiles}") if @wm_tiles > 0
|
|
179
|
+
convert.resize("#{@wm_resize}%") if @wm_resize
|
|
180
|
+
convert.write('mpr:watermark').delete.+
|
|
181
|
+
|
|
182
|
+
# convert the source image
|
|
183
|
+
convert << source
|
|
184
|
+
if @wm_tiles >= 0 and @wm_tiles <= 1
|
|
185
|
+
# only 1 watermark required (tiles = 0/1 => scaled no/yes)
|
|
186
|
+
convert << 'mpr:watermark'
|
|
187
|
+
else
|
|
188
|
+
# fill the image size with a pattern of the watermark image
|
|
189
|
+
convert.stack do |stack|
|
|
190
|
+
stack.size("#{image_info['width']}x#{image_info['height']}")
|
|
191
|
+
stack << 'xc:transparent'
|
|
192
|
+
# noinspection RubyResolve
|
|
193
|
+
stack.tile('mpr:watermark')
|
|
194
|
+
# noinspection RubyResolve
|
|
195
|
+
stack.draw "rectangle 0,0,#{image_info['width']},#{image_info['height']}"
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
# perform the blending operation
|
|
199
|
+
convert.compose(@wm_composition).gravity(@wm_gravity).define("compose:args=#{@wm_composition_args}").composite
|
|
200
|
+
|
|
201
|
+
convert.format(format)
|
|
202
|
+
convert << target
|
|
203
|
+
|
|
204
|
+
debug "ImageMagick command: '#{convert.command.join(' ')}'"
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
target
|
|
208
|
+
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
private
|
|
212
|
+
|
|
213
|
+
# Create or use a watermark image.
|
|
214
|
+
#
|
|
215
|
+
# If both text and image are set, the file will be used as-is if it exists and is a valid image file. Otherwise the
|
|
216
|
+
# file will be created or overwritten with a newly created watermark image.
|
|
217
|
+
#
|
|
218
|
+
# The created watermark file will be a 2000x2000 pixels PNG image with transparent background
|
|
219
|
+
#
|
|
220
|
+
# The text will be slanted by given rotation degrees counter-clockwise
|
|
221
|
+
def watermark_image
|
|
222
|
+
rotation = 360 - @wm_rotation
|
|
223
|
+
@wm_image = MiniMagick::Image.new(@wm_file) if @wm_file
|
|
224
|
+
# only create image if file is not an image
|
|
225
|
+
unless @wm_image&.valid?
|
|
226
|
+
# noinspection RubyResolve
|
|
227
|
+
# Create image file (as given or temp file)
|
|
228
|
+
image = @wm_file || (Dir::Tmpname.create(%w(wm_image .png)) {|_|})
|
|
229
|
+
# noinspection RubyResolve
|
|
230
|
+
MiniMagick::Tool::Convert.new do |convert|
|
|
231
|
+
convert.quiet # allways quiet
|
|
232
|
+
convert.background 'transparent'
|
|
233
|
+
convert.size('2000x2000')
|
|
234
|
+
convert.gravity 'Center'
|
|
235
|
+
convert.font('Helvetica').fill('black').pointsize(72) #.stroke('black').strokewidth(1)
|
|
236
|
+
convert << "label:#{@wm_text}"
|
|
237
|
+
convert.rotate rotation
|
|
238
|
+
convert.trim.repage.+
|
|
239
|
+
convert << image
|
|
240
|
+
end
|
|
241
|
+
if @wm_file
|
|
242
|
+
@wm_image = MiniMagick::Image.new(image)
|
|
243
|
+
else # delete temp file
|
|
244
|
+
@wm_image = MiniMagick::Image.open(image)
|
|
245
|
+
File.delete(image)
|
|
246
|
+
end
|
|
247
|
+
# noinspection RubyResolve
|
|
248
|
+
unless @wm_image.valid?
|
|
249
|
+
error "Problem creating watermark image '#{image}'."
|
|
250
|
+
@wm_image = nil
|
|
251
|
+
end
|
|
252
|
+
@wm_image
|
|
253
|
+
end
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
end
|
|
260
|
+
end
|
|
261
|
+
end
|