image_voodoo 0.1

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 Thomas E Enebo <enebo@acm.org>
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/Manifest.txt ADDED
@@ -0,0 +1,17 @@
1
+ bin/image_voodoo
2
+ Manifest.txt
3
+ Rakefile
4
+ README.txt
5
+ LICENSE.txt
6
+ lib/image_science.rb
7
+ lib/image_voodoo
8
+ lib/image_voodoo/version.rb
9
+ lib/image_voodoo.rb
10
+ samples/bench.rb
11
+ samples/checkerboard.jpg
12
+ samples/file_greyscale.rb
13
+ samples/file_thumbnail.rb
14
+ samples/file_view.rb
15
+ samples/in-memory.rb
16
+ test/pix.png
17
+ test/test_image_science.rb
data/README.txt ADDED
@@ -0,0 +1,34 @@
1
+ = ImageVoodoo
2
+
3
+ == DESCRIPTION:
4
+
5
+ ImageVoodoo is an Image manipulation library with a ImageScience-compatible API for
6
+ JRuby.
7
+
8
+ http://jruby-extras.rubyforge.org/image_voodoo/
9
+
10
+ == FEATURES/PROBLEMS:
11
+
12
+ * Uses java.awt and javax.image APIs native to Java to perform image manipulation; no other dependencies needed.
13
+ * Includes image_voodoo command-line utility for quick resizing of images, "image_voodoo --help" for usage.
14
+
15
+ == SYNOPSIS:
16
+
17
+ ImageVoodoo.with_image(ARGV[0]) do |img|
18
+ img.cropped_thumbnail(100) { |img2| img2.save "CTH.jpg" }
19
+ img.with_crop(100, 200, 400, 600) { |img2| img2.save "CR.jpg" }
20
+ img.thumbnail(50) { |img2| img2.save "TH.jpg" }
21
+ img.resize(100, 150) do |img2|
22
+ img2.save "HEH.jpg"
23
+ img2.save "HEH.png"
24
+ end
25
+ end
26
+
27
+
28
+ == REQUIREMENTS:
29
+
30
+ * JRuby
31
+
32
+ == INSTALL:
33
+
34
+ * jruby -S gem install image_voodoo
data/Rakefile ADDED
@@ -0,0 +1,27 @@
1
+ MANIFEST = FileList["bin/*", "Manifest.txt", "Rakefile", "README.txt", "LICENSE.txt", "lib/**/*", "samples/*","test/**/*"]
2
+
3
+ file "Manifest.txt" => :manifest
4
+ task :manifest do
5
+ File.open("Manifest.txt", "w") {|f| MANIFEST.each {|n| f << "#{n}\n"} }
6
+ end
7
+ Rake::Task['manifest'].invoke # Always regen manifest, so Hoe has up-to-date list of files
8
+
9
+ $LOAD_PATH << 'lib'
10
+ require 'image_voodoo/version'
11
+ begin
12
+ require 'hoe'
13
+ Hoe.new("image_voodoo", ImageVoodoo::VERSION) do |p|
14
+ p.rubyforge_name = "jruby-extras"
15
+ p.url = "http://jruby-extras.rubyforge.org/image_voodoo"
16
+ p.author = "Thomas Enebo, Charles Nutter and JRuby contributors"
17
+ p.email = "enebo@acm.org, headius@headius.com"
18
+ p.summary = "Image manipulation in JRuby with ImageScience compatible API"
19
+ p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
20
+ p.description = "Install this gem and require 'image_voodoo' to load the library."
21
+ end.spec.dependencies.delete_if { |dep| dep.name == "hoe" }
22
+ rescue LoadError
23
+ puts "You need Hoe installed to be able to package this gem"
24
+ rescue => e
25
+ p e.backtrace
26
+ puts "ignoring error while loading hoe: #{e.to_s}"
27
+ end
data/bin/image_voodoo ADDED
@@ -0,0 +1,89 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'optparse'
4
+
5
+ actions = []
6
+ images = []
7
+ original_image = nil
8
+
9
+ opts = OptionParser.new do |opts|
10
+ opts.banner = "Usage: image_voodoo [actions] image_file"
11
+ opts.separator "Perform some actions on a source image."
12
+
13
+ opts.separator ""
14
+ opts.separator "Actions are meant to be chained. Examples:"
15
+ opts.separator " # Print the dimensions"
16
+ opts.separator " image_voodoo --dim small.jpg"
17
+ opts.separator ""
18
+ opts.separator " # Convert to a thumbnail, preview, and then save the result"
19
+ opts.separator " image_voodoo --thumb 50 --preview --save thumb.png large.jpg"
20
+ opts.separator ""
21
+ opts.separator " # Convert source to 3 thumbnails, showing dimensions and"
22
+ opts.separator " # previewing along the way"
23
+ opts.separator " image_voodoo --dim --resize 50x50 --dim --preview --save t1.jpg"
24
+ opts.separator " --pop --resize 40x40 --dim --preview --save t2.jpg"
25
+ opts.separator " --pop --resize 30x30 --dim --preview --save t3.jpg image.jpg"
26
+
27
+ opts.separator ""
28
+ opts.separator "Actions:"
29
+
30
+ opts.on("-d", "--dimensions", "Print the image dimensions") do
31
+ actions << lambda {|img| puts "#{img.width}x#{img.height}"; img }
32
+ end
33
+
34
+ opts.on("-s", "--save FILENAME", "Save the results to a new file") do |f|
35
+ actions << lambda {|img| img.save(f); img }
36
+ end
37
+
38
+ opts.on("-t", "--thumbnail SIZE", Integer, "Create a thumbnail of the given size") do |size|
39
+ actions << lambda {|img| result = nil; img.thumbnail(size) {|img2| result = img2 }; result }
40
+ end
41
+
42
+ opts.on("-p", "--preview", "Preview the image. Close the frame window",
43
+ "to continue, or quit the application to", "abort the action pipeline") do
44
+ actions << lambda do |img|
45
+ done = false
46
+ img.preview { done = true }
47
+ Thread.pass until done
48
+ img
49
+ end
50
+ end
51
+
52
+ opts.on("--push", "Save the current image to be popped later") do
53
+ actions << lambda {|img| images << img; img }
54
+ end
55
+
56
+ opts.on("--pop", "Revert back to the previous saved image", "or the original source image") do
57
+ actions << lambda {|img| images.pop || original_image }
58
+ end
59
+
60
+ opts.on("-r", "--resize WIDTHxHEIGHT", "Create a new image with the specified", "dimensions") do |dim|
61
+ width, height = dim.split(/x/i).map {|v| v.to_i}
62
+ opts.usage "You need to specify proper dimensions" unless width && width > 0 && height && height > 0
63
+ actions << lambda {|img| result = nil; img.resize(width,height) {|img2| result = img2}; result }
64
+ end
65
+
66
+ opts.on_tail("-h", "--help", "Show this message") do
67
+ puts opts
68
+ exit 0
69
+ end
70
+
71
+ def opts.usage(msg)
72
+ puts msg
73
+ puts self
74
+ exit 1
75
+ end
76
+ end
77
+ opts.parse!(ARGV)
78
+ opts.usage("You need to supply a source image filename.") unless ARGV.first
79
+ opts.usage("You need to supply one or more actions.") unless actions.size > 0
80
+
81
+ require 'image_voodoo'
82
+ ImageVoodoo.with_image(ARGV.first) do |img|
83
+ original_image = img
84
+ actions.each do |act|
85
+ img = act.call(img)
86
+ end
87
+ end
88
+ # Be sure we exit out of swing
89
+ java.lang.System.exit(0)
@@ -0,0 +1,3 @@
1
+ require 'image_voodoo'
2
+ # HA HA...let the pin-pricking begin
3
+ ImageScience = ImageVoodoo
@@ -0,0 +1,3 @@
1
+ class ImageVoodoo
2
+ VERSION = "0.1"
3
+ end
@@ -0,0 +1,152 @@
1
+ # ImageVoodoo is an ImageScience-API-compatible image manipulation library for JRuby.
2
+ #
3
+ # Example of usage:
4
+ #
5
+ # ImageVoodoo.with_image(ARGV[0]) do |img|
6
+ # img.cropped_thumbnail(100) { |img2| img2.save "CTH.jpg" }
7
+ # img.with_crop(100, 200, 400, 600) { |img2| img2.save "CR.jpg" }
8
+ # img.thumbnail(50) { |img2| img2.save "TH.jpg" }
9
+ # img.resize(100, 150) do |img2|
10
+ # img2.save "HEH.jpg"
11
+ # img2.save "HEH.png"
12
+ # end
13
+ # end
14
+ class ImageVoodoo
15
+ VERSION = "0.1"
16
+
17
+ include Java
18
+
19
+ import java.awt.RenderingHints
20
+ import java.awt.geom.AffineTransform
21
+ import java.awt.image.BufferedImage
22
+ import javax.imageio.ImageIO
23
+ import javax.swing.JFrame
24
+
25
+ JFile = java.io.File
26
+ BAIS = java.io.ByteArrayInputStream
27
+ BAOS = java.io.ByteArrayOutputStream
28
+
29
+ class JImagePanel < javax.swing.JPanel
30
+ def initialize(image, x, y)
31
+ super()
32
+ @image, @x, @y = image, x, y
33
+ end
34
+ def getPreferredSize
35
+ java.awt.Dimension.new(@image.width, @image.height)
36
+ end
37
+ def paintComponent(graphics)
38
+ graphics.drawImage(@image, @x, @y, nil)
39
+ end
40
+ end
41
+
42
+ def initialize(src)
43
+ @src = src
44
+ end
45
+
46
+ def cropped_thumbnail(size)
47
+ l, t, r, b, half = 0, 0, width, height, (width - height).abs / 2
48
+ l, r = half, half + height if width > height
49
+ t, b = half, half + width if height > width
50
+
51
+ with_crop(l, t, r, b) do |img|
52
+ img.thumbnail(size) { |thumb| yield thumb }
53
+ end
54
+ end
55
+
56
+ def height
57
+ @src.height
58
+ end
59
+
60
+ def width
61
+ @src.width
62
+ end
63
+
64
+ def resize(width, height)
65
+ target = BufferedImage.new(width, height, BufferedImage::TYPE_INT_RGB)
66
+ graphics = target.graphics
67
+ graphics.set_rendering_hint(RenderingHints::KEY_INTERPOLATION,
68
+ RenderingHints::VALUE_INTERPOLATION_BICUBIC)
69
+
70
+ w_scale = width.to_f / @src.width
71
+ h_scale = height.to_f / @src.height
72
+
73
+ transform = AffineTransform.get_scale_instance w_scale, h_scale
74
+
75
+ graphics.draw_rendered_image @src, transform
76
+ graphics.dispose
77
+
78
+ yield ImageVoodoo.new(target)
79
+ rescue NativeException => ne
80
+ raise ArgumentError, ne.message
81
+ end
82
+
83
+ def greyscale
84
+ target = BufferedImage.new(width, height, BufferedImage::TYPE_USHORT_GRAY)
85
+ graphics = target.graphics
86
+ graphics.set_rendering_hint(RenderingHints::KEY_INTERPOLATION,
87
+ RenderingHints::VALUE_INTERPOLATION_BICUBIC)
88
+
89
+ graphics.draw_rendered_image @src, nil
90
+ graphics.dispose
91
+
92
+ yield ImageVoodoo.new(target)
93
+ end
94
+
95
+ def save(file)
96
+ format = File.extname(file)
97
+ return false if format == ""
98
+ format = format[1..-1].downcase
99
+ ImageIO.write(@src, format, JFile.new(file))
100
+ true
101
+ end
102
+
103
+ class WindowClosed
104
+ def initialize(block = nil)
105
+ @block = block || proc { java.lang.System.exit(0) }
106
+ end
107
+ def method_missing(meth,*args); end
108
+ def windowClosing(event); @block.call; end
109
+ end
110
+
111
+ def preview(&block)
112
+ frame = JFrame.new("Preview")
113
+ frame.add_window_listener WindowClosed.new(block)
114
+ frame.set_bounds 0, 0, width + 20, height + 40
115
+ frame.add JImagePanel.new(@src, 10, 10)
116
+ frame.visible = true
117
+ end
118
+
119
+ def bytes(format)
120
+ out = BAOS.new
121
+ ImageIO.write(@src, format, out)
122
+ String.from_java_bytes(out.to_byte_array)
123
+ end
124
+
125
+ def thumbnail(size)
126
+ scale = size.to_f / (width > height ? width : height)
127
+ new_width = (width * scale).to_i
128
+ new_height = (height * scale).to_i
129
+ resize(new_width, new_height) {|image| yield image }
130
+ end
131
+
132
+ def with_crop(left, top, right, bottom)
133
+ subimage = @src.get_subimage(left, top, right - left, bottom - top)
134
+ yield ImageVoodoo.new(subimage)
135
+ end
136
+
137
+ def self.with_image(file)
138
+ readers = ImageIO.getImageReadersBySuffix(File.extname(file)[1..-1])
139
+ raise TypeError, "unrecognized format for #{file}" unless readers.hasNext
140
+ image = ImageIO.read(JFile.new(file))
141
+ yield ImageVoodoo.new(image)
142
+ rescue NativeException => ne
143
+ nil
144
+ end
145
+
146
+ def self.with_bytes(bytes)
147
+ bytes = bytes.to_java_bytes if String === bytes
148
+
149
+ image = ImageIO.read(BAIS.new(bytes))
150
+ yield ImageVoodoo.new(image)
151
+ end
152
+ end
data/samples/bench.rb ADDED
@@ -0,0 +1,64 @@
1
+ #!/usr/local/bin/ruby -w
2
+
3
+ require 'benchmark'
4
+ require 'rbconfig'
5
+ require 'rubygems'
6
+ require 'image_science'
7
+
8
+ max = (ARGV.shift || 100).to_i
9
+ ext = ARGV.shift || "png"
10
+
11
+ file = "blah_big.#{ext}"
12
+
13
+ if Config::CONFIG['host_os'] =~ /darwin/ then
14
+ # how fucking cool is this???
15
+ puts "taking screenshot for thumbnailing benchmarks"
16
+ system "screencapture -SC #{file}"
17
+ else
18
+ abort "You need to plonk down #{file} or buy a mac"
19
+ end unless test ?f, "#{file}"
20
+
21
+ ImageScience.with_image(file.sub(/#{ext}$/, 'png')) do |img|
22
+ img.save(file)
23
+ end if ext != "png"
24
+
25
+ puts "# of iterations = #{max}"
26
+ Benchmark::bm(20) do |x|
27
+ x.report("null_time") {
28
+ for i in 0..max do
29
+ # do nothing
30
+ end
31
+ }
32
+
33
+ x.report("cropped") {
34
+ for i in 0..max do
35
+ ImageScience.with_image(file) do |img|
36
+ img.cropped_thumbnail(100) do |thumb|
37
+ thumb.save("blah_cropped.#{ext}")
38
+ end
39
+ end
40
+ end
41
+ }
42
+
43
+ x.report("proportional") {
44
+ for i in 0..max do
45
+ ImageScience.with_image(file) do |img|
46
+ img.thumbnail(100) do |thumb|
47
+ thumb.save("blah_thumb.#{ext}")
48
+ end
49
+ end
50
+ end
51
+ }
52
+
53
+ x.report("resize") {
54
+ for i in 0..max do
55
+ ImageScience.with_image(file) do |img|
56
+ img.resize(200, 200) do |resize|
57
+ resize.save("blah_resize.#{ext}")
58
+ end
59
+ end
60
+ end
61
+ }
62
+ end
63
+
64
+ # File.unlink(*Dir["blah*#{ext}"])
Binary file
@@ -0,0 +1,13 @@
1
+ require 'image_voodoo'
2
+
3
+ # reads in the file specified by ARGV[0], transforming to greyscale and
4
+ # writing to the file specified by ARGV[1]
5
+ ImageVoodoo.with_image(ARGV[0]) do |img|
6
+ img.greyscale do |img2|
7
+ if ARGV[1]
8
+ img2.save(ARGV[1])
9
+ else
10
+ img2.preview
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,14 @@
1
+ require 'image_science'
2
+
3
+ # reads in the file specified by ARGV[0], transforms it into a 32-pixel thumbnail,
4
+ # and writes it out to the file specified by ARGV[1], using that extension as the
5
+ # target format.
6
+ ImageScience.with_image(ARGV[0]) do |img|
7
+ img.thumbnail(32) do |img2|
8
+ if ARGV[1]
9
+ img2.save(ARGV[1])
10
+ else
11
+ img2.preview
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,6 @@
1
+ require 'image_voodoo'
2
+
3
+ # preview the file specified by ARGV[0] in a swing window
4
+ ImageVoodoo.with_image(ARGV[0]) do |img|
5
+ img.preview
6
+ end
@@ -0,0 +1,11 @@
1
+ require 'image_voodoo'
2
+
3
+ # reads in the image at ARGV[0], transforms it into a 32-pixel thumbnail in-memory,
4
+ # and writes it back out as a png to the file specified by ARGV[1]
5
+ ImageVoodoo.with_bytes(File.read(ARGV[0])) do |img|
6
+ img.thumbnail(32) do |img2|
7
+ File.open(ARGV[1], 'w') do |file|
8
+ file.write(img2.bytes('png'))
9
+ end
10
+ end
11
+ end
data/test/pix.png ADDED
Binary file
@@ -0,0 +1,124 @@
1
+ require 'test/unit/testcase'
2
+ require 'test/unit' if $0 == __FILE__
3
+ require 'image_science'
4
+
5
+ class TestImageScience < Test::Unit::TestCase
6
+ def deny x; assert ! x; end
7
+
8
+ def setup
9
+ @path = 'test/pix.png'
10
+ @tmppath = 'test/pix-tmp.png'
11
+ @h = @w = 50
12
+ end
13
+
14
+ def teardown
15
+ File.unlink @tmppath if File.exist? @tmppath
16
+ end
17
+
18
+ def test_class_with_image
19
+ ImageScience.with_image @path do |img|
20
+ assert_kind_of ImageScience, img
21
+ assert_equal @h, img.height
22
+ assert_equal @w, img.width
23
+ assert img.save(@tmppath)
24
+ end
25
+
26
+ assert File.exists?(@tmppath)
27
+
28
+ ImageScience.with_image @tmppath do |img|
29
+ assert_kind_of ImageScience, img
30
+ assert_equal @h, img.height
31
+ assert_equal @w, img.width
32
+ end
33
+ end
34
+
35
+ def test_class_with_image_missing
36
+ assert_raises TypeError do
37
+ ImageScience.with_image @path + "nope" do |img|
38
+ flunk
39
+ end
40
+ end
41
+ end
42
+
43
+ def test_class_with_image_missing_with_img_extension
44
+ assert_nil ImageScience.with_image("nope#{@path}") do |img|
45
+ flunk
46
+ end
47
+ end
48
+
49
+ def test_resize
50
+ ImageScience.with_image @path do |img|
51
+ img.resize(25, 25) do |thumb|
52
+ assert thumb.save(@tmppath)
53
+ end
54
+ end
55
+
56
+ assert File.exists?(@tmppath)
57
+
58
+ ImageScience.with_image @tmppath do |img|
59
+ assert_kind_of ImageScience, img
60
+ assert_equal 25, img.height
61
+ assert_equal 25, img.width
62
+ end
63
+ end
64
+
65
+ def test_resize_floats
66
+ ImageScience.with_image @path do |img|
67
+ img.resize(25.2, 25.7) do |thumb|
68
+ assert thumb.save(@tmppath)
69
+ end
70
+ end
71
+
72
+ assert File.exists?(@tmppath)
73
+
74
+ ImageScience.with_image @tmppath do |img|
75
+ assert_kind_of ImageScience, img
76
+ assert_equal 25, img.height
77
+ assert_equal 25, img.width
78
+ end
79
+ end
80
+
81
+ def test_resize_zero
82
+ assert_raises ArgumentError do
83
+ ImageScience.with_image @path do |img|
84
+ img.resize(0, 25) do |thumb|
85
+ assert thumb.save(@tmppath)
86
+ end
87
+ end
88
+ end
89
+
90
+ deny File.exists?(@tmppath)
91
+
92
+ assert_raises ArgumentError do
93
+ ImageScience.with_image @path do |img|
94
+ img.resize(25, 0) do |thumb|
95
+ assert thumb.save(@tmppath)
96
+ end
97
+ end
98
+ end
99
+
100
+ deny File.exists?(@tmppath)
101
+ end
102
+
103
+ def test_resize_negative
104
+ assert_raises ArgumentError do
105
+ ImageScience.with_image @path do |img|
106
+ img.resize(-25, 25) do |thumb|
107
+ assert thumb.save(@tmppath)
108
+ end
109
+ end
110
+ end
111
+
112
+ deny File.exists?(@tmppath)
113
+
114
+ assert_raises ArgumentError do
115
+ ImageScience.with_image @path do |img|
116
+ img.resize(25, -25) do |thumb|
117
+ assert thumb.save(@tmppath)
118
+ end
119
+ end
120
+ end
121
+
122
+ deny File.exists?(@tmppath)
123
+ end
124
+ end
metadata ADDED
@@ -0,0 +1,72 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: image_voodoo
3
+ version: !ruby/object:Gem::Version
4
+ version: "0.1"
5
+ platform: ruby
6
+ authors:
7
+ - Thomas Enebo, Charles Nutter and JRuby contributors
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-03-27 00:00:00 -05:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Install this gem and require 'image_voodoo' to load the library.
17
+ email: enebo@acm.org, headius@headius.com
18
+ executables:
19
+ - image_voodoo
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - Manifest.txt
24
+ - README.txt
25
+ - LICENSE.txt
26
+ files:
27
+ - bin/image_voodoo
28
+ - Manifest.txt
29
+ - Rakefile
30
+ - README.txt
31
+ - LICENSE.txt
32
+ - lib/image_science.rb
33
+ - lib/image_voodoo
34
+ - lib/image_voodoo/version.rb
35
+ - lib/image_voodoo.rb
36
+ - samples/bench.rb
37
+ - samples/checkerboard.jpg
38
+ - samples/file_greyscale.rb
39
+ - samples/file_thumbnail.rb
40
+ - samples/file_view.rb
41
+ - samples/in-memory.rb
42
+ - test/pix.png
43
+ - test/test_image_science.rb
44
+ has_rdoc: true
45
+ homepage: http://jruby-extras.rubyforge.org/image_voodoo
46
+ post_install_message:
47
+ rdoc_options:
48
+ - --main
49
+ - README.txt
50
+ require_paths:
51
+ - lib
52
+ required_ruby_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: "0"
57
+ version:
58
+ required_rubygems_version: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: "0"
63
+ version:
64
+ requirements: []
65
+
66
+ rubyforge_project: jruby-extras
67
+ rubygems_version: 1.0.1
68
+ signing_key:
69
+ specification_version: 2
70
+ summary: Image manipulation in JRuby with ImageScience compatible API
71
+ test_files:
72
+ - test/test_image_science.rb