mini_magick 4.9.5 → 5.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/README.md +540 -0
- data/lib/mini_magick/configuration.rb +13 -140
- data/lib/mini_magick/image/info.rb +18 -59
- data/lib/mini_magick/image.rb +88 -71
- data/lib/mini_magick/shell.rb +15 -47
- data/lib/mini_magick/tool.rb +52 -75
- data/lib/mini_magick/utilities.rb +4 -6
- data/lib/mini_magick/version.rb +3 -3
- data/lib/mini_magick.rb +17 -42
- metadata +13 -67
- data/lib/mini_gmagick.rb +0 -3
- data/lib/mini_magick/tool/animate.rb +0 -14
- data/lib/mini_magick/tool/compare.rb +0 -14
- data/lib/mini_magick/tool/composite.rb +0 -14
- data/lib/mini_magick/tool/conjure.rb +0 -14
- data/lib/mini_magick/tool/convert.rb +0 -14
- data/lib/mini_magick/tool/display.rb +0 -14
- data/lib/mini_magick/tool/identify.rb +0 -14
- data/lib/mini_magick/tool/import.rb +0 -14
- data/lib/mini_magick/tool/magick.rb +0 -14
- data/lib/mini_magick/tool/mogrify.rb +0 -14
- data/lib/mini_magick/tool/mogrify_restricted.rb +0 -15
- data/lib/mini_magick/tool/montage.rb +0 -14
- data/lib/mini_magick/tool/stream.rb +0 -14
|
@@ -4,22 +4,6 @@ require 'logger'
|
|
|
4
4
|
module MiniMagick
|
|
5
5
|
module Configuration
|
|
6
6
|
|
|
7
|
-
##
|
|
8
|
-
# Set whether you want to use [ImageMagick](http://www.imagemagick.org) or
|
|
9
|
-
# [GraphicsMagick](http://www.graphicsmagick.org).
|
|
10
|
-
#
|
|
11
|
-
# @return [Symbol] `:imagemagick`, `:imagemagick7`, or `:graphicsmagick`
|
|
12
|
-
#
|
|
13
|
-
attr_accessor :cli
|
|
14
|
-
|
|
15
|
-
##
|
|
16
|
-
# If you don't have the CLI tools in your PATH, you can set the path to the
|
|
17
|
-
# executables.
|
|
18
|
-
#
|
|
19
|
-
attr_writer :cli_path
|
|
20
|
-
# @private (for backwards compatibility)
|
|
21
|
-
attr_accessor :processor_path
|
|
22
|
-
|
|
23
7
|
##
|
|
24
8
|
# Adds a prefix to the CLI command.
|
|
25
9
|
# For example, you could use `firejail` to run all commands in a sandbox.
|
|
@@ -39,38 +23,19 @@ module MiniMagick
|
|
|
39
23
|
#
|
|
40
24
|
attr_accessor :timeout
|
|
41
25
|
##
|
|
42
|
-
#
|
|
43
|
-
#
|
|
44
|
-
#
|
|
45
|
-
# @return [Boolean]
|
|
46
|
-
#
|
|
47
|
-
attr_reader :debug
|
|
48
|
-
##
|
|
49
|
-
# Logger for {#debug}, default is `MiniMagick::Logger.new(STDOUT)`, but
|
|
50
|
-
# you can override it, for example if you want the logs to be written to
|
|
51
|
-
# a file.
|
|
26
|
+
# Logger for commands, default is `Logger.new($stdout)`, but you can
|
|
27
|
+
# override it, for example if you want the logs to be written to a file.
|
|
52
28
|
#
|
|
53
29
|
# @return [Logger]
|
|
54
30
|
#
|
|
55
31
|
attr_accessor :logger
|
|
56
|
-
|
|
57
|
-
##
|
|
58
|
-
# If set to `true`, it will `identify` every newly created image, and raise
|
|
59
|
-
# `MiniMagick::Invalid` if the image is not valid. Useful for validating
|
|
60
|
-
# user input, although it adds a bit of overhead. Defaults to `true`.
|
|
61
|
-
#
|
|
62
|
-
# @return [Boolean]
|
|
63
|
-
#
|
|
64
|
-
attr_accessor :validate_on_create
|
|
65
32
|
##
|
|
66
|
-
#
|
|
67
|
-
#
|
|
68
|
-
# is not valid. Useful for validating that processing was sucessful,
|
|
69
|
-
# although it adds a bit of overhead. Defaults to `true`.
|
|
33
|
+
# Temporary directory used by MiniMagick, default is `Dir.tmpdir`, but
|
|
34
|
+
# you can override it.
|
|
70
35
|
#
|
|
71
|
-
# @return [
|
|
36
|
+
# @return [String]
|
|
72
37
|
#
|
|
73
|
-
attr_accessor :
|
|
38
|
+
attr_accessor :tmpdir
|
|
74
39
|
|
|
75
40
|
##
|
|
76
41
|
# If set to `false`, it will not raise errors when ImageMagick returns
|
|
@@ -78,121 +43,29 @@ module MiniMagick
|
|
|
78
43
|
#
|
|
79
44
|
# @return [Boolean]
|
|
80
45
|
#
|
|
81
|
-
attr_accessor :
|
|
46
|
+
attr_accessor :errors
|
|
82
47
|
|
|
83
48
|
##
|
|
84
|
-
#
|
|
85
|
-
#
|
|
86
|
-
|
|
87
|
-
#
|
|
88
|
-
# @return [String]
|
|
89
|
-
#
|
|
90
|
-
attr_accessor :shell_api
|
|
49
|
+
# If set to `false`, it will not forward warnings from ImageMagick to
|
|
50
|
+
# standard error.
|
|
51
|
+
attr_accessor :warnings
|
|
91
52
|
|
|
92
53
|
def self.extended(base)
|
|
93
|
-
base.
|
|
94
|
-
base.
|
|
95
|
-
base.whiny = true
|
|
96
|
-
base.shell_api = "open3"
|
|
54
|
+
base.tmpdir = Dir.tmpdir
|
|
55
|
+
base.errors = true
|
|
97
56
|
base.logger = Logger.new($stdout).tap { |l| l.level = Logger::INFO }
|
|
57
|
+
base.warnings = true
|
|
98
58
|
end
|
|
99
59
|
|
|
100
60
|
##
|
|
101
61
|
# @yield [self]
|
|
102
62
|
# @example
|
|
103
63
|
# MiniMagick.configure do |config|
|
|
104
|
-
# config.cli = :graphicsmagick
|
|
105
64
|
# config.timeout = 5
|
|
106
65
|
# end
|
|
107
66
|
#
|
|
108
67
|
def configure
|
|
109
68
|
yield self
|
|
110
69
|
end
|
|
111
|
-
|
|
112
|
-
CLI_DETECTION = {
|
|
113
|
-
imagemagick: "mogrify",
|
|
114
|
-
graphicsmagick: "gm",
|
|
115
|
-
imagemagick7: "magick",
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
# @private (for backwards compatibility)
|
|
119
|
-
def processor
|
|
120
|
-
@processor ||= CLI_DETECTION.values.detect do |processor|
|
|
121
|
-
MiniMagick::Utilities.which(processor)
|
|
122
|
-
end
|
|
123
|
-
end
|
|
124
|
-
|
|
125
|
-
# @private (for backwards compatibility)
|
|
126
|
-
def processor=(processor)
|
|
127
|
-
@processor = processor.to_s
|
|
128
|
-
|
|
129
|
-
unless CLI_DETECTION.value?(@processor)
|
|
130
|
-
raise ArgumentError,
|
|
131
|
-
"processor has to be set to either \"magick\", \"mogrify\" or \"gm\"" \
|
|
132
|
-
", was set to #{@processor.inspect}"
|
|
133
|
-
end
|
|
134
|
-
end
|
|
135
|
-
|
|
136
|
-
##
|
|
137
|
-
# Get [ImageMagick](http://www.imagemagick.org) or
|
|
138
|
-
# [GraphicsMagick](http://www.graphicsmagick.org).
|
|
139
|
-
#
|
|
140
|
-
# @return [Symbol] `:imagemagick` or `:graphicsmagick`
|
|
141
|
-
#
|
|
142
|
-
def cli
|
|
143
|
-
if instance_variable_defined?("@cli")
|
|
144
|
-
instance_variable_get("@cli")
|
|
145
|
-
else
|
|
146
|
-
cli = CLI_DETECTION.key(processor) or
|
|
147
|
-
fail MiniMagick::Error, "You must have ImageMagick or GraphicsMagick installed"
|
|
148
|
-
|
|
149
|
-
instance_variable_set("@cli", cli)
|
|
150
|
-
end
|
|
151
|
-
end
|
|
152
|
-
|
|
153
|
-
##
|
|
154
|
-
# Set whether you want to use [ImageMagick](http://www.imagemagick.org) or
|
|
155
|
-
# [GraphicsMagick](http://www.graphicsmagick.org).
|
|
156
|
-
#
|
|
157
|
-
def cli=(value)
|
|
158
|
-
@cli = value
|
|
159
|
-
|
|
160
|
-
if not CLI_DETECTION.key?(@cli)
|
|
161
|
-
raise ArgumentError,
|
|
162
|
-
"CLI has to be set to either :imagemagick, :imagemagick7 or :graphicsmagick" \
|
|
163
|
-
", was set to #{@cli.inspect}"
|
|
164
|
-
end
|
|
165
|
-
end
|
|
166
|
-
|
|
167
|
-
##
|
|
168
|
-
# If you set the path of CLI tools, you can get the path of the
|
|
169
|
-
# executables.
|
|
170
|
-
#
|
|
171
|
-
# @return [String]
|
|
172
|
-
#
|
|
173
|
-
def cli_path
|
|
174
|
-
if instance_variable_defined?("@cli_path")
|
|
175
|
-
instance_variable_get("@cli_path")
|
|
176
|
-
else
|
|
177
|
-
processor_path = instance_variable_get("@processor_path") if instance_variable_defined?("@processor_path")
|
|
178
|
-
|
|
179
|
-
instance_variable_set("@cli_path", processor_path)
|
|
180
|
-
end
|
|
181
|
-
end
|
|
182
|
-
|
|
183
|
-
##
|
|
184
|
-
# When set to `true`, it outputs each command to STDOUT in their shell
|
|
185
|
-
# version.
|
|
186
|
-
#
|
|
187
|
-
def debug=(value)
|
|
188
|
-
warn "MiniMagick.debug is deprecated and will be removed in MiniMagick 5. Use `MiniMagick.logger.level = Logger::DEBUG` instead."
|
|
189
|
-
logger.level = value ? Logger::DEBUG : Logger::INFO
|
|
190
|
-
end
|
|
191
|
-
|
|
192
|
-
# Backwards compatibility
|
|
193
|
-
def reload_tools
|
|
194
|
-
warn "MiniMagick.reload_tools is deprecated because it is no longer necessary"
|
|
195
|
-
end
|
|
196
|
-
|
|
197
70
|
end
|
|
198
71
|
end
|
|
@@ -17,8 +17,6 @@ module MiniMagick
|
|
|
17
17
|
cheap_info(value)
|
|
18
18
|
when "colorspace"
|
|
19
19
|
colorspace
|
|
20
|
-
when "mime_type"
|
|
21
|
-
mime_type
|
|
22
20
|
when "resolution"
|
|
23
21
|
resolution(*args)
|
|
24
22
|
when "signature"
|
|
@@ -27,8 +25,6 @@ module MiniMagick
|
|
|
27
25
|
raw_exif(value)
|
|
28
26
|
when "exif"
|
|
29
27
|
exif
|
|
30
|
-
when "details"
|
|
31
|
-
details
|
|
32
28
|
when "data"
|
|
33
29
|
data
|
|
34
30
|
else
|
|
@@ -42,7 +38,7 @@ module MiniMagick
|
|
|
42
38
|
|
|
43
39
|
def cheap_info(value)
|
|
44
40
|
@info.fetch(value) do
|
|
45
|
-
format, width, height, size = self["%m %w %h %b"].split(" ")
|
|
41
|
+
format, width, height, size = parse_warnings(self["%m %w %h %b"]).split(" ")
|
|
46
42
|
|
|
47
43
|
path = @path
|
|
48
44
|
path = path.match(/\[\d+\]$/).pre_match if path =~ /\[\d+\]$/
|
|
@@ -62,12 +58,18 @@ module MiniMagick
|
|
|
62
58
|
raise MiniMagick::Invalid, "image data can't be read"
|
|
63
59
|
end
|
|
64
60
|
|
|
65
|
-
def
|
|
66
|
-
|
|
61
|
+
def parse_warnings(raw_info)
|
|
62
|
+
return raw_info unless raw_info.split("\n").size > 1
|
|
63
|
+
|
|
64
|
+
raw_info.split("\n").each do |line|
|
|
65
|
+
# must match "%m %w %h %b"
|
|
66
|
+
return line if line.match?(/^[A-Z]+ \d+ \d+ \d+(|\.\d+)([KMGTPEZY]{0,1})B$/)
|
|
67
|
+
end
|
|
68
|
+
raise TypeError
|
|
67
69
|
end
|
|
68
70
|
|
|
69
|
-
def
|
|
70
|
-
"
|
|
71
|
+
def colorspace
|
|
72
|
+
@info["colorspace"] ||= self["%r"]
|
|
71
73
|
end
|
|
72
74
|
|
|
73
75
|
def resolution(unit = nil)
|
|
@@ -90,20 +92,12 @@ module MiniMagick
|
|
|
90
92
|
output.each_line do |line|
|
|
91
93
|
line = line.chomp("\n")
|
|
92
94
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
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
|
-
next if line == "unknown"
|
|
104
|
-
key, value = line.split("=", 2)
|
|
105
|
-
value.gsub!("\\012", "\n") # convert "\012" characters to newlines
|
|
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)
|
|
106
98
|
hash[key] = value
|
|
99
|
+
else
|
|
100
|
+
hash[hash.keys.last] << "\n#{line}"
|
|
107
101
|
end
|
|
108
102
|
end
|
|
109
103
|
|
|
@@ -119,44 +113,9 @@ module MiniMagick
|
|
|
119
113
|
@info["signature"] ||= self["%#"]
|
|
120
114
|
end
|
|
121
115
|
|
|
122
|
-
def details
|
|
123
|
-
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? || MiniMagick.imagemagick7?
|
|
124
|
-
|
|
125
|
-
@info["details"] ||= (
|
|
126
|
-
details_string = identify(&:verbose)
|
|
127
|
-
key_stack = []
|
|
128
|
-
details_string.lines.to_a[1..-1].each_with_object({}) do |line, details_hash|
|
|
129
|
-
next if !line.valid_encoding? || line.strip.length.zero?
|
|
130
|
-
|
|
131
|
-
level = line[/^\s*/].length / 2 - 1
|
|
132
|
-
if level >= 0
|
|
133
|
-
key_stack.pop until key_stack.size <= level
|
|
134
|
-
else
|
|
135
|
-
# Some metadata, such as SVG clipping paths, will be saved without
|
|
136
|
-
# indentation, resulting in a level of -1
|
|
137
|
-
last_key = details_hash.keys.last
|
|
138
|
-
details_hash[last_key] = '' if details_hash[last_key].empty?
|
|
139
|
-
details_hash[last_key] << line
|
|
140
|
-
next
|
|
141
|
-
end
|
|
142
|
-
|
|
143
|
-
key, _, value = line.partition(/:[\s]/).map(&:strip)
|
|
144
|
-
hash = key_stack.inject(details_hash) { |_hash, _key| _hash.fetch(_key) }
|
|
145
|
-
if value.empty?
|
|
146
|
-
hash[key] = {}
|
|
147
|
-
key_stack.push key
|
|
148
|
-
else
|
|
149
|
-
hash[key] = value
|
|
150
|
-
end
|
|
151
|
-
end
|
|
152
|
-
)
|
|
153
|
-
end
|
|
154
|
-
|
|
155
116
|
def data
|
|
156
|
-
raise Error, "MiniMagick::Image#data isn't supported on GraphicsMagick. Use MiniMagick::Image#details instead." if MiniMagick.graphicsmagick?
|
|
157
|
-
|
|
158
117
|
@info["data"] ||= (
|
|
159
|
-
json = MiniMagick
|
|
118
|
+
json = MiniMagick.convert do |convert|
|
|
160
119
|
convert << path
|
|
161
120
|
convert << "json:"
|
|
162
121
|
end
|
|
@@ -168,7 +127,7 @@ module MiniMagick
|
|
|
168
127
|
end
|
|
169
128
|
|
|
170
129
|
def identify
|
|
171
|
-
MiniMagick
|
|
130
|
+
MiniMagick.identify do |builder|
|
|
172
131
|
yield builder if block_given?
|
|
173
132
|
builder << path
|
|
174
133
|
end
|
data/lib/mini_magick/image.rb
CHANGED
|
@@ -15,7 +15,7 @@ module MiniMagick
|
|
|
15
15
|
# methods.
|
|
16
16
|
#
|
|
17
17
|
# Use this to pass in a stream object. Must respond to #read(size) or be a
|
|
18
|
-
# binary string object (
|
|
18
|
+
# binary string object (BLOB)
|
|
19
19
|
#
|
|
20
20
|
# Probably easier to use the {.open} method if you want to open a file or a
|
|
21
21
|
# URL.
|
|
@@ -51,11 +51,11 @@ module MiniMagick
|
|
|
51
51
|
#
|
|
52
52
|
def self.import_pixels(blob, columns, rows, depth, map, format = 'png')
|
|
53
53
|
# Create an image object with the raw pixel data string:
|
|
54
|
-
|
|
54
|
+
read(blob, ".dat").tap do |image|
|
|
55
55
|
output_path = image.path.sub(/\.\w+$/, ".#{format}")
|
|
56
56
|
# Use ImageMagick to convert the raw data file to an image file of the
|
|
57
57
|
# desired format:
|
|
58
|
-
MiniMagick
|
|
58
|
+
MiniMagick.convert do |convert|
|
|
59
59
|
convert.size "#{columns}x#{rows}"
|
|
60
60
|
convert.depth depth
|
|
61
61
|
convert << "#{map}:#{image.path}"
|
|
@@ -79,30 +79,16 @@ module MiniMagick
|
|
|
79
79
|
# @param options [Hash] Specify options for the open method
|
|
80
80
|
# @return [MiniMagick::Image] The loaded image
|
|
81
81
|
#
|
|
82
|
-
def self.open(path_or_url, ext = nil, options
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
if path_or_url.respond_to?(:open)
|
|
88
|
-
path_or_url
|
|
89
|
-
elsif path_or_url.respond_to?(:to_str) &&
|
|
90
|
-
%r{\A[A-Za-z][A-Za-z0-9+\-\.]*://} =~ path_or_url &&
|
|
91
|
-
(uri = URI.parse(path_or_url)).respond_to?(:open)
|
|
92
|
-
uri
|
|
93
|
-
else
|
|
94
|
-
options = { binmode: true }.merge(options)
|
|
95
|
-
Pathname(path_or_url)
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
if openable.is_a?(URI::Generic)
|
|
99
|
-
ext ||= File.extname(openable.path)
|
|
82
|
+
def self.open(path_or_url, ext = nil, **options)
|
|
83
|
+
if path_or_url.to_s =~ %r{\A(https?|ftp)://}
|
|
84
|
+
uri = URI(path_or_url)
|
|
85
|
+
ext ||= File.extname(uri.path).sub(/:.*/, '') # handle URL including a colon
|
|
86
|
+
uri.open(options) { |file| read(file, ext) }
|
|
100
87
|
else
|
|
101
|
-
|
|
88
|
+
pathname = Pathname(path_or_url)
|
|
89
|
+
ext ||= File.extname(pathname.to_s)
|
|
90
|
+
pathname.open(binmode: true, **options) { |file| read(file, ext) }
|
|
102
91
|
end
|
|
103
|
-
ext.sub!(/:.*/, '') # hack for filenames or URLs that include a colon
|
|
104
|
-
|
|
105
|
-
openable.open(options) { |file| read(file, ext) }
|
|
106
92
|
end
|
|
107
93
|
|
|
108
94
|
##
|
|
@@ -114,18 +100,14 @@ module MiniMagick
|
|
|
114
100
|
# we have a good tempfile.
|
|
115
101
|
#
|
|
116
102
|
# @param ext [String] Specify the extension you want to read it as
|
|
117
|
-
# @param validate [Boolean] If false, skips validation of the created
|
|
118
|
-
# image. Defaults to true.
|
|
119
103
|
# @yield [Tempfile] You can #write bits to this object to create the new
|
|
120
104
|
# Image
|
|
121
105
|
# @return [MiniMagick::Image] The created image
|
|
122
106
|
#
|
|
123
|
-
def self.create(ext = nil,
|
|
107
|
+
def self.create(ext = nil, &block)
|
|
124
108
|
tempfile = MiniMagick::Utilities.tempfile(ext.to_s.downcase, &block)
|
|
125
109
|
|
|
126
|
-
new(tempfile.path, tempfile)
|
|
127
|
-
image.validate! if validate
|
|
128
|
-
end
|
|
110
|
+
new(tempfile.path, tempfile)
|
|
129
111
|
end
|
|
130
112
|
|
|
131
113
|
##
|
|
@@ -160,7 +142,7 @@ module MiniMagick
|
|
|
160
142
|
# which creates a temporary file for you and protects your original.
|
|
161
143
|
#
|
|
162
144
|
# @param input_path [String, Pathname] The location of an image file
|
|
163
|
-
# @yield [MiniMagick::Tool
|
|
145
|
+
# @yield [MiniMagick::Tool] If block is given, {#combine_options}
|
|
164
146
|
# is called.
|
|
165
147
|
#
|
|
166
148
|
def initialize(input_path, tempfile = nil, &block)
|
|
@@ -224,10 +206,6 @@ module MiniMagick
|
|
|
224
206
|
#
|
|
225
207
|
attribute :type, "format"
|
|
226
208
|
##
|
|
227
|
-
# @return [String]
|
|
228
|
-
#
|
|
229
|
-
attribute :mime_type
|
|
230
|
-
##
|
|
231
209
|
# @return [Integer]
|
|
232
210
|
#
|
|
233
211
|
attribute :width
|
|
@@ -270,7 +248,7 @@ module MiniMagick
|
|
|
270
248
|
#
|
|
271
249
|
attribute :resolution
|
|
272
250
|
##
|
|
273
|
-
# Returns the message digest of this image as a SHA-256,
|
|
251
|
+
# Returns the message digest of this image as a SHA-256, hexadecimal
|
|
274
252
|
# encoded string. This signature uniquely identifies the image and is
|
|
275
253
|
# convenient for determining if an image has been modified or whether two
|
|
276
254
|
# images are identical.
|
|
@@ -282,17 +260,10 @@ module MiniMagick
|
|
|
282
260
|
#
|
|
283
261
|
attribute :signature
|
|
284
262
|
##
|
|
285
|
-
# Returns the
|
|
286
|
-
# ImageMagick.
|
|
263
|
+
# Returns the result of converting the image to JSON format.
|
|
287
264
|
#
|
|
288
265
|
# @return [Hash]
|
|
289
266
|
attribute :data
|
|
290
|
-
##
|
|
291
|
-
# Returns the information from `identify -verbose` in a Hash format, for
|
|
292
|
-
# GraphicsMagick.
|
|
293
|
-
#
|
|
294
|
-
# @return [Hash]
|
|
295
|
-
attribute :details
|
|
296
267
|
|
|
297
268
|
##
|
|
298
269
|
# Use this method if you want to access raw Identify's format API.
|
|
@@ -336,13 +307,18 @@ module MiniMagick
|
|
|
336
307
|
#
|
|
337
308
|
# 1) one for each row of pixels
|
|
338
309
|
# 2) one for each column of pixels
|
|
339
|
-
# 3) three elements in the range 0-255, one for each of the RGB color channels
|
|
310
|
+
# 3) three or four elements in the range 0-255, one for each of the RGB(A) color channels
|
|
340
311
|
#
|
|
341
312
|
# @example
|
|
342
313
|
# img = MiniMagick::Image.open 'image.jpg'
|
|
343
314
|
# pixels = img.get_pixels
|
|
344
315
|
# pixels[3][2][1] # the green channel value from the 4th-row, 3rd-column pixel
|
|
345
316
|
#
|
|
317
|
+
# @example
|
|
318
|
+
# img = MiniMagick::Image.open 'image.jpg'
|
|
319
|
+
# pixels = img.get_pixels("RGBA")
|
|
320
|
+
# pixels[3][2][3] # the alpha channel value from the 4th-row, 3rd-column pixel
|
|
321
|
+
#
|
|
346
322
|
# It can also be called after applying transformations:
|
|
347
323
|
#
|
|
348
324
|
# @example
|
|
@@ -353,19 +329,22 @@ module MiniMagick
|
|
|
353
329
|
#
|
|
354
330
|
# In this example, all pixels in pix should now have equal R, G, and B values.
|
|
355
331
|
#
|
|
332
|
+
# @param map [String] A code for the mapping of the pixel data. Must be either
|
|
333
|
+
# 'RGB' or 'RGBA'. Default to 'RGB'
|
|
356
334
|
# @return [Array] Matrix of each color of each pixel
|
|
357
|
-
def get_pixels
|
|
358
|
-
|
|
335
|
+
def get_pixels(map="RGB")
|
|
336
|
+
raise ArgumentError, "Invalid map value" unless ["RGB", "RGBA"].include?(map)
|
|
337
|
+
convert = MiniMagick.convert
|
|
359
338
|
convert << path
|
|
360
339
|
convert.depth(8)
|
|
361
|
-
convert << "
|
|
340
|
+
convert << "#{map}:-"
|
|
362
341
|
|
|
363
342
|
# Do not use `convert.call` here. We need the whole binary (unstripped) output here.
|
|
364
343
|
shell = MiniMagick::Shell.new
|
|
365
344
|
output, * = shell.run(convert.command)
|
|
366
345
|
|
|
367
346
|
pixels_array = output.unpack("C*")
|
|
368
|
-
pixels = pixels_array.each_slice(
|
|
347
|
+
pixels = pixels_array.each_slice(map.length).each_slice(width).to_a
|
|
369
348
|
|
|
370
349
|
# deallocate large intermediary objects
|
|
371
350
|
output.clear
|
|
@@ -374,6 +353,23 @@ module MiniMagick
|
|
|
374
353
|
pixels
|
|
375
354
|
end
|
|
376
355
|
|
|
356
|
+
##
|
|
357
|
+
# This is used to create image from pixels. This might be required if you
|
|
358
|
+
# create pixels for some image processing reasons and you want to form
|
|
359
|
+
# image from those pixels.
|
|
360
|
+
#
|
|
361
|
+
# *DANGER*: This operation can be very expensive. Please try to use with
|
|
362
|
+
# caution.
|
|
363
|
+
#
|
|
364
|
+
# @example
|
|
365
|
+
# # It is given in readme.md file
|
|
366
|
+
##
|
|
367
|
+
def self.get_image_from_pixels(pixels, dimension, map, depth, format)
|
|
368
|
+
pixels = pixels.flatten
|
|
369
|
+
blob = pixels.pack('C*')
|
|
370
|
+
import_pixels(blob, *dimension, depth, map, format)
|
|
371
|
+
end
|
|
372
|
+
|
|
377
373
|
##
|
|
378
374
|
# This is used to change the format of the image. That is, from "tiff to
|
|
379
375
|
# jpg" or something like that. Once you run it, the instance is pointing to
|
|
@@ -397,7 +393,7 @@ module MiniMagick
|
|
|
397
393
|
# will convert all pages.
|
|
398
394
|
# @param read_opts [Hash] Any read options to be passed to ImageMagick
|
|
399
395
|
# for example: image.format('jpg', page, {density: '300'})
|
|
400
|
-
# @yield [MiniMagick::Tool
|
|
396
|
+
# @yield [MiniMagick::Tool] It optionally yields the command,
|
|
401
397
|
# if you want to add something.
|
|
402
398
|
# @return [self]
|
|
403
399
|
#
|
|
@@ -412,7 +408,7 @@ module MiniMagick
|
|
|
412
408
|
input_path = path.dup
|
|
413
409
|
input_path << "[#{page}]" if page && !layer?
|
|
414
410
|
|
|
415
|
-
MiniMagick
|
|
411
|
+
MiniMagick.convert do |convert|
|
|
416
412
|
read_opts.each do |opt, val|
|
|
417
413
|
convert.send(opt.to_s, val)
|
|
418
414
|
end
|
|
@@ -432,6 +428,9 @@ module MiniMagick
|
|
|
432
428
|
@info.clear
|
|
433
429
|
|
|
434
430
|
self
|
|
431
|
+
rescue MiniMagick::Invalid, MiniMagick::Error => e
|
|
432
|
+
new_tempfile.unlink if new_tempfile && @tempfile != new_tempfile
|
|
433
|
+
raise e
|
|
435
434
|
end
|
|
436
435
|
|
|
437
436
|
##
|
|
@@ -445,7 +444,7 @@ module MiniMagick
|
|
|
445
444
|
# c.background "blue"
|
|
446
445
|
# end
|
|
447
446
|
#
|
|
448
|
-
# @yield [MiniMagick::
|
|
447
|
+
# @yield [MiniMagick::Command]
|
|
449
448
|
# @see http://www.imagemagick.org/script/mogrify.php
|
|
450
449
|
# @return [self]
|
|
451
450
|
#
|
|
@@ -466,10 +465,6 @@ module MiniMagick
|
|
|
466
465
|
end
|
|
467
466
|
end
|
|
468
467
|
|
|
469
|
-
def respond_to_missing?(method_name, include_private = false)
|
|
470
|
-
MiniMagick::Tool::Mogrify.option_methods.include?(method_name.to_s)
|
|
471
|
-
end
|
|
472
|
-
|
|
473
468
|
##
|
|
474
469
|
# Writes the temporary file out to either a file location (by passing in a
|
|
475
470
|
# String) or by passing in a Stream that you can #write(chunk) to
|
|
@@ -482,7 +477,7 @@ module MiniMagick
|
|
|
482
477
|
case output_to
|
|
483
478
|
when String, Pathname
|
|
484
479
|
if layer?
|
|
485
|
-
MiniMagick
|
|
480
|
+
MiniMagick.convert do |builder|
|
|
486
481
|
builder << path
|
|
487
482
|
builder << output_to
|
|
488
483
|
end
|
|
@@ -492,6 +487,8 @@ module MiniMagick
|
|
|
492
487
|
else
|
|
493
488
|
IO.copy_stream File.open(path, "rb"), output_to
|
|
494
489
|
end
|
|
490
|
+
ensure
|
|
491
|
+
destroy! if tempfile
|
|
495
492
|
end
|
|
496
493
|
|
|
497
494
|
##
|
|
@@ -509,7 +506,7 @@ module MiniMagick
|
|
|
509
506
|
def composite(other_image, output_extension = type.downcase, mask = nil)
|
|
510
507
|
output_tempfile = MiniMagick::Utilities.tempfile(".#{output_extension}")
|
|
511
508
|
|
|
512
|
-
MiniMagick
|
|
509
|
+
MiniMagick.composite do |composite|
|
|
513
510
|
yield composite if block_given?
|
|
514
511
|
composite << other_image.path
|
|
515
512
|
composite << path
|
|
@@ -551,27 +548,21 @@ module MiniMagick
|
|
|
551
548
|
# b.verbose
|
|
552
549
|
# end # runs `identify -verbose image.jpg`
|
|
553
550
|
# @return [String] Output from `identify`
|
|
554
|
-
# @yield [MiniMagick::Tool
|
|
551
|
+
# @yield [MiniMagick::Tool]
|
|
555
552
|
#
|
|
556
553
|
def identify
|
|
557
|
-
MiniMagick
|
|
554
|
+
MiniMagick.identify do |builder|
|
|
558
555
|
yield builder if block_given?
|
|
559
556
|
builder << path
|
|
560
557
|
end
|
|
561
558
|
end
|
|
562
559
|
|
|
563
|
-
# @private
|
|
564
|
-
def run_command(tool_name, *args)
|
|
565
|
-
MiniMagick::Tool.const_get(tool_name.capitalize).new do |builder|
|
|
566
|
-
args.each do |arg|
|
|
567
|
-
builder << arg
|
|
568
|
-
end
|
|
569
|
-
end
|
|
570
|
-
end
|
|
571
|
-
|
|
572
560
|
def mogrify(page = nil)
|
|
573
|
-
MiniMagick
|
|
561
|
+
MiniMagick.mogrify do |builder|
|
|
574
562
|
yield builder if block_given?
|
|
563
|
+
if builder.args.include?("-format")
|
|
564
|
+
fail MiniMagick::Error, "you must call #format on a MiniMagick::Image directly"
|
|
565
|
+
end
|
|
575
566
|
builder << (page ? "#{path}[#{page}]" : path)
|
|
576
567
|
end
|
|
577
568
|
|
|
@@ -583,5 +574,31 @@ module MiniMagick
|
|
|
583
574
|
def layer?
|
|
584
575
|
path =~ /\[\d+\]$/
|
|
585
576
|
end
|
|
577
|
+
|
|
578
|
+
##
|
|
579
|
+
# Compares if image width
|
|
580
|
+
# is greater than height
|
|
581
|
+
# ============
|
|
582
|
+
# | |
|
|
583
|
+
# | |
|
|
584
|
+
# ============
|
|
585
|
+
# @return [Boolean]
|
|
586
|
+
def landscape?
|
|
587
|
+
width > height
|
|
588
|
+
end
|
|
589
|
+
|
|
590
|
+
##
|
|
591
|
+
# Compares if image height
|
|
592
|
+
# is greater than width
|
|
593
|
+
# ======
|
|
594
|
+
# | |
|
|
595
|
+
# | |
|
|
596
|
+
# | |
|
|
597
|
+
# | |
|
|
598
|
+
# ======
|
|
599
|
+
# @return [Boolean]
|
|
600
|
+
def portrait?
|
|
601
|
+
height > width
|
|
602
|
+
end
|
|
586
603
|
end
|
|
587
604
|
end
|