Skip to content

Commit

Permalink
merge
Browse files Browse the repository at this point in the history
  • Loading branch information
HamptonMakes committed Dec 28, 2011
2 parents a3db09d + 45bb993 commit 2d1cdee
Show file tree
Hide file tree
Showing 20 changed files with 116 additions and 46 deletions.
3 changes: 3 additions & 0 deletions .gitignore
@@ -1,3 +1,6 @@
/pkg
coverage
*.lock
.idea
.yardoc
.rvmrc
2 changes: 2 additions & 0 deletions CHANGELOG
@@ -1,3 +1,5 @@
* Dec 28, 2011 - Releasing v3.4 - New subexec version requirement and included previous fixes
* Dec 21, 2011 - Refactored gem structure a little and added a few bug fixes to better support Windows users - No changes to API though [2potatocakes]
* June 2, 2011 - Releasing v3.3 - A lot more bugfixes, plus a few new features (like better mime_type accessing) [hcatlin]
* Jan 11, 2011 - Releasing v3.2 - Bugfix release. Some small changes to the API in very rare circumstances. Mostly having to do with passing multiple arguments to format options. Also, you can now query an image's "colorspace". [hcatlin]
* October 28, 2010 - Releasing v3.0. Some small bugfixes. This is 3.0 because of the big interface changes and they are fairly stable from before. [hcatlin]
Expand Down
2 changes: 1 addition & 1 deletion Gemfile
@@ -1,3 +1,3 @@
source :rubygems
gem "rake"
gemspec
gem "rake"
19 changes: 19 additions & 0 deletions README.rdoc
Expand Up @@ -83,10 +83,29 @@ Want to get some meta-information out?
image["EXIF:BitsPerSample"] # It also can get all the EXIF tags
image["%m:%f %wx%h"] # Or you can use one of the many options of the format command

Want to use an internal image creation to create a big black square?

image = MiniMagick::Image.create 'jpg', false do |c|
c.size '1024x1024' # creates image option '-size 1024x1024'
c.canvas 'black' # creates image creation operator 'canvas:black'
end

For more on the format command see
http://www.imagemagick.org/script/command-line-options.php#format


== Windows Users

When passing in a blob or IOStream, Windows users need to make sure they read the file in as binary.

#This way works on Windows
buffer = StringIO.new(File.open(IMAGE_PATH,"rb") { |f| f.read })
MiniMagick::Image.read(buffer)

#You may run into problems doing it this way
buffer = StringIO.new(File.read(IMAGE_PATH))


== Using GraphicsMagick

Simply set
Expand Down
3 changes: 1 addition & 2 deletions Rakefile
Expand Up @@ -9,8 +9,7 @@ rescue LoadError
end
require 'rubygems/package_task'

$:.unshift(File.dirname(__FILE__) + "/lib")
require 'mini_magick'
$:.unshift 'lib'

desc 'Default: run unit tests.'
task :default => [:print_version, :test]
Expand Down
41 changes: 32 additions & 9 deletions lib/mini_magick.rb
Expand Up @@ -34,7 +34,9 @@ def valid_version_installed?
end
end

