Coder Social home page Coder Social logo

minimagick's Introduction

MiniMagick

Gem Version Gem Downloads Build Status Code Climate

A ruby wrapper for ImageMagick or GraphicsMagick command line.

Why?

I was using RMagick and loving it, but it was eating up huge amounts of memory. Even a simple script would use over 100MB of RAM. On my local machine this wasn't a problem, but on my hosting server the ruby apps would crash because of their 100MB memory limit.

Solution!

Using MiniMagick the ruby processes memory remains small (it spawns ImageMagick's command line program mogrify which takes up some memory as well, but is much smaller compared to RMagick). See Thinking of switching from RMagick? below.

MiniMagick gives you access to all the command line options ImageMagick has (found here).

Requirements

ImageMagick or GraphicsMagick command-line tool has to be installed. You can check if you have it installed by running

$ convert -version
Version: ImageMagick 6.8.9-7 Q16 x86_64 2014-09-11 http://www.imagemagick.org
Copyright: Copyright (C) 1999-2014 ImageMagick Studio LLC
Features: DPC Modules
Delegates: bzlib fftw freetype jng jpeg lcms ltdl lzma png tiff xml zlib

MiniMagick has been tested on following Rubies:

  • MRI 2.6
  • MRI 2.5
  • MRI 2.4
  • MRI 2.3
  • MRI 2.2
  • MRI 2.1
  • MRI 2.0
  • JRuby 9k

Installation

Add the gem to your Gemfile:

gem "mini_magick"

Information

Usage

Let's first see a basic example of resizing an image.

require "mini_magick"

image = MiniMagick::Image.open("input.jpg")
image.path #=> "/var/folders/k7/6zx6dx6x7ys3rv3srh0nyfj00000gn/T/magick20140921-75881-1yho3zc.jpg"
image.resize "100x100"
image.format "png"
image.write "output.png"

MiniMagick::Image.open makes a copy of the image, and further methods modify that copy (the original stays untouched). We then resize the image, and write it to a file. The writing part is necessary because the copy is just temporary, it gets garbage collected when we lose reference to the image.

MiniMagick::Image.open also accepts URLs, and options passed in will be forwarded to open-uri.

image = MiniMagick::Image.open("http://example.com/image.jpg")
image.contrast
image.write("from_internets.jpg")

On the other hand, if we want the original image to actually get modified, we can use MiniMagick::Image.new.

image = MiniMagick::Image.new("input.jpg")
image.path #=> "input.jpg"
image.resize "100x100"
# Not calling #write, because it's not a copy

Combine options

While using methods like #resize directly is convenient, if we use more methods in this way, it quickly becomes inefficient, because it calls the command on each methods call. MiniMagick::Image#combine_options takes multiple options and from them builds one single command.

image.combine_options do |b|
  b.resize "250x200>"
  b.rotate "-90"
  b.flip
end # the command gets executed

As a handy shortcut, MiniMagick::Image.new also accepts an optional block which is used to combine_options.

image = MiniMagick::Image.new("input.jpg") do |b|
  b.resize "250x200>"
  b.rotate "-90"
  b.flip
end # the command gets executed

The yielded builder is an instance of MiniMagick::Tool::Mogrify. To learn more about its interface, see Metal below.

Attributes

A MiniMagick::Image has various handy attributes.

image.type        #=> "JPEG"
image.mime_type   #=> "image/jpeg"
image.width       #=> 250
image.height      #=> 300
image.dimensions  #=> [250, 300]
image.size        #=> 3451 (in bytes)
image.colorspace  #=> "DirectClass sRGB"
image.exif        #=> {"DateTimeOriginal" => "2013:09:04 08:03:39", ...}
image.resolution  #=> [75, 75]
image.signature   #=> "60a7848c4ca6e36b8e2c5dea632ecdc29e9637791d2c59ebf7a54c0c6a74ef7e"

If you need more control, you can also access raw image attributes:

image["%[gamma]"] # "0.9"

To get the all information about the image, MiniMagick gives you a handy method which returns the output from identify -verbose in hash format:

image.data #=>
# {
#   "format": "JPEG",
#   "mimeType": "image/jpeg",
#   "class": "DirectClass",
#   "geometry": {
#     "width": 200,
#     "height": 276,
#     "x": 0,
#     "y": 0
#   },
#   "resolution": {
#     "x": "300",
#     "y": "300"
#   },
#   "colorspace": "sRGB",
#   "channelDepth": {
#     "red": 8,
#     "green": 8,
#     "blue": 8
#   },
#   "quality": 92,
#   "properties": {
#     "date:create": "2016-07-11T19:17:53+08:00",
#     "date:modify": "2016-07-11T19:17:53+08:00",
#     "exif:ColorSpace": "1",
#     "exif:ExifImageLength": "276",
#     "exif:ExifImageWidth": "200",
#     "exif:ExifOffset": "90",
#     "exif:Orientation": "1",
#     "exif:ResolutionUnit": "2",
#     "exif:XResolution": "300/1",
#     "exif:YResolution": "300/1",
#     "icc:copyright": "Copyright (c) 1998 Hewlett-Packard Company",
#     "icc:description": "sRGB IEC61966-2.1",
#     "icc:manufacturer": "IEC http://www.iec.ch",
#     "icc:model": "IEC 61966-2.1 Default RGB colour space - sRGB",
#     "jpeg:colorspace": "2",
#     "jpeg:sampling-factor": "1x1,1x1,1x1",
#     "signature": "1b2336f023e5be4a9f357848df9803527afacd4987ecc18c4295a272403e52c1"
#   },
#   ...
# }

Note that MiniMagick::Image#data is supported only on ImageMagick 6.8.8-3 or above, for GraphicsMagick or older versions of ImageMagick use MiniMagick::Image#details.

Pixels

With MiniMagick you can retrieve a matrix of image pixels, where each member of the matrix is a 3-element array of numbers between 0-255, one for each range of the RGB color channels.

image = MiniMagick::Image.open("image.jpg")
pixels = image.get_pixels
pixels[3][2][1] # the green channel value from the 4th-row, 3rd-column pixel

It can also be called after applying transformations:

image = MiniMagick::Image.open("image.jpg")
image.crop "20x30+10+5"
image.colorspace "Gray"
pixels = image.get_pixels

Pixels To Image

Sometimes when you have pixels and want to create image from pixels, you can do this to form an image:

image = MiniMagick::Image.open('/Users/rabin/input.jpg')
pixels = image.get_pixels
depth = 8
dimension = [image.width, image.height]
map = 'rgb'
image = MiniMagick::Image.get_image_from_pixels(pixels, dimension, map, depth ,'jpg')
image.write('/Users/rabin/output.jpg')

In this example, the returned pixels should now have equal R, G, and B values.

Configuration

MiniMagick.configure do |config|
  config.cli = :graphicsmagick
  config.timeout = 5
end

For a complete list of configuration options, see Configuration.

Composite

MiniMagick also allows you to composite images:

first_image  = MiniMagick::Image.new("first.jpg")
second_image = MiniMagick::Image.new("second.jpg")
result = first_image.composite(second_image) do |c|
  c.compose "Over"    # OverCompositeOp
  c.geometry "+20+20" # copy second_image onto first_image from (20, 20)
end
result.write "output.jpg"

Layers/Frames/Pages

For multilayered images you can access its layers.

gif.frames #=> [...]
pdf.pages  #=> [...]
psd.layers #=> [...]

gif.frames.each_with_index do |frame, idx|
  frame.write("frame#{idx}.jpg")
end

Image validation

By default, MiniMagick validates images each time it's opening them. It validates them by running identify on them, and see if ImageMagick finds them valid. This adds slight overhead to the whole processing. Sometimes it's safe to assume that all input and output images are valid by default and turn off validation:

MiniMagick.configure do |config|
  config.validate_on_create = false
end

You can test whether an image is valid:

image.valid?
image.validate! # raises MiniMagick::Invalid if image is invalid

Logging

You can choose to log MiniMagick commands and their execution times:

MiniMagick.logger.level = Logger::DEBUG
D, [2016-03-19T07:31:36.755338 #87191] DEBUG -- : [0.01s] identify /var/folders/k7/6zx6dx6x7ys3rv3srh0nyfj00000gn/T/mini_magick20160319-87191-1ve31n1.jpg

In Rails you'll probably want to set MiniMagick.logger = Rails.logger.

Switching CLIs (ImageMagick <=> GraphicsMagick)

Default CLI is ImageMagick, but if you want to use GraphicsMagick, you can specify it in configuration:

MiniMagick.configure do |config|
  config.cli = :graphicsmagick # or :imagemagick or :imagemagick7
end

You can also use .with_cli to temporary switch the CLI:

MiniMagick.with_cli(:graphicsmagick) do
  # Some processing that GraphicsMagick is better at
end

WARNING: If you're building a multithreaded web application, you should change the CLI only on application startup. This is because the configuration is global, so if you change it in a controller action, other threads in the same process will also have their CLI changed, which could lead to race conditions.

Metal

If you want to be close to the metal, you can use ImageMagick's command-line tools directly.

MiniMagick::Tool::Magick.new do |magick|
  magick << "input.jpg"
  magick.resize("100x100")
  magick.negate
  magick << "output.jpg"
end #=> `magick input.jpg -resize 100x100 -negate output.jpg`

# OR

convert = MiniMagick::Tool::Convert.new
convert << "input.jpg"
convert.resize("100x100")
convert.negate
convert << "output.jpg"
convert.call #=> `convert input.jpg -resize 100x100 -negate output.jpg`

If you're on ImageMagick 7, you should probably use MiniMagick::Tool::Magick, though the legacy MiniMagick::Tool::Convert and friends will work too. On ImageMagick 6 MiniMagick::Tool::Magick won't be available, so you should instead use MiniMagick::Tool::Convert and friends.

This way of using MiniMagick is highly recommended if you want to maximize performance of your image processing. We will now show the features available.

Appending

The most basic way of building a command is appending strings:

MiniMagick::Tool::Convert.new do |convert|
  convert << "input.jpg"
  convert.merge! ["-resize", "500x500", "-negate"]
  convert << "output.jpg"
end

Note that it is important that every command you would pass to the command line has to be separated with <<, e.g.:

# GOOD
convert << "-resize" << "500x500"

# BAD
convert << "-resize 500x500"

Shell escaping is also handled for you. If an option has a value that has spaces inside it, just pass it as a regular string.

convert << "-distort"
convert << "Perspective"
convert << "0,0,0,0 0,45,0,45 69,0,60,10 69,45,60,35"
convert -distort Perspective '0,0,0,0 0,45,0,45 69,0,60,10 69,45,60,35'

Methods

Instead of passing in options directly, you can use Ruby methods:

convert.resize("500x500")
convert.rotate(90)
convert.distort("Perspective", "0,0,0,0 0,45,0,45 69,0,60,10 69,45,60,35")

MiniMagick knows which options each tool has, so you will get an explicit NoMethodError if you happen to have mispelled an option.

Chaining

Every method call returns self, so you can chain them to create logical groups.

MiniMagick::Tool::Convert.new do |convert|
  convert << "input.jpg"
  convert.clone(0).background('gray').shadow('80x5+5+5')
  convert.negate
  convert << "output.jpg"
end

"Plus" options

MiniMagick::Tool::Convert.new do |convert|
  convert << "input.jpg"
  convert.repage.+
  convert.distort.+("Perspective", "more args")
end
convert input.jpg +repage +distort Perspective 'more args'

Stacks

MiniMagick::Tool::Convert.new do |convert|
  convert << "wand.gif"

  convert.stack do |stack|
    stack << "wand.gif"
    stack.rotate(30)
    stack.foo("bar", "baz")
  end
  # or
  convert.stack("wand.gif", { rotate: 30, foo: ["bar", "baz"] })

  convert << "images.gif"
end
convert wand.gif \( wand.gif -rotate 90 -foo bar baz \) images.gif

STDIN and STDOUT

If you want to pass something to standard input, you can pass the :stdin option to #call:

identify = MiniMagick::Tool::Identify.new
identify.stdin # alias for "-"
identify.call(stdin: image_content)

MiniMagick also has #stdout alias for "-" for outputing file contents to standard output:

content = MiniMagick::Tool::Convert.new do |convert|
  convert << "input.jpg"
  convert.auto_orient
  convert.stdout # alias for "-"
end

Capturing STDERR

Some MiniMagick tools such as compare output the result of the command on standard error, even if the command succeeded. The result of MiniMagick::Tool#call is always the standard output, but if you pass it a block, it will yield the stdout, stderr and exit status of the command:

compare = MiniMagick::Tool::Compare.new
# build the command
compare.call do |stdout, stderr, status|
  # ...
end

Limiting resources

ImageMagick supports a number of environment variables for controlling its resource limits. For example, you can enforce memory or execution time limits by setting the following variables in your application's process environment:

  • MAGICK_MEMORY_LIMIT=128MiB
  • MAGICK_MAP_LIMIT=64MiB
  • MAGICK_TIME_LIMIT=30

For a full list of variables and description, see ImageMagick's resources documentation.

Changing temporary directory

ImageMagick allows you to change the temporary directory to process the image file:

MiniMagick.configure do |config|
  config.tmpdir = File.join(Dir.tmpdir, "/my/new/tmp_dir")
end

The example directory /my/new/tmp_dir must exist and must be writable.

If not configured, it will default to Dir.tmpdir.

Troubleshooting

Errors being raised when they shouldn't

This gem raises an error when ImageMagick returns a nonzero exit code. Sometimes, however, ImageMagick returns nonzero exit codes when the command actually went ok. In these cases, to avoid raising errors, you can add the following configuration:

MiniMagick.configure do |config|
  config.whiny = false
end

If you're using the tool directly, you can pass whiny: false value to the constructor:

MiniMagick::Tool::Identify.new(whiny: false) do |b|
  b.help
end

Errno::ENOMEM

For clients using Ruby < 2.2, it can happen that, when dealing with very large images, the process runs out of memory, and Errno::ENOMEM is raised in your code. In that case try installing the posix-spawn gem, and tell MiniMagick to use it when executing shell commands.

MiniMagick.configure do |config|
  config.shell_api = "posix-spawn"
end

Thinking of switching from RMagick?

Unlike RMagick, MiniMagick is a much thinner wrapper around ImageMagick.

  • To piece together MiniMagick commands refer to the Mogrify Documentation. For instance you can use the -flop option as image.flop.
  • Operations on a MiniMagick image tend to happen in-place as image.trim, whereas RMagick has both copying and in-place methods like image.trim and image.trim!.
  • To open files with MiniMagick you use MiniMagick::Image.open as you would Magick::Image.read. To open a file and directly edit it, use MiniMagick::Image.new.

minimagick's People

Contributors

2potatocakes avatar andersondias avatar artofhuman avatar bensie avatar dcu avatar ethier avatar felixbuenemann avatar for-lesbians avatar fschwahn avatar futhr avatar giuseb avatar hamptonmakes avatar janko avatar jarmo avatar jf avatar kaspergrubbe avatar koic avatar lab-kw avatar lluzak avatar loe avatar maartenvanvliet avatar mtsmfm avatar n0nick avatar nadavshatz avatar nishidayuya avatar probablycorey avatar rrrene avatar stevenharman avatar thiagofm avatar troter avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

minimagick's Issues

LANG Variable Being Respected

If the user is set to a locale that is not "en_*", then the parsing of error
messages is breaking.

I have submitted a pull request to subexec to fix this issue. However, we need
to have a test to make sure that we aren't obeying the locales when it comes
to command processing.

NameError: uninitialized constant Class::StringIO

When using this code:
image = MiniMagick::Image.read blob
image.format "png"
image.write file_path

This error message appears:
NameError: uninitialized constant Class::StringIO
from C:/Ruby186/lib/ruby/gems/1.8/gems/mini_magick-3.1/lib/mini_magick.rb:49:in `read'

Requiring StringIO solves the problem:
require "stringio"

I guess mini_magick should require it instead because it seems to be it's requirement?

failed method seems to corrupt it

not sure if this is the right place, since the readme doesn't indicate if there's a "central" place to report issues...

Anyway not sure if the following is expected. The #to_blog methods works fine until you run a failed command, then it ceases working.

irb(main):006:0> image.to_blob
=> "BM\x9E\x04\x00\x00\x00\x00\x00\x006\x04\x00\x00(\x00\x00\x00\a\x00\x00\x00\r\x00\x00\x00\x01\x00\b\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC4\x0E\x00\x00\xC4\x0E\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\xFF\xEF\xEB\xEF\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x01\x01\x01\x01\x01\x01\x01\x00\x01\x01\x01\x01\x01\x01\x01\x00\x01\x01\x01\x01\x01\x01\x01\x00\x01\x01\x01\x01\x00\x01\x01\x00\x01\x01\x01\x01\x00\x01\x01\x00\x01\x01\x01\x01\x00\x01\x01\x00\x01\x00\x00\x00\x00\x00\x01\x00\x01\x00\x01\x01\x00\x01\x01\x00\x01\x01\x00\x01\x00\x01\x01\x00\x01\x01\x01\x00\x00\x01\x01\x00\x01\x01\x01\x01\x00\x01\x01\x00\x01\x01\x01\x01\x01\x01\x01\x00\x01\x01\x01\x01\x01\x01\x01\x00"
irb(main):007:0> image.to_blog
MiniMagick::Error: Command ("mogrify -to_blog \"C:/Users/packrd/AppData/Local/Temp/mini_magick20100802-5532-1bk9bgs\"") failed: {:status_code=>1, :output=>"Magick: unrecognized option `-to_blog' @ error/mogrify.c/MogrifyImageCommand/6196.\n"}
        from c:/installs/ruby192-rc1/lib/ruby/gems/1.9.1/gems/mini_magick-1.3.1/lib/mini_magick.rb:174:in `run_command'
        from c:/installs/ruby192-rc1/lib/ruby/gems/1.9.1/gems/mini_magick-1.3.1/lib/mini_magick.rb:130:in `method_missing'
        from (irb):7
        from c:/installs/ruby192-rc1/bin/irb:12:in `'
irb(main):008:0> image.to_blob
Errno::ENOENT: No such file or directory - C:/Users/packrd/AppData/Local/Temp/mini_magick20100802-5532-1bk9bgs
        from c:/installs/ruby192-rc1/lib/ruby/gems/1.9.1/gems/mini_magick-1.3.1/lib/mini_magick.rb:119:in `initialize'
        from c:/installs/ruby192-rc1/lib/ruby/gems/1.9.1/gems/mini_magick-1.3.1/lib/mini_magick.rb:119:in `new'
        from c:/installs/ruby192-rc1/lib/ruby/gems/1.9.1/gems/mini_magick-1.3.1/lib/mini_magick.rb:119:in `to_blob'
        from (irb):8
        from c:/installs/ruby192-rc1/bin/irb:12:in `'

Thank you.
-r

Invoking ImageMagick fails when there is a space in the image path

I have some images with a space in the path, and get this error :

MiniMagick::Invalid - identify: unable to open image `/home/renchap/dev/Picty/public/thumbs/A1/Le':  @ error/blob.c/OpenBlob/2584.
identify: no decode delegate for this image format `/home/renchap/dev/Picty/public/thumbs/A1/Le' @ error/constitute.c/ReadImage/532.
identify: unable to open image `Ext/IMG_5257.jpg':  @ error/blob.c/OpenBlob/2584.
:
 /home/renchap/.rvm/gems/ruby-1.8.7-p302/gems/mini_magick-3.1/lib/mini_magick.rb:343:in `run'
 /home/renchap/.rvm/gems/ruby-1.8.7-p302/gems/mini_magick-3.1/lib/mini_magick.rb:329:in `run_command'
 /home/renchap/.rvm/gems/ruby-1.8.7-p302/gems/mini_magick-3.1/lib/mini_magick.rb:253:in `write'

My code :

    image = MiniMagick::Image.open(@picture.physical_path)
    image.resize('200x200')
    image.write(self.physical_path)
    image.destroy!

But the image is successfuly created. Seems some escaping on the path is missing when running identify command.

image[:width] windows

The format query not work in windows. (width return 0)
if i try with image["%w"]
result:
Command ("gm identify -format "%w" C:/Users/boci/AppData/Local/Temp/mini_magick20100918-4128-1qwpxwg-0.jpg") failed: {:status_code=>1, :output=>""}

with command line it's work correctily (with the the temp image)

Ruby warning in mini_magick 3.2

I recently pulled mini_magick into our application, and we're getting a warning about adding parentheses around some arguments.

gems/mini_magick-3.2/lib/mini_magick.rb:412: warning: parenthesize argument(s) for future version

I'd love to submit a patch, but I don't know where to base my fork from. Can you point me in the right direction?

test_simple_composite fails

When I do the test of mini_magick on Ruby 1.9.3 on openSUSE, ruby1.9 test/command_builder_test.rb goes all green. But, ruby1.9 test/image_test.rb fails only on the case test_simple_composite because #245 diff is not identical.

Gm: Command not found ... but gm is installed and working

I get this error when trying to do a simple ImageMagick::Image.from_file(path)

Command ("gm identify -ping /var/folders/bT/bTG3WLkxG78yXgLDbyM9vU+++TI/-Tmp-/mini_magick20110411-73269-z6ibli.png") failed: {:status_code=>127, :output=>"sh: gm: command not foundn"}

I can run gm from the command line just fine. This must be a config issue, but I am at a loss.l

accepts random XML as a valid SVG image

mwotton@loki:~/projects/retailerland$ cat foo.xml

mwotton@loki:~/projects/retailerland$ identify foo.xml foo.xml SVG 0x0 16-bit DirectClass 63b

it's an identify issue really, I guess, but it carries through to MiniMagick.

example fails

On windows, this, taken from the "examples" fails

require 'mini_magick'
image = MiniMagick::Image.from_file("youtube_4.bmp")
  image.combine_options do |c|
    c.sample "50%"
    c.rotate "-90>"
  end
  image.write("output.jpg")

C:\dev\ruby\sensible-cinema\spec\images>ruby test.rb
C:/installs/ruby_1_9_2_installed/lib/ruby/gems/1.9.1/gems/mini_magick-1.3.2/lib/mini_magick.rb:199:in `run_command': Command ("mogrify -sample \"50%\" -rotate -90> \"C:/Users/packrd/AppData/Local/Temp/mini_magick20100818-3088-1kmx5fr.bmp\"") failed: {:status_code=>1, :output=>""} (MiniMagick::Error)
        from C:/installs/ruby_1_9_2_installed/lib/ruby/gems/1.9.1/gems/mini_magick-1.3.2/lib/mini_magick.rb:155:in `combine_options'
        from test.rb:3:in `'

It might be expected. The error doesn't result if you take out the "rotate" line.

Can't generate ico file with another extension

Hello,

mini_magick can succesfuly generate an ico file with another extension but then it rases an exception anyway. I can do this and it works:

f = MiniMagick::Image.open("boo.jpg")
f.resize "48x48"
f.format "ico"
f.write "boo.ico"

No problem and the file is created succesfuly. But if I do this, which is what carrierwave does, it generates an exception:

f = MiniMagick::Image.open("boo.jpg")
f.resize "48x48"
f.format "ico"
f.write "boo_ico.jpg"

The exception is: MiniMagick::Error: Command ("identify -ping "boo_ico.jpg"") failed: {:status_code=>1, :output=>"identify: Not a JPEG file: starts with 0x00 0x00 boo_ico.jpg @ error/jpeg.c/JPEGErrorHandler/297.\n"}

Indeed the command fails like that. Are you not running that command when the extension is .ico? Maybe it shouldn't be run when the format is "ico" either. What do you think?

Note that saving a jpg as .png or a png as .jpg works fine. The problem is only with ico.

Are there any workarounds for this?

Bad image quality with Carrierwave

I'm using Carrierwave to do file uploads in my rails app and I just noticed that the image quality of the thumbnails is really bad. A lot of artifacts are showing. I tried disabling a lot of things in my uploader but nothing helps except switching to ImageMagick instead of GraphicsMagick. Then the quality is satisfying.

Any ideas why that could be?

ArgumentError: invalid byte sequence in UTF-8

Ruby 1.9.2-p136, Rails 3.0.3, ImageMagick 6.6.4-5, mini_magick 3.2.

Getting this error when reading IPTC metadata with high-bit characters in it, for example, "Stable Café":

ArgumentError: invalid byte sequence in UTF-8

These are JPEG's exported from Adobe Lightroom 3.3. The high-bit characters are in what Lightroom calls the "Title" field, which shows up in the IPTC metadata as "Image Name":

Image Name[2,5]: Stable Caf?

I'm reading them using this parameter in Ruby:

image['%[IPTC:2:5]']

Doing a Command-I in OS X Preview shows the metadata with the correct character. The identify command likewise shows a question mark:

$ identify -format "%[IPTC:2:5]" ~/Pictures/_MG_4270.jpg
Stable Caf?

Writing the results to a file and bringing them up in TextMate does show the correct character:

$ identify -format "%[IPTC:2:5]" ~/Pictures/_MG_4270.jpg > foo.txt

The file contains:

Stable Café

So, it's clear that the "é" is correctly stored in the metadata. It's just that Ruby has trouble with it.

Rotating Landscape Photos

Can anyone point me to some code where mini_magick can inspect the EXIF metadata of an image to see if it is in landscape and then rotate it if necessary?

Thanks.

Windows gif conversion problem

If I try to convert a gif to png (image.format "png")
It's generate the key frames but the script using wrong name.
It's try:
mini_magick20101001-6120-1sc6m69-0.png

But in the filesystem:
mini_magick20101001-6120-1sc6m69-0.png.0

GraphicsMagick error: "gm identify: Unrecognized option (-quiet)."

I get the following error when I try to access the mime_type or the format attribute of an image with MiniMagick and GraphicsMagick:

1.9.3p125 :010 > image['format']
MiniMagick::Error: Command ("gm identify -ping -quiet -format "%mn" "/var/folders/kr/4822rmzd7zzcmvs89ghnc4z80000gn/T/mini_magick20120224-91343-10wb7he.jpg"") failed: {:status_code=>1, :output=>"gm identify: Unrecognized option (-quiet).\n"}

breaks with special characters?

Hey,

I've got a filename like this (german umlaut): Frühling.jpg
mini_magick breaks with:

failed: {:output=>"identify: unable to open image `/tmp/img/Fr\303\274hling.jpg': @ error/blob.c/OpenBlob/2498.\n", :status_code=>1}

same result for other things like quotes, etc... is there a solution to this?

Thanks in advance!
Christoph

Should the gem install fail if ImageMagick or GraphicsMagick isn't installed?

I was just having problems getting mini_magick to work on a new dev environment (it installed fine but other gems that I was using that depended on mini_magick weren't working as expected), when I realised that it was because the mini_magick gem was installing fine without actually having ImageMagick installed on the system.

This might be a really dumb question, but shouldn't mini_magick check if one of the required libraries is present during the gem install and fail if not?

I'm using mini_magick 3.3. (Thanks!)

Create a new image from scratch

Hi,

If I'm not mistaken, it is not possible to create a new image (which doesn't exist on the disk yet) with MiniMagick, while it is possible with the convert tool. It would be useful, especially for canvas and composite. Here's a dirty hack I'm using:

def new_image(width, height, format = "png", bgcolor = "transparent")
  tmp = Tempfile.new(%W[mini_magick_ .#{format}])
  `convert -size #{width}x#{height} xc:#{bgcolor} #{tmp.path}`
  MiniMagick::Image.new(tmp.path, tmp)
end

It would be interesting to add this feature in MiniMagick unless something similar already exists.

Best,
Vivien.

Can't use methods with dash

I'm not sure if there is some way I didn't find but I'm not able to use methods with dash. In sources, there is MOGRIFY_COMMANDS array which includes also dashed methods but because methods are handled as symbols, dash isn't available.

I want to run ie. image.auto_orient translated into mogrify -auto-orient

Problems converting a cr2 file to jpg

I'm using minimagic thru carrierwave, but I'd figure out that somewhere in the command the ppm file directory is wrong.

This is the output:

File Failed to manipulate with MiniMagick, maybe it is not an image? 

Original Error: Command ("identify -ping /tmp/mini_magick20111209-8619-1gbc6x6.cr2") failed: 

{:status_code=>1, :output=>
"sh: ufraw-batch: not found\nidentify: delegate failed

 `\"ufraw-batch\" --silent --wb=camera --black-point=auto --exposure=auto --create-id=also --out-type=png --out-depth=16 \"--output=%u.png\" \"%i\"' 

@ error/delegate.c/InvokeDelegate/1061.\nidentify: unable to open image `/tmp/magick-XXIBXfIL.ppm': pnm.la @ error/blob.c/OpenBlob/2489.\nidentify: 
unable to open image `/tmp/magick-XXIBXfIL.ppm': 8 @ error/blob.c/OpenBlob/2489.\n"}

composite

According to the documentation, the composite method can take a third argument.

"If a third image is given this is treated as a gray-scale 'mask' image relative to the first 'destination' image. This mask will limit what parts of the destination can be modified by the image composition. However for the 'displace' compose method, the mask is used to provide a separate Y-displacement image instead."
http://www.imagemagick.org/script/command-line-options.php?#composite

Whenever I add a third argument i get

undefined method `close' for nil:NilClass

I'm using it as so:

result = image.composite(MiniMagick::Image.open(images[0], "jpg"), MiniMagick::Image.open(images[1], "jpg"))

any idea?
Thanks!

Sending a PathName class to the arguments of push

This is my first gem editing experience so please excuse the brevity and anything else thats wrong :P.

Im running Ruby 1.9.2 with RVM and was getting this error:

NoMethodError - undefined method 'strip' for #<Pathname:0x000001016edff0>:
/Users/chris/.rvm/gems/ruby-1.9.2-p0@myproject/gems/mini_magick-2.1/lib/mini_magick.rb:263:in 'push'
/Users/chris/.rvm/gems/ruby-1.9.2-p0@myproject/gems/mini_magick-2.1/lib/mini_magick.rb:236:in 'block in initialize'
/Users/chris/.rvm/gems/ruby-1.9.2-p0@myproject/gems/mini_magick-2.1/lib/mini_magick.rb:236:in 'each'
/Users/chris/.rvm/gems/ruby-1.9.2-p0@myproject/gems/mini_magick-2.1/lib/mini_magick.rb:236:in 'initialize'
/Users/chris/.rvm/gems/ruby-1.9.2-p0@myproject/gems/mini_magick-2.1/lib/mini_magick.rb:186:in 'new'
/Users/chris/.rvm/gems/ruby-1.9.2-p0@myproject/gems/mini_magick-2.1/lib/mini_magick.rb:186:in 'run_command'
/Users/chris/.rvm/gems/ruby-1.9.2-p0@myproject/gems/mini_magick-2.1/lib/mini_magick.rb:129:in 'write'
/Users/chris/Projects/MyProject/project/lib/models/user.rb:164:in 'transform'

I investigated and found that push was in fact getting passed a Pathname class, though write was getting passed a string.
I patched it by replacing the push method on line 262 of lib/mini_magick.rb, replacing
@Args << arg.strip
with
@Args << "#{arg}".strip

My apologies that I dont have time to properly patch or test it but am running short on time and thought itd be good to at least raise an issue concerning it.

Have a good one

Failed to manipulate with MiniMagick, maybe it is not an image?

hi,

my rails app on Windows 7 cannot successfully resize and upload images with the following error returned.

Failed to manipulate with MiniMagick, maybe it is not an image?
Original Error: identify -ping C:/Users/User/xxxxxxxxx.jpg

the error message is originally returned by minimagick and passed to carrierwave.

i understand that the problem is likely not coming from minimagick but i want to make sure that the components which i installed are compatible.

  1. am i having the correct versions of the following components installed? any compatibility issue here?

gemfile
"activerecord", "2.3.14"
"carrierwave", "0.4.10"
"mini_magick", "3.2.1"
"rails", "2.3.14"

Platform
windows 7 64bit
ruby 1.8.7
imagemagick (installation path = C:\ImageMagick-6.7.2-Q16)

  1. any advice on how to fix the error?

i'm trying to describe everything that i know, please help.

batterhead

Shell out using EM.system instead of Subexec

I'm using MiniMagick in an EventMachine app which also happens to use em-synchrony. It'd be nice to shell out to ImageMagick using EM.system instead of Subexec.

My initial refactoring has the line that calls Subexec.run directly to instead call MiniMagick.execute which is configurable just like MiniMagick.timeout.

module MiniMagick
  @execute = lambda do |command, timeout|
    Subexec.run command, :timeout => timeout
  end

  def self.execute=(execute)
    @execute = execute
  end

  def self.execute(command, timeout)
    @execute.call command, timeout
  end
end

Here's how I'm using it:

require 'ostruct'
MiniMagick.timeout = 30
MiniMagick.execute = ->(command, timeout) do
  f = Fiber.current
  EM.system command do |output, status|
    f.resume [ output, status ]
  end

  # TODO: handle timeout

  output, status = Fiber.yield
  OpenStruct.new output: output, exitstatus: status.exitstatus
end

This will become a pull request once it gets some tests around it. Any feedback?

Failed to manipulate with MiniMagick, maybe it is not an image?

I am upgrading my app to rails 3.2 on ruby 1.9. I had to drop attachment_fu. Carrierwave seemed the obvious replacement. At this stage I am uploading files to the file system (no cloud files, yet).

I am on Lion, XCode 4.3.2, Command Line Tools installed. Running $ brew doctor returns: Your system is raring to brew.

I can upload and resize images in this configuration:
rails 3.1.4
ruby 1.8.7
carrierwave 0.5.8
mini_magick 3.4

I can upload images in the new configuration:
rails 3.2.3
ruby 1.9.3 (or 1.9.2)
carrierwave 0.6.2
(followed by $ bundle update)
but resizing using mini_magick returns this error message:
"File Failed to manipulate with MiniMagick, maybe it is not an image? Original Error: MiniMagick::Invalid", where File is the carrierwave uploader.

The FileUploader contains:

include CarrierWave::MiniMagick
def store_dir .. end # the shipped default 
process :resize_to_limit => [500, 600]

My Attachment class (with the mount_uploader :file, FileUploader) is a parent of Portrait, ReferenceLetter, and other attachment kind of classes. Each of the attachment classes inherits from the Attachment, is :polymorphic => true, and belongs_to :attachable (User) which, in turn, has_many :portraits, :reference_letters, etc. :as => :attachable.

None of these worked:
http://stackoverflow.com/questions/2838307/why-is-this-rmagick-call-generating-a-segmentation-fault
I didn't want to install ImageMagick manually as suggested here:
http://stackoverflow.com/questions/9905499/carrierwave-mini-magick-gems-not-an-image-error

I'm using Homebrew. I'm not sure whether this should be under carrierwave or mini_magic, so I'm posting under both. Help would be fantastic.

Thanks,
martin

Issues with background and combine_options

I've been having trouble since upgrading to MiniMagick 2. This code works on 1.X, but it fails on 2.0:

require 'rubygems'
require 'mini_magick'

background = "#ff0000"

img = ::MiniMagick::Image.from_file(File.expand_path('landscape.jpg', File.dirname(__FILE__)))
img.combine_options do |cmd|
  cmd.background background
end
img.write(File.expand_path('landscape_foo.jpg', File.dirname(__FILE__)))

The error looks like this:

~/Projects/carrierwave(master)$ ruby mini.rb 
mogrify: option requires an argument `-background' @ error/mogrify.c/MogrifyImageCommand/4233.
/Users/jonas/.rvm/gems/ruby-1.9.2-preview3@carrierwave/gems/mini_magick-2.0.0/lib/mini_magick.rb:210:in `run': Command ("mogrify -background #ff0000 \"/var/folders/-6/-68dG-nwEmyUAalxoRiyw++++TI/-Tmp-/mini_magick20100824-51391-117fhqj.jpg\"") failed: {:status_code=>1, :output=>""} (MiniMagick::Error)
  from /Users/jonas/.rvm/gems/ruby-1.9.2-preview3@carrierwave/gems/mini_magick-2.0.0/lib/mini_magick.rb:160:in `combine_options'
  from mini.rb:9:in `<main>'

Catch Identify Warnings For Dimensions

I think the identify command should catch errors, I used something like the following in an project:

::MiniMagick::Image.open(filename)['dimensions']

to get the dimensions and ended up getting arrays like [0, 0, 0, 0, 0, 0, 0, 0, 0] in some cases, because the identify command warns about broken images:

  /tmp % identify -format '%w %h' zg.tdix.jpeg
  identify: Premature end of JPEG file `zg.tdix.jpeg' @ warning/jpeg.c/JPEGWarningHandler/325.
  identify: Corrupt JPEG data: premature end of data segment `zg.tdix.jpeg' @ warning/jpeg.c/JPEGWarningHandler/325.
  390 195

and the code to parse this explains this behavior:

  run_command("identify", "-format", format_option("%w %h"), escaped_path).split("\n")[0].split.map{|v|v.to_i}

I think the error messages (stderr) of identify should be handled separately somehow.

unable to change type within a block

This succeeds:

require 'mini_magick'
image = MiniMagick::Image.from_file("youtube_4.bmp")
 image.format(:pnm)
 image.write("output.pnm")

however, the following appears to not change the type to pnm, perhaps it is expected?

require 'mini_magick'
image = MiniMagick::Image.from_file("youtube_4.bmp")
  image.combine_options do |c|
    c.format(:pnm)
  end
  image.write("output.pnm")

Argument escape doesn't work

In CommandBuilder:

push("-#{guessed_command_name} #{args.join(" ")}")

But the push method skips escaping if there's a - in the input. This breaks the mogrify command if there's a > in e.g. the resize argument.

A possible patch:

http://github.com/morten/mini_magick/commit/da7e58d4e20be97ee2fe00fc77cad88c28016270

But as this will always escape, beware that it breaks other tests, e.g.:

assert_equal "-resize 30x40 -alpha 1 3 4 -resize \"mome fingo\"", c.args.join(" ")

Where my change would result in:

assert_equal "-resize \"30x40\" -alpha \"1 3 4\" -resize \"mome fingo\"", c.args.join(" ")

If the patch is okay, then the test suite should be changed. Otherwise the code should be changed to pass the test case in my patch.

No such file or directory - identify -ping /tmp/somefile

Hi,

I've been struggling on an error we have on our staging server and I'd hope anybody could help me.

We are using mini_magick 3.4 together with ImageMagick 6.6.9-7

Carrierwave was configured to send images through s3 but I don't think this is relevant (correct me if it is :)

We upload the image file by sending it through ajax in the post raw data and grab it in this controller action:

def create
  filename   = params[:qqfile]
  attachment = create_file_to_upload(request.body, filename)
  content    = File.open(attachment.path)
  current_user.media.create(:attachment => content)
  attachment.delete
  render :json => {success: true}, :status => 200
end

The create_file_to_upload method uses a tempfile to store the request raw data payload:

def create_file_to_upload(body, name)
  basename  = File.basename(name)
  extension = File.extname(name)
  file      = Tempfile.new([basename, extension])
  file.binmode
  file.write(body.read)
  file.close
  file
end

It works great in development and test environment but however, on our staging server, it fails with:

Completed 500 Internal Server Error in 29ms

Errno::ENOENT (No such file or directory - identify -ping /tmp/mini_magick20120112-14991-1gw63m2.png):
  app/controllers/media_controller.rb:6:in `create'

I've checked that the identify command was accessible to the user with which the app is being run and it is. I have also run the command in a terminal on our server and it works like a charm.

I'm a bit lost and would be open to any suggestion, so if you have a few minutes to think about this or to point me in any direction, I'd really appreciate it.

Thanks

Image Temp files get deleted.

My problem is that currently mini_magick deletes the temp file after I perform one operation. The result is that any other operations including write fail since they depend on the presence of the temp file. After the first operation mini_magick creates a dozen files sharing the same base as the original temp file but appending a -0,-1,-2 etc... to the end of the file name. I am running Rails 3.1, mini_magick 3.3 (note: i am using mini_magick through carrierwave).

import_pixels gives "mogrify: unable to open image (/tmp/mini_magick...png)"

I ran into trouble decoding raw image data:

i = MiniMagick::Image.import_pixels 0.chr * 64, 4, 4, 4, 'rgba'
i.resize "2x2"

This gives the following error:

MiniMagick::Error: Command ("mogrify -resize "2x2" /tmp/mini_magick20120503-9816-soa1i9.png") failed: {:status_code=>1, :output=>"mogrify: unable to open image `/tmp/mini_magick20120503-9816-soa1i9.png':  @ error/blob.c/OpenBlob/2498.\nmogrify: unable to open file `/tmp/mini_magick20120503-9816-soa1i9.png' @ error/png.c/ReadPNGImage/3072.\n"}
    from /home/jewel/.rvm/gems/ruby-1.9.3-p194/gems/mini_magick-3.4/lib/mini_magick.rb:417:in `run'
    from /home/jewel/.rvm/gems/ruby-1.9.3-p194/gems/mini_magick-3.4/lib/mini_magick.rb:362:in `combine_options'
    from /home/jewel/.rvm/gems/ruby-1.9.3-p194/gems/mini_magick-3.4/lib/mini_magick.rb:341:in `method_missing'
    from (irb):21
    from /home/jewel/.rvm/rubies/ruby-1.9.3-p194/bin/irb:16:in `<main>'

However, it works fine if "pam" is passed as an additional argument. (This might be a better default value than PNG anyway.)

This is on Ubuntu natty, ruby 1.9.3p194, ImageMagick 6.6.2-6 (from apt).

MiniMagick creating Tempfiles with -0 and -1 suffixes, getting confused, throwing an error

In my app, I open an image from a file path, then attempt to do some manipulation to it. The first one works, the second errors out.

irb(main):024:0> img = MiniMagick::Image.open(path(descriptor, options))
=> #<MiniMagick::Image:0xc4b3488 @path="/tmp/mini_magick20110401-5076-1jrms7g.jpg", @tempfile=#<File:/tmp/mini_magick20110401-5076-1jrms7g.jpg (closed)>>
irb(main):025:0> img.resize("300x300")
=> ""
irb(main):026:0> img.resize("300x200")
Errno::ENOENT: No such file or directory - /tmp/mini_magick20110401-5076-1jrms7g.jpg
from /var/www/rails.dreamcatcher.net/shared/bundle/ruby/1.9.1/gems/mini_magick-3.2/lib/mini_magick.rb:369:in `unlink'
from /var/www/rails.dreamcatcher.net/shared/bundle/ruby/1.9.1/gems/mini_magick-3.2/lib/mini_magick.rb:369:in `destroy!'
from /var/www/rails.dreamcatcher.net/shared/bundle/ruby/1.9.1/gems/mini_magick-3.2/lib/mini_magick.rb:352:in `run'
from /var/www/rails.dreamcatcher.net/shared/bundle/ruby/1.9.1/gems/mini_magick-3.2/lib/mini_magick.rb:305:in `combine_options'

Yet, in my /tmp/, I see the files:
mini_magick20110401-5076-1jrms7g-0.jpg
mini_magick20110401-5076-1jrms7g-1.jpg

I can't tell when it will create multiple temp files, or when it creates just one. When it creates one it works fine, but when it creates two, it always errors out.

(The server is running Ubuntu.)

Test failure with ImageMagick 6.5.8.8

  1. Failure:
    test_exif(ImageTest) [./test/image_test.rb:121]:
    <"0220"> expected but was
    <"48, 50, 50, 48">.

24 tests, 33 assertions, 1 failures, 0 errors
rake aborted!
Command failed with status (1): [/usr/bin/ruby18 -I"lib:lib" "/usr/lib64/ru...]

The same happens with Ruby 1.9, the problem is that the exif strings at least here are left unparsed. With which version is mini_magick tsted?

spaces in path result in error

I saw that spaces in the path are not handled properly. I resolved this locally by renaming the path.

however, somewhere should the filename be quoted...

MiniMagic's CommandBuilder doesn't correctly protect paths

Hi, this is similar to the space in the filename issue, but if you look at the following output during processing:

sh: -c: line 0: syntax error near unexpected token `('
sh: -c: line 0: `identify -ping /xxxx/medium_xxxx(new)_title.jpg 2>&1'
/Library/Ruby/Gems/1.8/gems/mini_magick-3.2/lib/mini_magick.rb:360:in `run': Command ("identify -ping /xxxx/medium_xxxx(new)_title.jpg") failed: {:output=>"", :status_code=>2} (MiniMagick::Error)

it seems clear that the CommandBuilder#push method should ensure that arguments are either properly shell protected with quotes or that they're otherwise escaped using some kind of regex processing.

I'm writing something that needs to handle any valid GUI filename - and that includes any kind of messed up character sequences people's UI environments allow in filenames - and then process that with MiniMagick to generate thumbnails, etc.

I've been working around the problem by trying to quote the arguments myself, but I keep finding more places where I've missed them. Any chance of a more fundamental fix to the CommandBuilder?

This isn't a perfect fix, but it's gotten me past my immediate problem:

430     def push(arg)
431       if arg =~ /[\s()\[\]!><&;$]/  
432         arg = "\"#{arg}\""
433       end
434       @args << arg.to_s.strip
435     end
436     alias :<< :push
437   end
438 end
"/Library/Ruby/Gems/1.8/gems/mini_magick-3.2/lib/mini_magick.rb" 438L, 17781C

Great work on MiniMagick. It's been a very useful addition to several projects at this stage! :)

Cheers,

ast

Ruby 1.9.3p0 and mini_magick 3.3

I got a standard attachement_fu setup with rails 2.3.14:

from the model:
:processor => :MiniMagick,
:thumbnails => {
:small => "30x30>",
:medium => "200x200>",
:big => "500x500>"
}

When mini_magick tries to resize my images it throws this error:

Exception working with image: Command ("identify -ping /tmp/["mini_magick", ""]19335-") failed: {:status_code=>1, :output=>"identify: unable to open image /tmp/[mini_magick,': @ error/blob.c/OpenBlob/2489.\nidentify: unable to open image]19335-': @ error/blob.c/OpenBlob/2489.\n"}

I guess it has something to do with this line from lib/mini_magick.rb line 136:

tempfile = Tempfile.new(['mini_magick', ext.to_s.downcase])

RangeError out of char range

Ruby 1.9.2-p136, Rails 3.0.3, ImageMagick 6.6.4-5, mini_magick 3.2.

Any commas in a metadata fields cause this error when being read:

RangeError out of char range

Specifically, I'm trying to read a iPhone photo's Latitude and Longitude. Their EXIF values in identify -verbose look like this:

exif:GPSLatitude: 35/1, 2962/100, 0/1

label in MOGRIFY_COMMANDS & IMAGE_CREATION_OPERATORS

'label' has different behaviors for the different syntaxes. The first is to add the label as meta-data, the second draws it as text on the image. I don't think there is a way to specify use of -label arg or label:arg so it never gets past elsif MOGRIFY_COMMANDS.include?

    def method_missing(symbol, *options)
      guessed_command_name = symbol.to_s.gsub('_','-')
      if guessed_command_name == "format"
        raise Error, "You must call 'format' on the image object directly!"
      elsif MOGRIFY_COMMANDS.include?(guessed_command_name)
        add_command(guessed_command_name, *options)
        self
      elsif IMAGE_CREATION_OPERATORS.include?(guessed_command_name)
        add_creation_operator(guessed_command_name, *options)
        self
      else
        super(symbol, *args)
      end
    end

label arg
http://www.imagemagick.org/script/command-line-options.php#label

label:arg
http://www.imagemagick.org/Usage/text/#label

As far as I can tell, label:arg is the best way to add text that dynamically resizes to dimensions given by -size

Add support for GraphicsMagick

GraphicsMagick is a fork of ImageMagick which has the exact same command line but can be significantly faster for some operations. http://www.graphicsmagick.org/benchmarks.html

You simply prepend "gm" to the command line.

gm convert ...
gm mogrify ...
gm identify ...

I was thinking you could just have a flag to set which enables it, like so:

MiniMagick.use_graphicsmagick = true

and update the run_command method to use it.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.