mini_magick 4.3.6 → 4.7.2
Sign up to get free protection for your applications and to get access to all the features.
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
|