MOGRIFY_COMMANDS = %w{adaptive-blur adaptive-resize adaptive-sharpen adjoin affine alpha annotate antialias append authenticate auto-gamma auto-level auto-orient background bench iterations bias black-threshold blue-primary point blue-shift factor blur border bordercolor brightness-contrast caption string cdl filename channel type charcoal radius chop clip clamp clip-mask filename clip-path id clone index clut contrast-stretch coalesce colorize color-matrix colors colorspace type combine comment string compose operator composite compress type contrast convolve coefficients crop cycle amount decipher filename debug events define format:option deconstruct delay delete index density depth despeckle direction type display server dispose method distort type coefficients dither method draw string edge radius emboss radius encipher filename encoding type endian type enhance equalize evaluate operator evaluate-sequence operator extent extract family name fft fill filter type flatten flip floodfill flop font name format string frame function name fuzz distance fx expression gamma gaussian-blur geometry gravity type green-primary point help identify ifft implode amount insert index intent type interlace type interline-spacing interpolate method interword-spacing kerning label string lat layers method level limit type linear-stretch liquid-rescale log format loop iterations mask filename mattecolor median radius modulate monitor monochrome morph morphology method kernel motion-blur negate noise radius normalize opaque ordered-dither NxN orient type page paint radius ping pointsize polaroid angle posterize levels precision preview type print string process image-filter profile filename quality quantize quiet radial-blur angle raise random-threshold low,high red-primary point regard-warnings region remap filename render repage resample resize respect-parentheses roll rotate degrees sample sampling-factor scale scene seed segments selective-blur separate sepia-tone threshold set attribute shade degrees shadow sharpen shave shear sigmoidal-contrast size sketch solarize threshold splice spread radius strip stroke strokewidth stretch type style type swap indexes swirl degrees texture filename threshold thumbnail tile filename tile-offset tint transform transparent transparent-color transpose transverse treedepth trim type type undercolor unique-colors units type unsharp verbose version view vignette virtual-pixel method wave weight type white-point point white-threshold write filename}
MOGRIFY_COMMANDS = %w{adaptive-blur adaptive-resize adaptive-sharpen adjoin affine alpha annotate antialias append authenticate auto-gamma auto-level auto-orient background bench iterations bias black-threshold blue-primary point blue-shift factor blur border bordercolor brightness-contrast caption string cdl filename channel type charcoal radius chop clip clamp clip-mask filename clip-path id clone index clut contrast-stretch coalesce colorize color-matrix colors colorspace type combine comment string compose operator composite compress type contrast convolve coefficients crop cycle amount decipher filename debug events define format:option deconstruct delay delete index density depth despeckle direction type dissolve display server dispose method distort type coefficients dither method draw string edge radius emboss radius encipher filename encoding type endian type enhance equalize evaluate operator evaluate-sequence operator extent extract family name fft fill filter type flatten flip floodfill flop font name format string frame function name fuzz distance fx expression gamma gaussian-blur geometry gravity type green-primary point help identify ifft implode amount insert index intent type interlace type interline-spacing interpolate method interword-spacing kerning label string lat layers method level limit type linear-stretch liquid-rescale log format loop iterations mask filename mattecolor median radius modulate monitor monochrome morph morphology method kernel motion-blur negate noise radius normalize opaque ordered-dither NxN orient type page paint radius ping pointsize polaroid angle posterize levels precision preview type print string process image-filter profile filename quality quantize quiet radial-blur angle raise random-threshold low,high red-primary point regard-warnings region remap filename render repage resample resize respect-parentheses roll rotate degrees sample sampling-factor scale scene seed segments selective-blur separate sepia-tone threshold set attribute shade degrees shadow sharpen shave shear sigmoidal-contrast size sketch solarize threshold splice spread radius strip stroke strokewidth stretch type style type swap indexes swirl degrees texture filename threshold thumbnail tile filename tile-offset tint transform transparent transparent-color transpose transverse treedepth trim type type undercolor unique-colors units type unsharp verbose version view vignette virtual-pixel method wave weight type white-point point white-threshold write filename}

IMAGE_CREATION_OPERATORS = %w{canvas caption gradient label logo pattern plasma radial radient rose text tile xc }

class Error < RuntimeError; end
class Invalid < StandardError; end
Expand All @@ -60,6 +62,12 @@ class << self
def read(stream, ext = nil)
if stream.is_a?(String)
stream = StringIO.new(stream)
elsif stream.is_a?(File)
if File.respond_to?(:binread)
stream = StringIO.new File.binread(stream.path.to_s)
else
stream = StringIO.new File.open(stream.path.to_s,"rb") { |f| f.read }
end
end

create(ext) do |f|
Expand Down Expand Up @@ -321,13 +329,13 @@ def to_blob
ensure
f.close if f
end

def mime_type
format = self[:format]
"image/"+format.downcase
"image/" + format.to_s.downcase
end

# If an unknown method is called then it is sent through the morgrify program
# If an unknown method is called then it is sent through the mogrify program
# Look here to find all the commands (http://www.imagemagick.org/script/mogrify.php)
def method_missing(symbol, *args)
combine_options do |c|
Expand All @@ -345,16 +353,18 @@ def method_missing(symbol, *args)
# end
#
# @yieldparam command [CommandBuilder]
def combine_options(&block)
c = CommandBuilder.new('mogrify')
def combine_options(tool = :mogrify, &block)
c = CommandBuilder.new(tool || :mogrify)

c << @path if tool == :convert
block.call(c)
c << @path
run(c)
end

# Check to see if we are running on win32 -- we need to escape things differently
def windows?
!(RUBY_PLATFORM =~ /win32|mswin|mingw/).nil?
RUBY_PLATFORM =~ /mswin|mingw|cygwin/
end

def composite(other_image, output_extension = 'jpg', &block)
Expand Down Expand Up @@ -448,7 +458,10 @@ def method_missing(symbol, *options)
if guessed_command_name == "format"
raise Error, "You must call 'format' on the image object directly!"
elsif MOGRIFY_COMMANDS.include?(guessed_command_name)
add(guessed_command_name, *options)
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)
Expand All @@ -464,7 +477,7 @@ def +(*options)
end
end

