mini_magick 4.10.1 → 5.2.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 +558 -0
- data/lib/mini_magick/configuration.rb +39 -136
- data/lib/mini_magick/image/info.rb +18 -59
- data/lib/mini_magick/image.rb +65 -73
- data/lib/mini_magick/shell.rb +19 -47
- data/lib/mini_magick/tool.rb +56 -79
- data/lib/mini_magick/utilities.rb +4 -6
- data/lib/mini_magick/version.rb +3 -3
- data/lib/mini_magick.rb +18 -42
- metadata +20 -64
- data/lib/mini_gmagick.rb +0 -3
- data/lib/mini_magick/immutable_image.rb +0 -18
- 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
@@ -5,20 +5,11 @@ module MiniMagick
|
|
5
5
|
module Configuration
|
6
6
|
|
7
7
|
##
|
8
|
-
#
|
9
|
-
#
|
8
|
+
# Uses [GraphicsMagick](http://www.graphicsmagick.org/) instead of
|
9
|
+
# ImageMagick, by prefixing commands with `gm` instead of `magick`.
|
10
10
|
#
|
11
|
-
# @return [
|
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
|
11
|
+
# @return [Boolean]
|
12
|
+
attr_accessor :graphicsmagick
|
22
13
|
|
23
14
|
##
|
24
15
|
# Adds a prefix to the CLI command.
|
@@ -32,45 +23,46 @@ module MiniMagick
|
|
32
23
|
attr_accessor :cli_prefix
|
33
24
|
|
34
25
|
##
|
35
|
-
#
|
36
|
-
#
|
26
|
+
# Adds environment variables to every CLI command call.
|
27
|
+
# For example, you could use it to set `LD_PRELOAD="/path/to/libsomething.so"`.
|
28
|
+
# Must be a hash of strings keyed to valid environment variable name strings.
|
29
|
+
# e.g. {'MY_ENV' => 'my value'}
|
37
30
|
#
|
38
|
-
# @return [
|
31
|
+
# @return [Hash]
|
39
32
|
#
|
40
|
-
attr_accessor :
|
33
|
+
attr_accessor :cli_env
|
34
|
+
|
41
35
|
##
|
42
|
-
#
|
43
|
-
#
|
36
|
+
# If set to true, Open3 will restrict system calls to access only
|
37
|
+
# environment variables defined in :cli_env, plus HOME, PATH, and LANG
|
38
|
+
# since those are required for such system calls. It will not pass on any
|
39
|
+
# other environment variables from the system.
|
44
40
|
#
|
45
41
|
# @return [Boolean]
|
46
42
|
#
|
47
|
-
|
43
|
+
attr_accessor :restricted_env
|
44
|
+
|
48
45
|
##
|
49
|
-
#
|
50
|
-
#
|
51
|
-
# a file.
|
46
|
+
# If you don't want commands to take too long, you can set a timeout (in
|
47
|
+
# seconds).
|
52
48
|
#
|
53
|
-
# @return [
|
49
|
+
# @return [Integer]
|
54
50
|
#
|
55
|
-
attr_accessor :
|
56
|
-
|
51
|
+
attr_accessor :timeout
|
57
52
|
##
|
58
|
-
#
|
59
|
-
#
|
60
|
-
# user input, although it adds a bit of overhead. Defaults to `true`.
|
53
|
+
# Logger for commands, default is `Logger.new($stdout)`, but you can
|
54
|
+
# override it, for example if you want the logs to be written to a file.
|
61
55
|
#
|
62
|
-
# @return [
|
56
|
+
# @return [Logger]
|
63
57
|
#
|
64
|
-
attr_accessor :
|
58
|
+
attr_accessor :logger
|
65
59
|
##
|
66
|
-
#
|
67
|
-
#
|
68
|
-
# is not valid. Useful for validating that processing was sucessful,
|
69
|
-
# although it adds a bit of overhead. Defaults to `true`.
|
60
|
+
# Temporary directory used by MiniMagick, default is `Dir.tmpdir`, but
|
61
|
+
# you can override it.
|
70
62
|
#
|
71
|
-
# @return [
|
63
|
+
# @return [String]
|
72
64
|
#
|
73
|
-
attr_accessor :
|
65
|
+
attr_accessor :tmpdir
|
74
66
|
|
75
67
|
##
|
76
68
|
# If set to `false`, it will not raise errors when ImageMagick returns
|
@@ -78,121 +70,32 @@ module MiniMagick
|
|
78
70
|
#
|
79
71
|
# @return [Boolean]
|
80
72
|
#
|
81
|
-
attr_accessor :
|
73
|
+
attr_accessor :errors
|
82
74
|
|
83
75
|
##
|
84
|
-
#
|
85
|
-
#
|
86
|
-
|
87
|
-
#
|
88
|
-
# @return [String]
|
89
|
-
#
|
90
|
-
attr_accessor :shell_api
|
76
|
+
# If set to `false`, it will not forward warnings from ImageMagick to
|
77
|
+
# standard error.
|
78
|
+
attr_accessor :warnings
|
91
79
|
|
92
80
|
def self.extended(base)
|
93
|
-
base.
|
94
|
-
base.
|
95
|
-
base.whiny = true
|
96
|
-
base.shell_api = "open3"
|
81
|
+
base.tmpdir = Dir.tmpdir
|
82
|
+
base.errors = true
|
97
83
|
base.logger = Logger.new($stdout).tap { |l| l.level = Logger::INFO }
|
84
|
+
base.warnings = true
|
85
|
+
base.cli_env = {}.freeze
|
86
|
+
base.restricted_env = false
|
87
|
+
base.graphicsmagick = false
|
98
88
|
end
|
99
89
|
|
100
90
|
##
|
101
91
|
# @yield [self]
|
102
92
|
# @example
|
103
93
|
# MiniMagick.configure do |config|
|
104
|
-
# config.cli = :graphicsmagick
|
105
94
|
# config.timeout = 5
|
106
95
|
# end
|
107
96
|
#
|
108
97
|
def configure
|
109
98
|
yield self
|
110
99
|
end
|
111
|
-
|
112
|
-
CLI_DETECTION = {
|
113
|
-
imagemagick7: "magick",
|
114
|
-
imagemagick: "mogrify",
|
115
|
-
graphicsmagick: "gm",
|
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
100
|
end
|
198
101
|
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,33 +79,15 @@ 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)
|
100
|
-
else
|
101
|
-
ext ||= File.extname(openable.to_s)
|
102
|
-
end
|
103
|
-
ext.sub!(/:.*/, '') # hack for filenames or URLs that include a colon
|
104
|
-
|
105
|
-
if openable.is_a?(URI::Generic)
|
106
|
-
openable.open(options) { |file| read(file, ext) }
|
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) }
|
107
87
|
else
|
108
|
-
|
88
|
+
pathname = Pathname(path_or_url)
|
89
|
+
ext ||= File.extname(pathname.to_s)
|
90
|
+
pathname.open(binmode: true, **options) { |file| read(file, ext) }
|
109
91
|
end
|
110
92
|
end
|
111
93
|
|
@@ -118,18 +100,14 @@ module MiniMagick
|
|
118
100
|
# we have a good tempfile.
|
119
101
|
#
|
120
102
|
# @param ext [String] Specify the extension you want to read it as
|
121
|
-
# @param validate [Boolean] If false, skips validation of the created
|
122
|
-
# image. Defaults to true.
|
123
103
|
# @yield [Tempfile] You can #write bits to this object to create the new
|
124
104
|
# Image
|
125
105
|
# @return [MiniMagick::Image] The created image
|
126
106
|
#
|
127
|
-
def self.create(ext = nil,
|
107
|
+
def self.create(ext = nil, &block)
|
128
108
|
tempfile = MiniMagick::Utilities.tempfile(ext.to_s.downcase, &block)
|
129
109
|
|
130
|
-
new(tempfile.path, tempfile)
|
131
|
-
image.validate! if validate
|
132
|
-
end
|
110
|
+
new(tempfile.path, tempfile)
|
133
111
|
end
|
134
112
|
|
135
113
|
##
|
@@ -164,7 +142,7 @@ module MiniMagick
|
|
164
142
|
# which creates a temporary file for you and protects your original.
|
165
143
|
#
|
166
144
|
# @param input_path [String, Pathname] The location of an image file
|
167
|
-
# @yield [MiniMagick::Tool
|
145
|
+
# @yield [MiniMagick::Tool] If block is given, {#combine_options}
|
168
146
|
# is called.
|
169
147
|
#
|
170
148
|
def initialize(input_path, tempfile = nil, &block)
|
@@ -228,10 +206,6 @@ module MiniMagick
|
|
228
206
|
#
|
229
207
|
attribute :type, "format"
|
230
208
|
##
|
231
|
-
# @return [String]
|
232
|
-
#
|
233
|
-
attribute :mime_type
|
234
|
-
##
|
235
209
|
# @return [Integer]
|
236
210
|
#
|
237
211
|
attribute :width
|
@@ -274,7 +248,7 @@ module MiniMagick
|
|
274
248
|
#
|
275
249
|
attribute :resolution
|
276
250
|
##
|
277
|
-
# Returns the message digest of this image as a SHA-256,
|
251
|
+
# Returns the message digest of this image as a SHA-256, hexadecimal
|
278
252
|
# encoded string. This signature uniquely identifies the image and is
|
279
253
|
# convenient for determining if an image has been modified or whether two
|
280
254
|
# images are identical.
|
@@ -286,17 +260,10 @@ module MiniMagick
|
|
286
260
|
#
|
287
261
|
attribute :signature
|
288
262
|
##
|
289
|
-
# Returns the
|
290
|
-
# ImageMagick.
|
263
|
+
# Returns the result of converting the image to JSON format.
|
291
264
|
#
|
292
265
|
# @return [Hash]
|
293
266
|
attribute :data
|
294
|
-
##
|
295
|
-
# Returns the information from `identify -verbose` in a Hash format, for
|
296
|
-
# GraphicsMagick.
|
297
|
-
#
|
298
|
-
# @return [Hash]
|
299
|
-
attribute :details
|
300
267
|
|
301
268
|
##
|
302
269
|
# Use this method if you want to access raw Identify's format API.
|
@@ -340,13 +307,18 @@ module MiniMagick
|
|
340
307
|
#
|
341
308
|
# 1) one for each row of pixels
|
342
309
|
# 2) one for each column of pixels
|
343
|
-
# 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
|
344
311
|
#
|
345
312
|
# @example
|
346
313
|
# img = MiniMagick::Image.open 'image.jpg'
|
347
314
|
# pixels = img.get_pixels
|
348
315
|
# pixels[3][2][1] # the green channel value from the 4th-row, 3rd-column pixel
|
349
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
|
+
#
|
350
322
|
# It can also be called after applying transformations:
|
351
323
|
#
|
352
324
|
# @example
|
@@ -357,19 +329,22 @@ module MiniMagick
|
|
357
329
|
#
|
358
330
|
# In this example, all pixels in pix should now have equal R, G, and B values.
|
359
331
|
#
|
332
|
+
# @param map [String] A code for the mapping of the pixel data. Must be either
|
333
|
+
# 'RGB' or 'RGBA'. Default to 'RGB'
|
360
334
|
# @return [Array] Matrix of each color of each pixel
|
361
|
-
def get_pixels
|
362
|
-
|
335
|
+
def get_pixels(map="RGB")
|
336
|
+
raise ArgumentError, "Invalid map value" unless ["RGB", "RGBA"].include?(map)
|
337
|
+
convert = MiniMagick.convert
|
363
338
|
convert << path
|
364
339
|
convert.depth(8)
|
365
|
-
convert << "
|
340
|
+
convert << "#{map}:-"
|
366
341
|
|
367
342
|
# Do not use `convert.call` here. We need the whole binary (unstripped) output here.
|
368
343
|
shell = MiniMagick::Shell.new
|
369
344
|
output, * = shell.run(convert.command)
|
370
345
|
|
371
346
|
pixels_array = output.unpack("C*")
|
372
|
-
pixels = pixels_array.each_slice(
|
347
|
+
pixels = pixels_array.each_slice(map.length).each_slice(width).to_a
|
373
348
|
|
374
349
|
# deallocate large intermediary objects
|
375
350
|
output.clear
|
@@ -378,6 +353,23 @@ module MiniMagick
|
|
378
353
|
pixels
|
379
354
|
end
|
380
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
|
+
|
381
373
|
##
|
382
374
|
# This is used to change the format of the image. That is, from "tiff to
|
383
375
|
# jpg" or something like that. Once you run it, the instance is pointing to
|
@@ -401,7 +393,7 @@ module MiniMagick
|
|
401
393
|
# will convert all pages.
|
402
394
|
# @param read_opts [Hash] Any read options to be passed to ImageMagick
|
403
395
|
# for example: image.format('jpg', page, {density: '300'})
|
404
|
-
# @yield [MiniMagick::Tool
|
396
|
+
# @yield [MiniMagick::Tool] It optionally yields the command,
|
405
397
|
# if you want to add something.
|
406
398
|
# @return [self]
|
407
399
|
#
|
@@ -416,7 +408,7 @@ module MiniMagick
|
|
416
408
|
input_path = path.dup
|
417
409
|
input_path << "[#{page}]" if page && !layer?
|
418
410
|
|
419
|
-
MiniMagick
|
411
|
+
MiniMagick.convert do |convert|
|
420
412
|
read_opts.each do |opt, val|
|
421
413
|
convert.send(opt.to_s, val)
|
422
414
|
end
|
@@ -436,6 +428,9 @@ module MiniMagick
|
|
436
428
|
@info.clear
|
437
429
|
|
438
430
|
self
|
431
|
+
rescue MiniMagick::Invalid, MiniMagick::Error => e
|
432
|
+
new_tempfile.unlink if new_tempfile && @tempfile != new_tempfile
|
433
|
+
raise e
|
439
434
|
end
|
440
435
|
|
441
436
|
##
|
@@ -449,7 +444,7 @@ module MiniMagick
|
|
449
444
|
# c.background "blue"
|
450
445
|
# end
|
451
446
|
#
|
452
|
-
# @yield [MiniMagick::
|
447
|
+
# @yield [MiniMagick::Command]
|
453
448
|
# @see http://www.imagemagick.org/script/mogrify.php
|
454
449
|
# @return [self]
|
455
450
|
#
|
@@ -470,8 +465,11 @@ module MiniMagick
|
|
470
465
|
end
|
471
466
|
end
|
472
467
|
|
473
|
-
|
474
|
-
|
468
|
+
##
|
469
|
+
# Prevents ruby from calling `#to_ary` on the image when checking if it's a
|
470
|
+
# splattable data structure in certain cases.
|
471
|
+
def respond_to_missing?(name, include_all)
|
472
|
+
false
|
475
473
|
end
|
476
474
|
|
477
475
|
##
|
@@ -486,7 +484,7 @@ module MiniMagick
|
|
486
484
|
case output_to
|
487
485
|
when String, Pathname
|
488
486
|
if layer?
|
489
|
-
MiniMagick
|
487
|
+
MiniMagick.convert do |builder|
|
490
488
|
builder << path
|
491
489
|
builder << output_to
|
492
490
|
end
|
@@ -513,7 +511,7 @@ module MiniMagick
|
|
513
511
|
def composite(other_image, output_extension = type.downcase, mask = nil)
|
514
512
|
output_tempfile = MiniMagick::Utilities.tempfile(".#{output_extension}")
|
515
513
|
|
516
|
-
MiniMagick
|
514
|
+
MiniMagick.composite do |composite|
|
517
515
|
yield composite if block_given?
|
518
516
|
composite << other_image.path
|
519
517
|
composite << path
|
@@ -555,27 +553,21 @@ module MiniMagick
|
|
555
553
|
# b.verbose
|
556
554
|
# end # runs `identify -verbose image.jpg`
|
557
555
|
# @return [String] Output from `identify`
|
558
|
-
# @yield [MiniMagick::Tool
|
556
|
+
# @yield [MiniMagick::Tool]
|
559
557
|
#
|
560
558
|
def identify
|
561
|
-
MiniMagick
|
559
|
+
MiniMagick.identify do |builder|
|
562
560
|
yield builder if block_given?
|
563
561
|
builder << path
|
564
562
|
end
|
565
563
|
end
|
566
564
|
|
567
|
-
# @private
|
568
|
-
def run_command(tool_name, *args)
|
569
|
-
MiniMagick::Tool.const_get(tool_name.capitalize).new do |builder|
|
570
|
-
args.each do |arg|
|
571
|
-
builder << arg
|
572
|
-
end
|
573
|
-
end
|
574
|
-
end
|
575
|
-
|
576
565
|
def mogrify(page = nil)
|
577
|
-
MiniMagick
|
566
|
+
MiniMagick.mogrify do |builder|
|
578
567
|
yield builder if block_given?
|
568
|
+
if builder.args.include?("-format")
|
569
|
+
fail MiniMagick::Error, "you must call #format on a MiniMagick::Image directly"
|
570
|
+
end
|
579
571
|
builder << (page ? "#{path}[#{page}]" : path)
|
580
572
|
end
|
581
573
|
|