smartimage 0.0.0-java

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.textile
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,21 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Tony Arcieri
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.textile ADDED
@@ -0,0 +1,11 @@
1
+ h1. SmartImage
2
+
3
+ Hi. There will be a real README here soon, I promise.
4
+
5
+ h2. Credits
6
+
7
+ SmartImage assumes your Ruby interpreter supports the absurdly powerful RMagick
8
+ library, unless you're running JRuby, in which case it uses the absurdly
9
+ powerful Java Graphics2D library and AWT.
10
+
11
+ Mongoose courtesy Wikimedia Commons: http://en.wikipedia.org/wiki/File:Mongoose.jpg
data/Rakefile ADDED
@@ -0,0 +1,74 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "smartimage"
8
+ gem.summary = %Q{It's like a Swiss Army Knife for images, but one of those tiny ones you can keep on your keychain}
9
+ gem.description = <<-EOD
10
+ SmartImage provides a cross-platform solution for image compositing that works on both MRI and JRuby.
11
+ If using RMagick feels like swatting a fly with a nucler missile, and ImageScience just doesn't get
12
+ you there, SmartImage is hopefully at that sweet spot in the middle
13
+ EOD
14
+
15
+ gem.email = "tony@medioh.com"
16
+ gem.homepage = "http://github.com/tarcieri/smartimage"
17
+ gem.authors = ["Tony Arcieri"]
18
+ gem.add_dependency "imagesize", ">= 0.1.1"
19
+ gem.add_dependency "rmagick", ">= 2.12.2"
20
+ gem.add_development_dependency "rspec", ">= 1.2.9"
21
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
22
+ end
23
+ Jeweler::GemcutterTasks.new
24
+ rescue LoadError
25
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
26
+ end
27
+
28
+ require 'spec/rake/spectask'
29
+ Spec::Rake::SpecTask.new(:spec) do |spec|
30
+ spec.libs << 'lib' << 'spec'
31
+ spec.spec_files = FileList['spec/**/*_spec.rb']
32
+ end
33
+
34
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
35
+ spec.libs << 'lib' << 'spec'
36
+ spec.pattern = 'spec/**/*_spec.rb'
37
+ spec.rcov = true
38
+ end
39
+
40
+ task :spec => :check_dependencies
41
+
42
+ task :default => :spec
43
+
44
+ require 'rake/rdoctask'
45
+ Rake::RDocTask.new do |rdoc|
46
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
47
+
48
+ rdoc.rdoc_dir = 'rdoc'
49
+ rdoc.title = "smartimage #{version}"
50
+ rdoc.rdoc_files.include('README*')
51
+ rdoc.rdoc_files.include('lib/**/*.rb')
52
+ end
53
+
54
+ namespace :java do
55
+ desc 'Munge the Jeweler gemspec into a JRuby compatible one'
56
+ task :gemspec => 'rake:gemspec' do
57
+ gemspec = File.read('smartimage.gemspec')
58
+
59
+ # Remove the last end statement
60
+ gemspec.sub!(/end\s*\Z/m, '')
61
+
62
+ # Add the Java platform requirement
63
+ gemspec << " s.platform = %q{java}\n"
64
+
65
+ # Readd the end statement
66
+ gemspec << "end\n"
67
+
68
+ # Remove RMagic dependencies
69
+ gemspec = gemspec.split("\n").reject { |line| line["<rmagick>"] }.join("\n")
70
+
71
+ # Write the Java gemspec
72
+ File.open("smartimage-java.gemspec", "w") { |file| file << gemspec }
73
+ end
74
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.0
@@ -0,0 +1,137 @@
1
+ require 'image_size'
2
+ require 'smart_image/ratio_calculator'
3
+
4
+ # Load the appropriate canvas class for the current environment
5
+ if defined? JRUBY_VERSION
6
+ require 'smart_image/java_canvas'
7
+ else
8
+ require 'smart_image/rmagick_canvas'
9
+ end
10
+
11
+ # SmartImage: it's like a Swiss Army Knife for images, but one of those tiny
12
+ # ones you can keep on your keychain.
13
+ class SmartImage
14
+ # I'm sorry, I couldn't understand the data you gave me
15
+ class FormatError < ArgumentError; end
16
+
17
+ # Struct type containing information about a given image
18
+ class Info < Struct.new(:width, :height, :type); end
19
+
20
+ class << self
21
+ # Obtain basic information about the given image data
22
+ # Returns a SmartImage::Info object
23
+ def info(data)
24
+ img = ImageSize.new data
25
+ raise FormatError, "invalid image" if img.get_type == "OTHER"
26
+
27
+ Info.new(img.width, img.height, img.get_type.downcase.to_sym)
28
+ end
29
+
30
+ # Obtain information about a file
31
+ # Returns a SmartImage::Info object
32
+ def file_info(path)
33
+ info File.read(path)
34
+ end
35
+ end
36
+
37
+ # Create a new SmartImage of the given width and height. Always takes a
38
+ # block... no exceptions! Returns a destroyed SmartImage object.
39
+ #
40
+ # SmartImage.new(400, 300) do |compositor|
41
+ # compositor.image "foo/bar.jpg", :x => 10, :y => 10
42
+ # compositor.text "Hello, world!", :x => 20, :y => 20
43
+ # compositor.write "baz/qux.jpg"
44
+ # end
45
+ #
46
+ # When used with a block, all images are automatically freed from memory
47
+ def initialize(width, height, &block)
48
+ raise ArgumentError, "give me a block, pretty please" unless block_given?
49
+
50
+ @width, @height = Integer(width), Integer(height)
51
+ @canvas = SmartImage::Canvas.new @width, @height
52
+
53
+ yield self
54
+ @canvas.destroy
55
+ @canvas = DeadCanvas.new
56
+ end
57
+
58
+ class DeadCanvas
59
+ def method_missing(*args)
60
+ raise ArgumentError, "your image exists only within the SmartImage.new block"
61
+ end
62
+ end
63
+
64
+ # Composite the given image data onto the SmartImage
65
+ #
66
+ # Accepts the following options:
67
+ #
68
+ # * x: coordinate of the upper left corner of the image (default 0)
69
+ # * y: ditto, it's the y coordinate
70
+ # * width: an alternate width
71
+ # * height: alternate height
72
+ # * preserve_aspect_ratio: should the aspect ratio be preserved? (default: true)
73
+ def composite(data, options = {})
74
+ info = self.class.info data
75
+
76
+ opts = {
77
+ :x => 0,
78
+ :y => 0,
79
+ :width => info.width,
80
+ :height => info.height,
81
+ :preserve_aspect_ratio => true
82
+ }.merge(options)
83
+
84
+ if opts[:preserve_aspect_ratio]
85
+ composited_size = SmartImage::RatioCalculator.new(
86
+ :source_width => info.width,
87
+ :source_height => info.height,
88
+ :dest_width => Integer(opts[:width]),
89
+ :dest_height => Integer(opts[:height])
90
+ ).size
91
+
92
+ dest_width, dest_height = composited_size.width, composited_size.height
93
+ else
94
+ dest_width, dest_height = opts[:width], opts[:height]
95
+ end
96
+
97
+ @canvas.composite data, :width => Integer(dest_width),
98
+ :height => Integer(dest_height),
99
+ :x => opts[:x],
100
+ :y => opts[:y]
101
+ end
102
+
103
+ # Composite a given image file onto the SmartImage. Accepts the same options
104
+ # as the composite method
105
+ def composite_file(file, options = {})
106
+ composite File.read(file), options
107
+ end
108
+
109
+ # Apply an alpha mask from the given image data. Doesn't accept any options
110
+ # right now, sorry. It's just another useless dangling options hash.
111
+ def alpha_mask(data, options = {})
112
+ @canvas.alpha_mask data
113
+ end
114
+
115
+ # Apply an alpha mask from the given file. Accepts the same options as the
116
+ # alpha_mask method.
117
+ def alpha_mask_file(file, options = {})
118
+ alpha_mask File.read(file), options
119
+ end
120
+
121
+ # Encode the image with the given format (a file extension) and return it
122
+ # as a string. Doesn't accept any options at present. The options hash is
123
+ # just there to annoy you and make you wish it had more options.
124
+ def encode(format, options = {})
125
+ # Sorry .jpeg lovers, I'm one of you too but the standard is jpg
126
+ format = :jpg if format.to_s == 'jpeg'
127
+
128
+ @canvas.encode format, options
129
+ end
130
+
131
+ # Write the resulting image out to disk. Picks format based on filename.
132
+ # Takes the same options as encode
133
+ def write(path, options = {})
134
+ format = File.extname(path).sub(/^\./, '')
135
+ File.open(path, 'w') { |file| file << encode(format, options) }
136
+ end
137
+ end
@@ -0,0 +1,46 @@
1
+ class SmartImage
2
+ # Exception thrown for unimplemented features
3
+ class NotImplementedError < StandardError; end
4
+
5
+ # This class defines the set of methods all canvases are expected to implement
6
+ # It also documents the set of methods that should be available for a canvas
7
+ class BaseCanvas
8
+ # Create a new canvas object of the given width and height
9
+ def initialize(width, height)
10
+ raise NotImplementedError, "some silly person forgot to define a constructor"
11
+ end
12
+
13
+ # Destroy the canvas (if you need to)
14
+ def destroy
15
+ not_implemented :destroy
16
+ end
17
+
18
+ # Has the canvas been destroyed already?
19
+ def destroyed?
20
+ not_implemented :destroyed?
21
+ end
22
+
23
+ # Composite another image onto this canvas
24
+ def composite(image_data, width, height, options = {})
25
+ not_implemented :composite
26
+ end
27
+
28
+ # Load the given file as an alpha mask for the image
29
+ def alpha_mask(image_data, options = {})
30
+ not_implemented :alpha_mask
31
+ end
32
+
33
+ # Encode the image to the given format
34
+ def encode(format, options = {})
35
+ not_implemented :encode
36
+ end
37
+
38
+ #######
39
+ private
40
+ #######
41
+
42
+ def not_implemented(meth)
43
+ raise NotImplementedError, "#{meth} not implemented by #{self.class.inspect}"
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,74 @@
1
+ require 'smart_image/base_canvas'
2
+
3
+ class SmartImage
4
+ # Canvas object backed by Java Graphics2D
5
+ class JavaCanvas < BaseCanvas
6
+ java_import java.awt.image.BufferedImage
7
+ java_import javax.imageio.ImageIO
8
+ java_import java.io.ByteArrayInputStream
9
+ java_import java.io.ByteArrayOutputStream
10
+
11
+ def initialize(width, height)
12
+ @canvas = BufferedImage.new width, height, BufferedImage::TYPE_INT_ARGB
13
+ end
14
+
15
+ # Stub out destroy since Java actually garbage collects crap, unlike... C
16
+ def destroy
17
+ end
18
+
19
+ # Composite the given image data onto the canvas
20
+ def composite(image_data, options = {})
21
+ info = SmartImage.info image_data
22
+ opts = {
23
+ :width => info.width,
24
+ :height => info.height,
25
+ :x => 0,
26
+ :y => 0
27
+ }.merge(options)
28
+
29
+ input_stream = ByteArrayInputStream.new image_data.to_java_bytes
30
+ image = ImageIO.read input_stream
31
+ raise FormatError, "invalid image" unless image
32
+
33
+ graphics = @canvas.graphics
34
+ graphics.draw_image image, opts[:x], opts[:y], opts[:width], opts[:height], nil
35
+ end
36
+
37
+ # Load the given file as an alpha mask for the image
38
+ def alpha_mask(image_data, options = {})
39
+ input_stream = ByteArrayInputStream.new image_data.to_java_bytes
40
+ mask = ImageIO.read input_stream
41
+
42
+ width = mask.width
43
+ image_data, mask_data = Java::int[width].new, Java::int[width].new
44
+
45
+ mask.height.times do |y|
46
+ # fetch a line of data from each image
47
+ @canvas.get_rgb 0, y, width, 1, image_data, 0, 1
48
+ mask.get_rgb 0, y, width, 1, mask_data, 0, 1
49
+
50
+ width.times do |x|
51
+ # mask away the alpha
52
+ color = image_data[x] & 0x00FFFFFF
53
+
54
+ # turn red from the mask into alpha
55
+ alpha = (mask_data[x] & 0x00FF0000) << 8
56
+
57
+ image_data[x] = color | alpha
58
+ end
59
+
60
+ @canvas.set_rgb 0, y, width, 1, image_data, 0, 1
61
+ end
62
+ end
63
+
64
+ # Encode the image to the given format
65
+ def encode(format, options = {})
66
+ output_stream = ByteArrayOutputStream.new
67
+ ImageIO.write(@canvas, format.to_s, output_stream)
68
+ String.from_java_bytes output_stream.to_byte_array
69
+ end
70
+ end
71
+
72
+ # Java is our Canvas on Java, duh!
73
+ Canvas = JavaCanvas
74
+ end
@@ -0,0 +1,42 @@
1
+ class SmartImage
2
+ class RatioCalculator
3
+ # Create a new RatioCalculator object with the given options
4
+ def initialize(options = {})
5
+ @options = options
6
+ end
7
+
8
+ # Calculate the resulting size given a particular set of contraints
9
+ def size(options = {})
10
+ opts = @options.merge(options)
11
+
12
+ source = Size.new opts[:source_width], opts[:source_height]
13
+ bounds = Size.new opts[:dest_width], opts[:dest_height]
14
+
15
+ # Calculate what the width would be if we matched the dest height
16
+ naive_width = bounds.height * source.aspect_ratio
17
+
18
+ # If it fits, use it!
19
+ if naive_width <= bounds.width
20
+ width = naive_width
21
+ height = naive_width / source.aspect_ratio
22
+ # Otherwise, the height must fit
23
+ else
24
+ height = bounds.width / source.aspect_ratio
25
+ width = height * source.aspect_ratio
26
+ end
27
+
28
+ return Size.new(width, height)
29
+ end
30
+
31
+ #
32
+ # Struct to hold the resulting size and compute aspect ratios
33
+ #
34
+ class Size < Struct.new(:width, :height, :aspect_ratio)
35
+ def initialize(width, height)
36
+ width, height = Integer(width), Integer(height)
37
+ aspect_ratio = width.to_f / height
38
+ super(width, height, aspect_ratio)
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,57 @@
1
+ require 'RMagick'
2
+ require 'smart_image/base_canvas'
3
+
4
+ class SmartImage
5
+ # Canvas object, backed by RMagick
6
+ class RMagickCanvas < BaseCanvas
7
+ include Magick
8
+
9
+ def initialize(width, height)
10
+ @canvas = Image.new width, height do
11
+ self.background_color = "transparent"
12
+ end
13
+ end
14
+
15
+ def destroy
16
+ @canvas.destroy!
17
+ end
18
+
19
+ def composite(image_data, options = {})
20
+ image = ImageList.new
21
+ image.from_blob image_data
22
+
23
+ opts = {
24
+ :width => image.columns,
25
+ :height => image.rows,
26
+ :x => 0,
27
+ :y => 0
28
+ }.merge(options)
29
+
30
+ image.thumbnail! opts[:width], opts[:height]
31
+ @canvas.composite! image, opts[:x], opts[:y], OverCompositeOp
32
+ ensure
33
+ image.destroy!
34
+ end
35
+
36
+ # Load the given file as an alpha mask for the image
37
+ def alpha_mask(image_data, options = {})
38
+ mask = ImageList.new
39
+ mask.from_blob image_data
40
+
41
+ # Disable this image's alpha channel to use the opacity data as a mask
42
+ mask.matte = false
43
+ @canvas.composite! mask, NorthWestGravity, CopyOpacityCompositeOp
44
+ ensure
45
+ mask.destroy!
46
+ end
47
+
48
+ # Encode this image into the given format (as a file extension)
49
+ def encode(format, options = {})
50
+ @canvas.format = format.to_s.upcase
51
+ @canvas.to_blob
52
+ end
53
+ end
54
+
55
+ # RMagick is our Canvas on everything besides JRuby. Hope it works for you!
56
+ Canvas = RMagickCanvas
57
+ end
@@ -0,0 +1,71 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{smartimage}
8
+ s.version = "0.0.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Tony Arcieri"]
12
+ s.date = %q{2010-03-26}
13
+ s.description = %q{ SmartImage provides a cross-platform solution for image compositing that works on both MRI and JRuby.
14
+ If using RMagick feels like swatting a fly with a nucler missile, and ImageScience just doesn't get
15
+ you there, SmartImage is hopefully at that sweet spot in the middle
16
+ }
17
+ s.email = %q{tony@medioh.com}
18
+ s.extra_rdoc_files = [
19
+ "LICENSE",
20
+ "README.textile"
21
+ ]
22
+ s.files = [
23
+ ".document",
24
+ ".gitignore",
25
+ "LICENSE",
26
+ "README.textile",
27
+ "Rakefile",
28
+ "VERSION",
29
+ "lib/smart_image.rb",
30
+ "lib/smart_image/base_canvas.rb",
31
+ "lib/smart_image/java_canvas.rb",
32
+ "lib/smart_image/ratio_calculator.rb",
33
+ "lib/smart_image/rmagick_canvas.rb",
34
+ "smartimage.gemspec",
35
+ "spec/fixtures/mask.png",
36
+ "spec/fixtures/mongoose.jpg",
37
+ "spec/smart_image_spec.rb",
38
+ "spec/spec.opts",
39
+ "spec/spec_helper.rb",
40
+ "spec/tmp/.gitignore"
41
+ ]
42
+ s.homepage = %q{http://github.com/tarcieri/smartimage}
43
+ s.rdoc_options = ["--charset=UTF-8"]
44
+ s.require_paths = ["lib"]
45
+ s.rubygems_version = %q{1.3.5}
46
+ s.summary = %q{It's like a Swiss Army Knife for images, but one of those tiny ones you can keep on your keychain}
47
+ s.test_files = [
48
+ "spec/smart_image_spec.rb",
49
+ "spec/spec_helper.rb"
50
+ ]
51
+
52
+ if s.respond_to? :specification_version then
53
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
54
+ s.specification_version = 3
55
+
56
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
57
+ s.add_runtime_dependency(%q<imagesize>, [">= 0.1.1"])
58
+ s.add_runtime_dependency(%q<rmagick>, [">= 2.12.2"])
59
+ s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
60
+ else
61
+ s.add_dependency(%q<imagesize>, [">= 0.1.1"])
62
+ s.add_dependency(%q<rmagick>, [">= 2.12.2"])
63
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
64
+ end
65
+ else
66
+ s.add_dependency(%q<imagesize>, [">= 0.1.1"])
67
+ s.add_dependency(%q<rmagick>, [">= 2.12.2"])
68
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
69
+ end
70
+ end
71
+
Binary file
Binary file
@@ -0,0 +1,44 @@
1
+ SPEC_DIR = File.dirname(__FILE__)
2
+ require SPEC_DIR + '/spec_helper'
3
+
4
+ describe SmartImage do
5
+ before :all do
6
+ @mongoose = SPEC_DIR + '/fixtures/mongoose.jpg'
7
+ @mask = SPEC_DIR + '/fixtures/mask.png'
8
+ @output_dir = SPEC_DIR + '/tmp/'
9
+ end
10
+
11
+ it "obtains image information" do
12
+ info = SmartImage.file_info(@mongoose)
13
+
14
+ info.type.should == :jpeg
15
+ info.width.should == 1327
16
+ info.height.should == 1260
17
+ end
18
+
19
+ it "composites images" do
20
+ SmartImage.new(800, 400) do |image|
21
+ image.composite_file @mongoose, :y => 15
22
+ image.write @output_dir + 'composited.png'
23
+ end
24
+ end
25
+
26
+ it "scales when compositing" do
27
+ SmartImage.new(800, 400) do |image|
28
+ image.composite_file @mongoose, :y => 15
29
+ image.composite_file @mongoose, :x => 100, :y => 30, :width => 250, :height => 100
30
+ image.write @output_dir + 'scaled.png'
31
+ end
32
+ end
33
+
34
+ it "alpha masks images" do
35
+ SmartImage.new(115, 95) do |image|
36
+ image.composite_file @mongoose, :width => 115,
37
+ :height => 95,
38
+ :preserve_aspect_ratio => false
39
+
40
+ image.alpha_mask_file @mask
41
+ image.write @output_dir + 'alpha_mask.png'
42
+ end
43
+ end
44
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,5 @@
1
+ # We depend on the ImageSize gem, at the very least
2
+ require 'rubygems'
3
+
4
+ $LOAD_PATH << File.dirname(__FILE__) + '/../lib'
5
+ require 'smart_image'
metadata ADDED
@@ -0,0 +1,93 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: smartimage
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0
5
+ platform: java
6
+ authors:
7
+ - Tony Arcieri
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-03-26 00:00:00 -06:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: imagesize
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 0.1.1
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: rspec
27
+ type: :development
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 1.2.9
34
+ version:
35
+ description: " SmartImage provides a cross-platform solution for image compositing that works on both MRI and JRuby.\n If using RMagick feels like swatting a fly with a nucler missile, and ImageScience just doesn't get \n you there, SmartImage is hopefully at that sweet spot in the middle\n"
36
+ email: tony@medioh.com
37
+ executables: []
38
+
39
+ extensions: []
40
+
41
+ extra_rdoc_files:
42
+ - LICENSE
43
+ - README.textile
44
+ files:
45
+ - .document
46
+ - .gitignore
47
+ - LICENSE
48
+ - README.textile
49
+ - Rakefile
50
+ - VERSION
51
+ - lib/smart_image.rb
52
+ - lib/smart_image/base_canvas.rb
53
+ - lib/smart_image/java_canvas.rb
54
+ - lib/smart_image/ratio_calculator.rb
55
+ - lib/smart_image/rmagick_canvas.rb
56
+ - smartimage.gemspec
57
+ - spec/fixtures/mask.png
58
+ - spec/fixtures/mongoose.jpg
59
+ - spec/smart_image_spec.rb
60
+ - spec/spec.opts
61
+ - spec/spec_helper.rb
62
+ - spec/tmp/.gitignore
63
+ has_rdoc: true
64
+ homepage: http://github.com/tarcieri/smartimage
65
+ licenses: []
66
+
67
+ post_install_message:
68
+ rdoc_options:
69
+ - --charset=UTF-8
70
+ require_paths:
71
+ - lib
72
+ required_ruby_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: "0"
77
+ version:
78
+ required_rubygems_version: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: "0"
83
+ version:
84
+ requirements: []
85
+
86
+ rubyforge_project:
87
+ rubygems_version: 1.3.5
88
+ signing_key:
89
+ specification_version: 3
90
+ summary: It's like a Swiss Army Knife for images, but one of those tiny ones you can keep on your keychain
91
+ test_files:
92
+ - spec/smart_image_spec.rb
93
+ - spec/spec_helper.rb