def add(command, *options)
def add_command(command, *options)
push "-#{command}"
if options.any?
options.each do |o|
Expand All @@ -477,6 +490,16 @@ def escape_string(value)
'"' + value + '"'
end

def add_creation_operator(command, *options)
creation_command = command
if options.any?
options.each do |option|
creation_command << ":#{option}"
end
end
push creation_command
end

def push(arg)
@args << arg.to_s.strip
end
Expand Down
12 changes: 9 additions & 3 deletions mini_magick.gemspec
@@ -1,7 +1,10 @@
# -*- encoding: utf-8 -*-
$:.push File.expand_path("../lib", __FILE__)

version = File.read("VERSION").strip

Gem::Specification.new do |s|
s.name = 'mini_magick'
s.name = "mini_magick"
s.version = version
s.platform = Gem::Platform::RUBY
s.summary = "Manipulate images with minimal use of memory via ImageMagick / GraphicsMagick"
Expand All @@ -13,7 +16,10 @@ Gem::Specification.new do |s|

s.files = Dir['README.rdoc', 'VERSION', 'MIT-LICENSE', 'Rakefile', 'lib/**/*']
s.test_files = Dir['test/**/*']
s.require_path = 'lib'

s.require_paths = ["lib"]
s.add_runtime_dependency('subexec', ['~> 0.2.1'])

s.add_development_dependency('rake')
s.add_development_dependency('test-unit')

end
10 changes: 7 additions & 3 deletions test/command_builder_test.rb
@@ -1,6 +1,4 @@
require 'rubygems'
require 'test/unit'
require File.expand_path('../../lib/mini_magick', __FILE__)
require 'test_helper'

class CommandBuilderTest < Test::Unit::TestCase
include MiniMagick
Expand Down Expand Up @@ -40,4 +38,10 @@ def test_dashed
c.auto_orient
assert_equal "-auto-orient", c.args.join(" ")
end

def test_canvas
c = CommandBuilder.new('test')
c.canvas 'black'
assert_equal "canvas:black", c.args.join
end
end
File renamed without changes
File renamed without changes
File renamed without changes
Binary file added test/files/leaves (spaced).tiff
Binary file not shown.
File renamed without changes.
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
Binary file added test/files/trogdor_capitalized.JPG
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
50 changes: 22 additions & 28 deletions test/image_test.rb
@@ -1,24 +1,10 @@
require 'rubygems'
require 'test/unit'
require 'pathname'
require File.expand_path('../../lib/mini_magick', __FILE__)
require 'test_helper'

#MiniMagick.processor = :gm

class ImageTest < Test::Unit::TestCase
include MiniMagick

CURRENT_DIR = File.dirname(File.expand_path(__FILE__)) + "/"

SIMPLE_IMAGE_PATH = CURRENT_DIR + "simple.gif"
MINUS_IMAGE_PATH = CURRENT_DIR + "simple-minus.gif"
TIFF_IMAGE_PATH = CURRENT_DIR + "leaves (spaced).tiff"
NOT_AN_IMAGE_PATH = CURRENT_DIR + "not_an_image.php"
GIF_WITH_JPG_EXT = CURRENT_DIR + "actually_a_gif.jpg"
EXIF_IMAGE_PATH = CURRENT_DIR + "trogdor.jpg"
CAP_EXT_PATH = CURRENT_DIR + "trogdor_capitalized.JPG"
ANIMATION_PATH = CURRENT_DIR + "animation.gif"
PNG_PATH = CURRENT_DIR + "png.png"
include MiniMagickTestFiles

def test_image_from_blob
File.open(SIMPLE_IMAGE_PATH, "rb") do |f|
Expand All @@ -35,15 +21,17 @@ def test_image_open
end

def test_image_io_reading
buffer = StringIO.new(File.read(SIMPLE_IMAGE_PATH))
# buffer = StringIO.new(File.read(SIMPLE_IMAGE_PATH)) #This way does not work properly on windows
buffer = StringIO.new File.open(SIMPLE_IMAGE_PATH,"rb") { |f| f.read } #This way works the same on all platforms
image = Image.read(buffer)
assert image.valid?
image.destroy!
end

def test_image_create
image = Image.create do |f|
f.write(File.read(SIMPLE_IMAGE_PATH))
#Had to replace the old File.read with the following to work across all platforms
f.write(File.open(SIMPLE_IMAGE_PATH,"rb") { |f| f.read })
end
image.destroy!
end
Expand Down Expand Up @@ -99,7 +87,7 @@ def test_image_write_with_space_in_output_path
def test_image_write_with_stream
stream = StringIO.new
image = Image.open(SIMPLE_IMAGE_PATH)
image.write("/tmp/foo.gif")
image.write("#{Dir.tmpdir}/foo.gif")
image.write(stream)
# assert Image.read(stream.string).valid?
image.destroy!
Expand All @@ -111,7 +99,7 @@ def test_not_an_image
image.destroy!
end

