mini_magick 4.3.6 → 4.7.2
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.
Potentially problematic release.
This version of mini_magick might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/lib/mini_magick/configuration.rb +6 -3
- data/lib/mini_magick/image/info.rb +60 -11
- data/lib/mini_magick/image.rb +78 -21
- data/lib/mini_magick/shell.rb +47 -19
- data/lib/mini_magick/tool/mogrify_restricted.rb +15 -0
- data/lib/mini_magick/tool.rb +67 -12
- data/lib/mini_magick/utilities.rb +1 -1
- data/lib/mini_magick/version.rb +2 -2
- metadata +48 -7
- data/lib/mini_magick/logger.rb +0 -38
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3f5606d4a6e91d6ad90a393da30244dc774e374b
|
4
|
+
data.tar.gz: 71ff2a31e86426bfd514879b787fd530cf2717ad
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5b17e89081bd677cd255e377c9dd22b64bc37dc467a81f4bbd0d7fde27cc552d99f3927d23ce48c9becabe37234652cd0fdd913062316fe57c3b85a003d51ad7
|
7
|
+
data.tar.gz: 32d0e633b52b6d6104fa8633db9579dbe78513a3ad997737bc1506c3cc9ddb375015afbc3423fc9ee72b3fba4c710597306c167c2094f33b792f9f9c383a6d85
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'mini_magick/utilities'
|
2
|
+
require 'logger'
|
2
3
|
|
3
4
|
module MiniMagick
|
4
5
|
module Configuration
|
@@ -86,6 +87,7 @@ module MiniMagick
|
|
86
87
|
base.validate_on_write = true
|
87
88
|
base.whiny = true
|
88
89
|
base.shell_api = "open3"
|
90
|
+
base.logger = Logger.new($stdout).tap { |l| l.level = Logger::INFO }
|
89
91
|
end
|
90
92
|
|
91
93
|
##
|
@@ -140,13 +142,14 @@ module MiniMagick
|
|
140
142
|
@cli_path || @processor_path
|
141
143
|
end
|
142
144
|
|
143
|
-
def
|
144
|
-
|
145
|
+
def debug=(value)
|
146
|
+
warn "MiniMagick.debug is deprecated and will be removed in MiniMagick 5. Use `MiniMagick.logger.level = Logger::DEBUG` instead."
|
147
|
+
logger.level = value ? Logger::DEBUG : Logger::INFO
|
145
148
|
end
|
146
149
|
|
147
150
|
# Backwards compatibility
|
148
151
|
def reload_tools
|
149
|
-
warn "
|
152
|
+
warn "MiniMagick.reload_tools is deprecated because it is no longer necessary"
|
150
153
|
end
|
151
154
|
|
152
155
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require "json"
|
2
|
+
|
1
3
|
module MiniMagick
|
2
4
|
class Image
|
3
5
|
# @private
|
@@ -27,6 +29,8 @@ module MiniMagick
|
|
27
29
|
exif
|
28
30
|
when "details"
|
29
31
|
details
|
32
|
+
when "data"
|
33
|
+
data
|
30
34
|
else
|
31
35
|
raw(value)
|
32
36
|
end
|
@@ -80,16 +84,29 @@ module MiniMagick
|
|
80
84
|
|
81
85
|
def exif
|
82
86
|
@info["exif"] ||= (
|
87
|
+
hash = {}
|
83
88
|
output = self["%[EXIF:*]"]
|
84
|
-
pairs = output.gsub(/^exif:/, "").split("\n").map { |line| line.split("=") }
|
85
|
-
Hash[pairs].tap do |hash|
|
86
|
-
ASCII_ENCODED_EXIF_KEYS.each do |key|
|
87
|
-
next unless hash.has_key?(key)
|
88
89
|
|
89
|
-
|
90
|
-
|
90
|
+
output.each_line do |line|
|
91
|
+
line = line.chomp("\n")
|
92
|
+
|
93
|
+
case MiniMagick.cli
|
94
|
+
when :imagemagick
|
95
|
+
if match = line.match(/^exif:/)
|
96
|
+
key, value = match.post_match.split("=", 2)
|
97
|
+
value = decode_comma_separated_ascii_characters(value) if ASCII_ENCODED_EXIF_KEYS.include?(key)
|
98
|
+
hash[key] = value
|
99
|
+
else
|
100
|
+
hash[hash.keys.last] << "\n#{line}"
|
101
|
+
end
|
102
|
+
when :graphicsmagick
|
103
|
+
key, value = line.split("=", 2)
|
104
|
+
value.gsub!("\\012", "\n") # convert "\012" characters to newlines
|
105
|
+
hash[key] = value
|
91
106
|
end
|
92
107
|
end
|
108
|
+
|
109
|
+
hash
|
93
110
|
)
|
94
111
|
end
|
95
112
|
|
@@ -102,13 +119,25 @@ module MiniMagick
|
|
102
119
|
end
|
103
120
|
|
104
121
|
def details
|
122
|
+
warn "[MiniMagick] MiniMagick::Image#details has been deprecated, as it was causing too many parsing errors. You should use MiniMagick::Image#data instead, which differs in a way that the keys are in camelcase." if MiniMagick.imagemagick?
|
123
|
+
|
105
124
|
@info["details"] ||= (
|
106
125
|
details_string = identify(&:verbose)
|
107
126
|
key_stack = []
|
108
127
|
details_string.lines.to_a[1..-1].each_with_object({}) do |line, details_hash|
|
109
|
-
next if line.strip.length.zero?
|
128
|
+
next if !line.valid_encoding? || line.strip.length.zero?
|
129
|
+
|
110
130
|
level = line[/^\s*/].length / 2 - 1
|
111
|
-
|
131
|
+
if level >= 0
|
132
|
+
key_stack.pop until key_stack.size <= level
|
133
|
+
else
|
134
|
+
# Some metadata, such as SVG clipping paths, will be saved without
|
135
|
+
# indentation, resulting in a level of -1
|
136
|
+
last_key = details_hash.keys.last
|
137
|
+
details_hash[last_key] = '' if details_hash[last_key].empty?
|
138
|
+
details_hash[last_key] << line
|
139
|
+
next
|
140
|
+
end
|
112
141
|
|
113
142
|
key, _, value = line.partition(/:[\s\n]/).map(&:strip)
|
114
143
|
hash = key_stack.inject(details_hash) { |hash, key| hash.fetch(key) }
|
@@ -122,21 +151,41 @@ module MiniMagick
|
|
122
151
|
)
|
123
152
|
end
|
124
153
|
|
125
|
-
def
|
126
|
-
|
127
|
-
path += "[0]" unless path =~ /\[\d+\]$/
|
154
|
+
def data
|
155
|
+
raise Error, "MiniMagick::Image#data isn't supported on GraphicsMagick. Use MiniMagick::Image#details instead." if MiniMagick.graphicsmagick?
|
128
156
|
|
157
|
+
@info["data"] ||= (
|
158
|
+
json = MiniMagick::Tool::Convert.new do |convert|
|
159
|
+
convert << path
|
160
|
+
convert << "json:"
|
161
|
+
end
|
162
|
+
|
163
|
+
data = JSON.parse(json)
|
164
|
+
data = data.fetch(0) if data.is_a?(Array)
|
165
|
+
data.fetch("image")
|
166
|
+
)
|
167
|
+
end
|
168
|
+
|
169
|
+
def identify
|
129
170
|
MiniMagick::Tool::Identify.new do |builder|
|
130
171
|
yield builder if block_given?
|
131
172
|
builder << path
|
132
173
|
end
|
133
174
|
end
|
134
175
|
|
176
|
+
private
|
177
|
+
|
135
178
|
def decode_comma_separated_ascii_characters(encoded_value)
|
136
179
|
return encoded_value unless encoded_value.include?(',')
|
137
180
|
encoded_value.scan(/\d+/).map(&:to_i).map(&:chr).join
|
138
181
|
end
|
139
182
|
|
183
|
+
def path
|
184
|
+
value = @path
|
185
|
+
value += "[0]" unless value =~ /\[\d+\]$/
|
186
|
+
value
|
187
|
+
end
|
188
|
+
|
140
189
|
end
|
141
190
|
end
|
142
191
|
end
|
data/lib/mini_magick/image.rb
CHANGED
@@ -86,6 +86,8 @@ module MiniMagick
|
|
86
86
|
File.extname(URI(path_or_url).path)
|
87
87
|
end
|
88
88
|
|
89
|
+
ext.sub!(/:.*/, '') # hack for filenames or URLs that include a colon
|
90
|
+
|
89
91
|
Kernel.open(path_or_url, "rb") do |file|
|
90
92
|
read(file, ext)
|
91
93
|
end
|
@@ -133,6 +135,10 @@ module MiniMagick
|
|
133
135
|
# @return [String] The location of the current working file
|
134
136
|
#
|
135
137
|
attr_reader :path
|
138
|
+
##
|
139
|
+
# @return [Tempfile] The underlying temporary file
|
140
|
+
#
|
141
|
+
attr_reader :tempfile
|
136
142
|
|
137
143
|
##
|
138
144
|
# Create a new {MiniMagick::Image} object.
|
@@ -141,23 +147,22 @@ module MiniMagick
|
|
141
147
|
# is, it gets *modified*. You can either copy it yourself or use {.open}
|
142
148
|
# which creates a temporary file for you and protects your original.
|
143
149
|
#
|
144
|
-
# @param input_path [String] The location of an image file
|
150
|
+
# @param input_path [String, Pathname] The location of an image file
|
145
151
|
# @yield [MiniMagick::Tool::Mogrify] If block is given, {#combine_options}
|
146
152
|
# is called.
|
147
153
|
#
|
148
154
|
def initialize(input_path, tempfile = nil, &block)
|
149
|
-
@path = input_path
|
155
|
+
@path = input_path.to_s
|
150
156
|
@tempfile = tempfile
|
151
157
|
@info = MiniMagick::Image::Info.new(@path)
|
152
158
|
|
153
159
|
combine_options(&block) if block
|
154
160
|
end
|
155
161
|
|
156
|
-
def
|
157
|
-
self.class
|
158
|
-
signature == other.signature
|
162
|
+
def ==(other)
|
163
|
+
self.class == other.class && signature == other.signature
|
159
164
|
end
|
160
|
-
alias
|
165
|
+
alias eql? ==
|
161
166
|
|
162
167
|
def hash
|
163
168
|
signature.hash
|
@@ -265,7 +270,14 @@ module MiniMagick
|
|
265
270
|
#
|
266
271
|
attribute :signature
|
267
272
|
##
|
268
|
-
# Returns the information from `identify -verbose` in a Hash format
|
273
|
+
# Returns the information from `identify -verbose` in a Hash format, for
|
274
|
+
# ImageMagick.
|
275
|
+
#
|
276
|
+
# @return [Hash]
|
277
|
+
attribute :data
|
278
|
+
##
|
279
|
+
# Returns the information from `identify -verbose` in a Hash format, for
|
280
|
+
# GraphicsMagick.
|
269
281
|
#
|
270
282
|
# @return [Hash]
|
271
283
|
attribute :details
|
@@ -306,6 +318,47 @@ module MiniMagick
|
|
306
318
|
alias pages layers
|
307
319
|
alias frames layers
|
308
320
|
|
321
|
+
##
|
322
|
+
# Returns a matrix of pixels from the image. The matrix is constructed as
|
323
|
+
# an array (1) of arrays (2) of arrays (3) of unsigned integers:
|
324
|
+
#
|
325
|
+
# 1) one for each row of pixels
|
326
|
+
# 2) one for each column of pixels
|
327
|
+
# 3) three elements in the range 0-255, one for each of the RGB color channels
|
328
|
+
#
|
329
|
+
# @example
|
330
|
+
# img = MiniMagick::Image.open 'image.jpg'
|
331
|
+
# pixels = img.get_pixels
|
332
|
+
# pixels[3][2][1] # the green channel value from the 4th-row, 3rd-column pixel
|
333
|
+
#
|
334
|
+
# It can also be called after applying transformations:
|
335
|
+
#
|
336
|
+
# @example
|
337
|
+
# img = MiniMagick::Image.open 'image.jpg'
|
338
|
+
# img.crop '20x30+10+5'
|
339
|
+
# img.colorspace 'Gray'
|
340
|
+
# pixels = img.get_pixels
|
341
|
+
#
|
342
|
+
# In this example, all pixels in pix should now have equal R, G, and B values.
|
343
|
+
#
|
344
|
+
# @return [Array] Matrix of each color of each pixel
|
345
|
+
def get_pixels
|
346
|
+
output = MiniMagick::Tool::Convert.new do |convert|
|
347
|
+
convert << path
|
348
|
+
convert.depth(8)
|
349
|
+
convert << "RGB:-"
|
350
|
+
end
|
351
|
+
|
352
|
+
pixels_array = output.unpack("C*")
|
353
|
+
pixels = pixels_array.each_slice(3).each_slice(width).to_a
|
354
|
+
|
355
|
+
# deallocate large intermediary objects
|
356
|
+
output.clear
|
357
|
+
pixels_array.clear
|
358
|
+
|
359
|
+
pixels
|
360
|
+
end
|
361
|
+
|
309
362
|
##
|
310
363
|
# This is used to change the format of the image. That is, from "tiff to
|
311
364
|
# jpg" or something like that. Once you run it, the instance is pointing to
|
@@ -327,29 +380,37 @@ module MiniMagick
|
|
327
380
|
# @param page [Integer] If this is an animated gif, say which 'page' you
|
328
381
|
# want with an integer. Default 0 will convert only the first page; 'nil'
|
329
382
|
# will convert all pages.
|
383
|
+
# @param read_opts [Hash] Any read options to be passed to ImageMagick
|
384
|
+
# for example: image.format('jpg', page, {density: '300'})
|
330
385
|
# @yield [MiniMagick::Tool::Convert] It optionally yields the command,
|
331
386
|
# if you want to add something.
|
332
387
|
# @return [self]
|
333
388
|
#
|
334
|
-
def format(format, page = 0)
|
389
|
+
def format(format, page = 0, read_opts={})
|
335
390
|
if @tempfile
|
336
391
|
new_tempfile = MiniMagick::Utilities.tempfile(".#{format}")
|
337
392
|
new_path = new_tempfile.path
|
338
393
|
else
|
339
|
-
new_path = path.
|
394
|
+
new_path = Pathname(path).sub_ext(".#{format}").to_s
|
340
395
|
end
|
341
396
|
|
397
|
+
input_path = path.dup
|
398
|
+
input_path << "[#{page}]" if page && !layer?
|
399
|
+
|
342
400
|
MiniMagick::Tool::Convert.new do |convert|
|
343
|
-
|
401
|
+
read_opts.each do |opt, val|
|
402
|
+
convert.send(opt.to_s, val)
|
403
|
+
end
|
404
|
+
convert << input_path
|
344
405
|
yield convert if block_given?
|
345
406
|
convert << new_path
|
346
407
|
end
|
347
408
|
|
348
409
|
if @tempfile
|
349
|
-
|
410
|
+
destroy!
|
350
411
|
@tempfile = new_tempfile
|
351
412
|
else
|
352
|
-
File.delete(path) unless path == new_path
|
413
|
+
File.delete(path) unless path == new_path || layer?
|
353
414
|
end
|
354
415
|
|
355
416
|
path.replace new_path
|
@@ -459,7 +520,10 @@ module MiniMagick
|
|
459
520
|
# Destroys the tempfile (created by {.open}) if it exists.
|
460
521
|
#
|
461
522
|
def destroy!
|
462
|
-
|
523
|
+
if @tempfile
|
524
|
+
FileUtils.rm_f @tempfile.path.sub(/mpc$/, "cache") if @tempfile.path.end_with?(".mpc")
|
525
|
+
@tempfile.unlink
|
526
|
+
end
|
463
527
|
end
|
464
528
|
|
465
529
|
##
|
@@ -491,13 +555,7 @@ module MiniMagick
|
|
491
555
|
end
|
492
556
|
|
493
557
|
def mogrify(page = nil)
|
494
|
-
MiniMagick::Tool::
|
495
|
-
builder.instance_eval do
|
496
|
-
def format(*args)
|
497
|
-
fail NoMethodError,
|
498
|
-
"you must call #format on a MiniMagick::Image directly"
|
499
|
-
end
|
500
|
-
end
|
558
|
+
MiniMagick::Tool::MogrifyRestricted.new do |builder|
|
501
559
|
yield builder if block_given?
|
502
560
|
builder << (page ? "#{path}[#{page}]" : path)
|
503
561
|
end
|
@@ -510,6 +568,5 @@ module MiniMagick
|
|
510
568
|
def layer?
|
511
569
|
path =~ /\[\d+\]$/
|
512
570
|
end
|
513
|
-
|
514
571
|
end
|
515
572
|
end
|
data/lib/mini_magick/shell.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
require "mini_magick/logger"
|
2
1
|
require "timeout"
|
2
|
+
require "benchmark"
|
3
3
|
|
4
4
|
module MiniMagick
|
5
5
|
##
|
@@ -11,26 +11,21 @@ module MiniMagick
|
|
11
11
|
class Shell
|
12
12
|
|
13
13
|
def run(command, options = {})
|
14
|
-
stdout, stderr,
|
14
|
+
stdout, stderr, status = execute(command, stdin: options[:stdin])
|
15
15
|
|
16
|
-
|
17
|
-
when 1
|
16
|
+
if status != 0 && options.fetch(:whiny, MiniMagick.whiny)
|
18
17
|
fail MiniMagick::Error, "`#{command.join(" ")}` failed with error:\n#{stderr}"
|
19
|
-
|
20
|
-
fail MiniMagick::Error, stderr
|
21
|
-
end if options.fetch(:whiny, true)
|
18
|
+
end
|
22
19
|
|
23
20
|
$stderr.print(stderr) unless options[:stderr] == false
|
24
21
|
|
25
|
-
stdout
|
22
|
+
[stdout, stderr, status]
|
26
23
|
end
|
27
24
|
|
28
|
-
def execute(command)
|
25
|
+
def execute(command, options = {})
|
29
26
|
stdout, stderr, status =
|
30
|
-
|
31
|
-
|
32
|
-
send("execute_#{MiniMagick.shell_api.gsub("-", "_")}", *command)
|
33
|
-
end
|
27
|
+
log(command.join(" ")) do
|
28
|
+
send("execute_#{MiniMagick.shell_api.gsub("-", "_")}", command, options)
|
34
29
|
end
|
35
30
|
|
36
31
|
[stdout, stderr, status.exitstatus]
|
@@ -38,17 +33,50 @@ module MiniMagick
|
|
38
33
|
["", "executable not found: \"#{command.first}\"", 127]
|
39
34
|
end
|
40
35
|
|
41
|
-
|
36
|
+
private
|
37
|
+
|
38
|
+
def execute_open3(command, options = {})
|
42
39
|
require "open3"
|
43
|
-
|
40
|
+
|
41
|
+
in_w, out_r, err_r, subprocess_thread = Open3.popen3(*command)
|
42
|
+
|
43
|
+
capture_command(in_w, out_r, err_r, subprocess_thread, options)
|
44
44
|
end
|
45
45
|
|
46
|
-
def execute_posix_spawn(
|
46
|
+
def execute_posix_spawn(command, options = {})
|
47
47
|
require "posix-spawn"
|
48
|
-
pid, stdin, stdout, stderr = POSIX::Spawn.popen4(*command)
|
49
|
-
Process.waitpid(pid)
|
50
48
|
|
51
|
-
|
49
|
+
pid, in_w, out_r, err_r = POSIX::Spawn.popen4(*command)
|
50
|
+
subprocess_thread = Process.detach(pid)
|
51
|
+
|
52
|
+
capture_command(in_w, out_r, err_r, subprocess_thread, options)
|
53
|
+
end
|
54
|
+
|
55
|
+
def capture_command(in_w, out_r, err_r, subprocess_thread, options)
|
56
|
+
[in_w, out_r, err_r].each(&:binmode)
|
57
|
+
stdout_reader = Thread.new { out_r.read }
|
58
|
+
stderr_reader = Thread.new { err_r.read }
|
59
|
+
begin
|
60
|
+
in_w.write options[:stdin].to_s
|
61
|
+
rescue Errno::EPIPE
|
62
|
+
end
|
63
|
+
in_w.close
|
64
|
+
|
65
|
+
Timeout.timeout(MiniMagick.timeout) { subprocess_thread.join }
|
66
|
+
|
67
|
+
[stdout_reader.value, stderr_reader.value, subprocess_thread.value]
|
68
|
+
rescue Timeout::Error => error
|
69
|
+
Process.kill("TERM", subprocess_thread.pid)
|
70
|
+
raise error
|
71
|
+
ensure
|
72
|
+
[out_r, err_r].each(&:close)
|
73
|
+
end
|
74
|
+
|
75
|
+
def log(command, &block)
|
76
|
+
value = nil
|
77
|
+
duration = Benchmark.realtime { value = block.call }
|
78
|
+
MiniMagick.logger.debug "[%.2fs] %s" % [duration, command]
|
79
|
+
value
|
52
80
|
end
|
53
81
|
|
54
82
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require "mini_magick/tool/mogrify"
|
2
|
+
|
3
|
+
module MiniMagick
|
4
|
+
class Tool
|
5
|
+
##
|
6
|
+
# @see http://www.imagemagick.org/script/mogrify.php
|
7
|
+
#
|
8
|
+
class MogrifyRestricted < Mogrify
|
9
|
+
def format(*args)
|
10
|
+
fail NoMethodError,
|
11
|
+
"you must call #format on a MiniMagick::Image directly"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/mini_magick/tool.rb
CHANGED
@@ -49,13 +49,15 @@ module MiniMagick
|
|
49
49
|
# @param whiny [Boolean] Whether to raise errors on exit codes different
|
50
50
|
# than 0.
|
51
51
|
# @example
|
52
|
-
# MiniMagick::Tool::Identify.new(false) do |identify|
|
52
|
+
# MiniMagick::Tool::Identify.new(whiny: false) do |identify|
|
53
53
|
# identify.help # returns exit status 1, which would otherwise throw an error
|
54
54
|
# end
|
55
|
-
def initialize(name,
|
55
|
+
def initialize(name, options = {})
|
56
|
+
warn "MiniMagick::Tool.new(false) is deprecated and will be removed in MiniMagick 5, use MiniMagick::Tool.new(whiny: false) instead." if !options.is_a?(Hash)
|
57
|
+
|
56
58
|
@name = name
|
57
|
-
@whiny = whiny
|
58
59
|
@args = []
|
60
|
+
@whiny = options.is_a?(Hash) ? options.fetch(:whiny, MiniMagick.whiny) : options
|
59
61
|
end
|
60
62
|
|
61
63
|
##
|
@@ -67,16 +69,30 @@ module MiniMagick
|
|
67
69
|
# mogrify << "path/to/image.jpg"
|
68
70
|
# mogrify.call # executes `mogrify -resize 500x500 path/to/image.jpg`
|
69
71
|
#
|
70
|
-
# @
|
71
|
-
#
|
72
|
-
#
|
73
|
-
#
|
72
|
+
# @example
|
73
|
+
# mogrify = MiniMagick::Tool::Mogrify.new
|
74
|
+
# # build the command
|
75
|
+
# mogrify.call do |stdout, stderr, status|
|
76
|
+
# # ...
|
77
|
+
# end
|
74
78
|
#
|
75
|
-
# @
|
79
|
+
# @yield [Array] Optionally yields stdout, stderr, and exit status
|
76
80
|
#
|
77
|
-
|
81
|
+
# @return [String] Returns the output of the command
|
82
|
+
#
|
83
|
+
def call(*args)
|
84
|
+
options = args[-1].is_a?(Hash) ? args.pop : {}
|
85
|
+
warn "Passing whiny to MiniMagick::Tool#call is deprecated and will be removed in MiniMagick 5, use MiniMagick::Tool.new(whiny: false) instead." if args.any?
|
86
|
+
whiny = args.fetch(0, @whiny)
|
87
|
+
|
88
|
+
options[:whiny] = whiny
|
89
|
+
options[:stderr] = false if block_given?
|
90
|
+
|
78
91
|
shell = MiniMagick::Shell.new
|
79
|
-
shell.run(command, options
|
92
|
+
stdout, stderr, status = shell.run(command, options)
|
93
|
+
yield stdout, stderr, status if block_given?
|
94
|
+
|
95
|
+
stdout.strip
|
80
96
|
end
|
81
97
|
|
82
98
|
##
|
@@ -171,6 +187,34 @@ module MiniMagick
|
|
171
187
|
self << ")"
|
172
188
|
end
|
173
189
|
|
190
|
+
##
|
191
|
+
# Adds ImageMagick's pseudo-filename `-` for standard input.
|
192
|
+
#
|
193
|
+
# @example
|
194
|
+
# identify = MiniMagick::Tool::Identify.new
|
195
|
+
# identify.stdin
|
196
|
+
# identify.call(stdin: image_content)
|
197
|
+
# # executes `identify -` with the given standard input
|
198
|
+
#
|
199
|
+
def stdin
|
200
|
+
self << "-"
|
201
|
+
end
|
202
|
+
|
203
|
+
##
|
204
|
+
# Adds ImageMagick's pseudo-filename `-` for standard output.
|
205
|
+
#
|
206
|
+
# @example
|
207
|
+
# content = MiniMagick::Tool::Convert.new do |convert|
|
208
|
+
# convert << "input.jpg"
|
209
|
+
# convert.auto_orient
|
210
|
+
# convert.stdout
|
211
|
+
# end
|
212
|
+
# # executes `convert input.jpg -auto-orient -` which returns file contents
|
213
|
+
#
|
214
|
+
def stdout
|
215
|
+
self << "-"
|
216
|
+
end
|
217
|
+
|
174
218
|
##
|
175
219
|
# Define creator operator methods
|
176
220
|
#
|
@@ -185,6 +229,16 @@ module MiniMagick
|
|
185
229
|
end
|
186
230
|
end
|
187
231
|
|
232
|
+
##
|
233
|
+
# This option is a valid ImageMagick option, but it's also a Ruby method,
|
234
|
+
# so we need to override it so that it correctly acts as an option method.
|
235
|
+
#
|
236
|
+
def clone(*args)
|
237
|
+
self << '-clone'
|
238
|
+
self.merge!(args)
|
239
|
+
self
|
240
|
+
end
|
241
|
+
|
188
242
|
##
|
189
243
|
# Any undefined method will be transformed into a CLI option
|
190
244
|
#
|
@@ -206,9 +260,9 @@ module MiniMagick
|
|
206
260
|
|
207
261
|
def self.option_methods
|
208
262
|
@option_methods ||= (
|
209
|
-
tool = new
|
263
|
+
tool = new(whiny: false)
|
210
264
|
tool << "-help"
|
211
|
-
help_page = tool.call(
|
265
|
+
help_page = tool.call(stderr: false)
|
212
266
|
|
213
267
|
cli_options = help_page.scan(/^\s+-[a-z\-]+/).map(&:strip)
|
214
268
|
if tool.name == "mogrify" && MiniMagick.graphicsmagick?
|
@@ -232,5 +286,6 @@ require "mini_magick/tool/display"
|
|
232
286
|
require "mini_magick/tool/identify"
|
233
287
|
require "mini_magick/tool/import"
|
234
288
|
require "mini_magick/tool/mogrify"
|
289
|
+
require "mini_magick/tool/mogrify_restricted"
|
235
290
|
require "mini_magick/tool/montage"
|
236
291
|
require "mini_magick/tool/stream"
|
@@ -14,7 +14,7 @@ module MiniMagick
|
|
14
14
|
#
|
15
15
|
def which(cmd)
|
16
16
|
exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
|
17
|
-
ENV
|
17
|
+
ENV.fetch('PATH').split(File::PATH_SEPARATOR).each do |path|
|
18
18
|
exts.each do |ext|
|
19
19
|
exe = File.join(path, "#{cmd}#{ext}")
|
20
20
|
return exe if File.executable? exe
|
data/lib/mini_magick/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mini_magick
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.7.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Corey Johnson
|
@@ -13,7 +13,7 @@ authors:
|
|
13
13
|
autorequire:
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
|
-
date:
|
16
|
+
date: 2017-06-20 00:00:00.000000000 Z
|
17
17
|
dependencies:
|
18
18
|
- !ruby/object:Gem::Dependency
|
19
19
|
name: rake
|
@@ -35,14 +35,42 @@ dependencies:
|
|
35
35
|
requirements:
|
36
36
|
- - "~>"
|
37
37
|
- !ruby/object:Gem::Version
|
38
|
-
version: 3.
|
38
|
+
version: 3.5.0
|
39
39
|
type: :development
|
40
40
|
prerelease: false
|
41
41
|
version_requirements: !ruby/object:Gem::Requirement
|
42
42
|
requirements:
|
43
43
|
- - "~>"
|
44
44
|
- !ruby/object:Gem::Version
|
45
|
-
version: 3.
|
45
|
+
version: 3.5.0
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: guard
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '0'
|
53
|
+
type: :development
|
54
|
+
prerelease: false
|
55
|
+
version_requirements: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: '0'
|
60
|
+
- !ruby/object:Gem::Dependency
|
61
|
+
name: guard-rspec
|
62
|
+
requirement: !ruby/object:Gem::Requirement
|
63
|
+
requirements:
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: '0'
|
67
|
+
type: :development
|
68
|
+
prerelease: false
|
69
|
+
version_requirements: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '0'
|
46
74
|
- !ruby/object:Gem::Dependency
|
47
75
|
name: posix-spawn
|
48
76
|
requirement: !ruby/object:Gem::Requirement
|
@@ -57,6 +85,20 @@ dependencies:
|
|
57
85
|
- - ">="
|
58
86
|
- !ruby/object:Gem::Version
|
59
87
|
version: '0'
|
88
|
+
- !ruby/object:Gem::Dependency
|
89
|
+
name: webmock
|
90
|
+
requirement: !ruby/object:Gem::Requirement
|
91
|
+
requirements:
|
92
|
+
- - ">="
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: '0'
|
95
|
+
type: :development
|
96
|
+
prerelease: false
|
97
|
+
version_requirements: !ruby/object:Gem::Requirement
|
98
|
+
requirements:
|
99
|
+
- - ">="
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
60
102
|
description: Manipulate images with minimal use of memory via ImageMagick / GraphicsMagick
|
61
103
|
email:
|
62
104
|
- probablycorey@gmail.com
|
@@ -76,7 +118,6 @@ files:
|
|
76
118
|
- lib/mini_magick/configuration.rb
|
77
119
|
- lib/mini_magick/image.rb
|
78
120
|
- lib/mini_magick/image/info.rb
|
79
|
-
- lib/mini_magick/logger.rb
|
80
121
|
- lib/mini_magick/shell.rb
|
81
122
|
- lib/mini_magick/tool.rb
|
82
123
|
- lib/mini_magick/tool/animate.rb
|
@@ -88,6 +129,7 @@ files:
|
|
88
129
|
- lib/mini_magick/tool/identify.rb
|
89
130
|
- lib/mini_magick/tool/import.rb
|
90
131
|
- lib/mini_magick/tool/mogrify.rb
|
132
|
+
- lib/mini_magick/tool/mogrify_restricted.rb
|
91
133
|
- lib/mini_magick/tool/montage.rb
|
92
134
|
- lib/mini_magick/tool/stream.rb
|
93
135
|
- lib/mini_magick/utilities.rb
|
@@ -113,9 +155,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
113
155
|
requirements:
|
114
156
|
- You must have ImageMagick or GraphicsMagick installed
|
115
157
|
rubyforge_project:
|
116
|
-
rubygems_version: 2.
|
158
|
+
rubygems_version: 2.6.11
|
117
159
|
signing_key:
|
118
160
|
specification_version: 4
|
119
161
|
summary: Manipulate images with minimal use of memory via ImageMagick / GraphicsMagick
|
120
162
|
test_files: []
|
121
|
-
has_rdoc:
|
data/lib/mini_magick/logger.rb
DELETED
@@ -1,38 +0,0 @@
|
|
1
|
-
require "benchmark"
|
2
|
-
|
3
|
-
module MiniMagick
|
4
|
-
##
|
5
|
-
# Responsible for logging commands to stdout (activated when
|
6
|
-
# `MiniMagick.debug` is set to `true`). Implements a simplified Logger
|
7
|
-
# interface.
|
8
|
-
#
|
9
|
-
# @private
|
10
|
-
#
|
11
|
-
class Logger
|
12
|
-
|
13
|
-
attr_accessor :format
|
14
|
-
|
15
|
-
def initialize(io)
|
16
|
-
@io = io
|
17
|
-
@format = "[%<duration>.2fs] %<command>s"
|
18
|
-
end
|
19
|
-
|
20
|
-
def debug(command, &action)
|
21
|
-
benchmark(action) do |duration|
|
22
|
-
output(duration: duration, command: command) if MiniMagick.debug
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
def output(data)
|
27
|
-
printf @io, "#{format}\n", data
|
28
|
-
end
|
29
|
-
|
30
|
-
def benchmark(action)
|
31
|
-
return_value = nil
|
32
|
-
duration = Benchmark.realtime { return_value = action.call }
|
33
|
-
yield duration
|
34
|
-
return_value
|
35
|
-
end
|
36
|
-
|
37
|
-
end
|
38
|
-
end
|