def test_throw_on_openining_not_an_image
def test_throw_on_opening_not_an_image
assert_raise(MiniMagick::Invalid) do
image = Image.open(NOT_AN_IMAGE_PATH)
image.destroy
Expand All @@ -130,15 +118,15 @@ def test_image_meta_info

def test_tiff
image = Image.new(TIFF_IMAGE_PATH)
assert_equal "tiff", image[:format].downcase
assert_equal "tiff", image[:format].to_s.downcase
assert_equal 50, image[:width]
assert_equal 41, image[:height]
image.destroy!
end

def test_gif_with_jpg_format
image = Image.new(GIF_WITH_JPG_EXT)
assert_equal "gif", image[:format].downcase
assert_equal "gif", image[:format].to_s.downcase
image.destroy!
end

Expand Down Expand Up @@ -247,6 +235,12 @@ def test_simple_composite
else
puts "Need at least version #{MiniMagick.minimum_image_magick_version} of ImageMagick"
end
#TODO - need to write test that works cross platform
#I thought the following would work but there is a 4 byte difference between the files.
#Not sure if it's caused from this test breaking for the right reason though..
#assert File.identical?(result.path, COMP_IMAGE_PATH)
#This following test will only work on Linux
assert `diff -s #{result.path} #{COMP_IMAGE_PATH}`.include?("identical") unless RUBY_PLATFORM =~ /mswin|mingw|cygwin/
end

# http://github.com/probablycorey/mini_magick/issues#issue/8
Expand Down Expand Up @@ -276,7 +270,7 @@ def test_nonstandard_locale
ENV["LANG"] = "fr_FR.UTF-8"

# This test should break
test_throw_on_openining_not_an_image
test_throw_on_opening_not_an_image
ensure
ENV["LANG"] = original_lang
end
Expand All @@ -286,7 +280,7 @@ def test_poop
img.gravity "Center"
img.crop "480x480"
img.resize "250x250"
img.write "/tmp/output.png"
img.write "#{Dir.tmpdir}/output.png"
end

def test_throw_format_error
Expand All @@ -308,10 +302,10 @@ def test_import_pixels_default_format
blob = pixels.pack("S*") # unsigned short, native byte order
image = Image.import_pixels(blob, columns, rows, depth, map)
assert image.valid?
assert_equal "png", image[:format].downcase
assert_equal "png", image[:format].to_s.downcase
assert_equal columns, image[:width]
assert_equal rows, image[:height]
image.write("/tmp/imported_pixels_image.png")
image.write("#{Dir.tmpdir}/imported_pixels_image.png")
end

def test_import_pixels_custom_format
Expand All @@ -324,10 +318,10 @@ def test_import_pixels_custom_format
blob = pixels.pack("S*") # unsigned short, native byte order
image = Image.import_pixels(blob, columns, rows, depth, map, format)
assert image.valid?
assert_equal format, image[:format].downcase
assert_equal format, image[:format].to_s.downcase
assert_equal columns, image[:width]
assert_equal rows, image[:height]
image.write("/tmp/imported_pixels_image." + format)
image.write("#{Dir.tmpdir}/imported_pixels_image." + format)
end

def test_mime_type
Expand Down
20 changes: 20 additions & 0 deletions test/test_helper.rb
@@ -0,0 +1,20 @@
require 'rubygems'
require 'test/unit'
require 'pathname'
require 'tempfile'
require File.expand_path('../../lib/mini_magick', __FILE__)


module MiniMagickTestFiles
test_files = File.expand_path(File.dirname(__FILE__) + "/files")
SIMPLE_IMAGE_PATH = test_files + "/simple.gif"
MINUS_IMAGE_PATH = test_files + "/simple-minus.gif"
TIFF_IMAGE_PATH = test_files + "/leaves (spaced).tiff"
NOT_AN_IMAGE_PATH = test_files + "/not_an_image.php"
GIF_WITH_JPG_EXT = test_files + "/actually_a_gif.jpg"
EXIF_IMAGE_PATH = test_files + "/trogdor.jpg"
CAP_EXT_PATH = test_files + "/trogdor_capitalized.JPG"
ANIMATION_PATH = test_files + "/animation.gif"
PNG_PATH = test_files + "/png.png"
COMP_IMAGE_PATH = test_files + "/composited.jpg"
end

0 comments on commit 2d1cdee

Please sign in to comment.