Diff
Property changes: trunk/image_voodoo
Name: svn:ignore
+ doc
pkg
Modified: trunk/image_voodoo/README.txt (955 => 956)
--- trunk/image_voodoo/README.txt 2008-03-24 20:20:43 UTC (rev 955)
+++ trunk/image_voodoo/README.txt 2008-03-27 20:15:36 UTC (rev 956)
@@ -1,6 +1,58 @@
-This is an Image manipulation library with a ImageScience-compatible API for
-JRuby. See:
+= ImageVoodoo
+== DESCRIPTION:
+
+ImageVoodoo is an Image manipulation library with a ImageScience-compatible API for
+JRuby.
+
http://jruby-extras.rubyforge.org/image_voodoo/
-for more information.
+== FEATURES/PROBLEMS:
+
+* Uses java.awt and javax.image APIs native to Java to perform image manipulation; no other dependencies needed.
+
+== SYNOPSIS:
+
+ ImageVoodoo.with_image(ARGV[0]) do |img|
+ img.cropped_thumbnail(100) { |img2| img2.save "CTH.jpg" }
+ img.with_crop(100, 200, 400, 600) { |img2| img2.save "CR.jpg" }
+ img.thumbnail(50) { |img2| img2.save "TH.jpg" }
+ img.resize(100, 150) do |img2|
+ img2.save "HEH.jpg"
+ img2.save "HEH.png"
+ end
+ end
+
+
+== REQUIREMENTS:
+
+* JRuby
+
+== INSTALL:
+
+* jruby -S gem install image_voodoo
+
+== LICENSE:
+
+(The MIT License)
+
+Copyright (c) 2008 Thomas Enebo, Nick Sieger
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+'Software'), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Added: trunk/image_voodoo/bin/image_voodoo (0 => 956)
--- trunk/image_voodoo/bin/image_voodoo (rev 0)
+++ trunk/image_voodoo/bin/image_voodoo 2008-03-27 20:15:36 UTC (rev 956)
@@ -0,0 +1,89 @@
+#!/usr/bin/env ruby
+
+require 'optparse'
+
+actions = []
+images = []
+original_image = nil
+
+opts = OptionParser.new do |opts|
+ opts.banner = "Usage: image_voodoo [actions] image_file"
+ opts.separator "Perform some actions on a source image."
+
+ opts.separator ""
+ opts.separator "Actions are meant to be chained. Examples:"
+ opts.separator " # Print the dimensions"
+ opts.separator " image_voodoo --dim small.jpg"
+ opts.separator ""
+ opts.separator " # Convert to a thumbnail, preview, and then save the result"
+ opts.separator " image_voodoo --thumb 50 --preview --save thumb.png large.jpg"
+ opts.separator ""
+ opts.separator " # Convert source to 3 thumbnails, showing dimensions and"
+ opts.separator " # previewing along the way"
+ opts.separator " image_voodoo --dim --resize 50x50 --dim --preview --save t1.jpg"
+ opts.separator " --pop --resize 40x40 --dim --preview --save t2.jpg"
+ opts.separator " --pop --resize 30x30 --dim --preview --save t3.jpg image.jpg"
+
+ opts.separator ""
+ opts.separator "Actions:"
+
+ opts.on("-d", "--dimensions", "Print the image dimensions") do
+ actions << lambda {|img| puts "#{img.width}x#{img.height}"; img }
+ end
+
+ opts.on("-s", "--save FILENAME", "Save the results to a new file") do |f|
+ actions << lambda {|img| img.save(f); img }
+ end
+
+ opts.on("-t", "--thumbnail SIZE", Integer, "Create a thumbnail of the given size") do |size|
+ actions << lambda {|img| result = nil; img.thumbnail(size) {|img2| result = img2 }; result }
+ end
+
+ opts.on("-p", "--preview", "Preview the image. Close the frame window",
+ "to continue, or quit the application to", "abort the action pipeline") do
+ actions << lambda do |img|
+ done = false
+ img.preview { done = true }
+ Thread.pass until done
+ img
+ end
+ end
+
+ opts.on("--push", "Save the current image to be popped later") do
+ actions << lambda {|img| images << img; img }
+ end
+
+ opts.on("--pop", "Revert back to the previous saved image", "or the original source image") do
+ actions << lambda {|img| images.pop || original_image }
+ end
+
+ opts.on("-r", "--resize WIDTHxHEIGHT", "Create a new image with the specified", "dimensions") do |dim|
+ width, height = dim.split(/x/i).map {|v| v.to_i}
+ opts.usage "You need to specify proper dimensions" unless width && width > 0 && height && height > 0
+ actions << lambda {|img| result = nil; img.resize(width,height) {|img2| result = img2}; result }
+ end
+
+ opts.on_tail("-h", "--help", "Show this message") do
+ puts opts
+ exit 0
+ end
+
+ def opts.usage(msg)
+ puts msg
+ puts self
+ exit 1
+ end
+end
+opts.parse!(ARGV)
+opts.usage("You need to supply a source image filename.") unless ARGV.first
+opts.usage("You need to supply one or more actions.") unless actions.size > 0
+
+require 'image_voodoo'
+ImageVoodoo.with_image(ARGV.first) do |img|
+ original_image = img
+ actions.each do |act|
+ img = act.call(img)
+ end
+end
+# Be sure we exit out of swing
+java.lang.System.exit(0)
Modified: trunk/image_voodoo/lib/image_voodoo.rb (955 => 956)
--- trunk/image_voodoo/lib/image_voodoo.rb 2008-03-24 20:20:43 UTC (rev 955)
+++ trunk/image_voodoo/lib/image_voodoo.rb 2008-03-27 20:15:36 UTC (rev 956)
@@ -1,3 +1,16 @@
+# ImageVoodoo is an ImageScience-API-compatible image manipulation library for JRuby.
+#
+# Example of usage:
+#
+# ImageVoodoo.with_image(ARGV[0]) do |img|
+# img.cropped_thumbnail(100) { |img2| img2.save "CTH.jpg" }
+# img.with_crop(100, 200, 400, 600) { |img2| img2.save "CR.jpg" }
+# img.thumbnail(50) { |img2| img2.save "TH.jpg" }
+# img.resize(100, 150) do |img2|
+# img2.save "HEH.jpg"
+# img2.save "HEH.png"
+# end
+# end
class ImageVoodoo
VERSION = "0.1"
@@ -2,14 +15,26 @@
include Java
-
- import java.awt.Image
+
import java.awt.RenderingHints
import java.awt.geom.AffineTransform
import java.awt.image.BufferedImage
import javax.imageio.ImageIO
-
+ import javax.swing.JFrame
+
JFile = java.io.File
BAIS = java.io.ByteArrayInputStream
BAOS = java.io.ByteArrayOutputStream
- FOS = java.io.FileOutputStream
+ class JImagePanel < javax.swing.JPanel
+ def initialize(image, x, y)
+ super()
+ @image, @x, @y = image, x, y
+ end
+ def getPreferredSize
+ java.awt.Dimension.new(@image.width, @image.height)
+ end
+ def paintComponent(graphics)
+ graphics.drawImage(@image, @x, @y, nil)
+ end
+ end
+
def initialize(src)
@@ -24,7 +49,7 @@
t, b = half, half + width if height > width
with_crop(l, t, r, b) do |img|
- img.thumbnail(size) { |thumb| yield thumb }
+ img.thumbnail(size) { |thumb| yield thumb }
end
end
@@ -37,45 +62,60 @@
end
def resize(width, height)
- target = BufferedImage.new(width, height, BufferedImage::TYPE_4BYTE_ABGR)
+ target = BufferedImage.new(width, height, BufferedImage::TYPE_INT_RGB)
graphics = target.graphics
graphics.set_rendering_hint(RenderingHints::KEY_INTERPOLATION,
RenderingHints::VALUE_INTERPOLATION_BICUBIC)
-
+
w_scale = width.to_f / @src.width
h_scale = height.to_f / @src.height
-
+
transform = AffineTransform.get_scale_instance w_scale, h_scale
-
+
graphics.draw_rendered_image @src, transform
graphics.dispose
-
+
yield ImageVoodoo.new(target)
rescue NativeException => ne
raise ArgumentError, ne.message
end
-
+
def greyscale
target = BufferedImage.new(width, height, BufferedImage::TYPE_USHORT_GRAY)
graphics = target.graphics
graphics.set_rendering_hint(RenderingHints::KEY_INTERPOLATION,
RenderingHints::VALUE_INTERPOLATION_BICUBIC)
-
+
graphics.draw_rendered_image @src, nil
graphics.dispose
-
+
yield ImageVoodoo.new(target)
end
def save(file)
- return false if file !~ /\.(.*)$/
-
- out = FOS.new file
- ImageIO.write(@src, $1, out)
- out.close
+ format = File.extname(file)
+ return false if format == ""
+ format = format[1..-1].downcase
+ ImageIO.write(@src, format, JFile.new(file))
true
end
+ class WindowClosed
+ def initialize(block = nil)
+ @block = block || proc { java.lang.System.exit(0) }
+ end
+ def method_missing(meth,*args); end
+ def windowClosing(event); @block.call; end
+ end
+
+ def preview(&block)
+ frame = JFrame.new("Preview")
+ frame.add_window_listener WindowClosed.new(block)
+ frame.set_bounds 0, 0, width + 20, height + 40
+ frame.add JImagePanel.new(@src, 10, 10)
+ frame.visible = true
+ end
+
def bytes(format)
out = BAOS.new
ImageIO.write(@src, format, out)
@@ -110,13 +150,3 @@
yield ImageVoodoo.new(image)
end
end
-
-#ImageVoodoo.with_image(ARGV[0]) do |img|
-# img.cropped_thumbnail(100) { |img2| img2.save "CTH.jpg" }
-# img.with_crop(100, 200, 400, 600) { |img2| img2.save "CR.jpg" }
-# img.thumbnail(50) { |img2| img2.save "TH.jpg" }
-# img.resize(100, 150) do |img2|
-# img2.save "HEH.jpg"
-# img2.save "HEH.png"
-# end
-#end
Added: trunk/image_voodoo/samples/bench.rb (0 => 956)
--- trunk/image_voodoo/samples/bench.rb (rev 0)
+++ trunk/image_voodoo/samples/bench.rb 2008-03-27 20:15:36 UTC (rev 956)
@@ -0,0 +1,64 @@
+#!/usr/local/bin/ruby -w
+
+require 'benchmark'
+require 'rbconfig'
+require 'rubygems'
+require 'image_science'
+
+max = (ARGV.shift || 100).to_i
+ext = ARGV.shift || "png"
+
+file = "blah_big.#{ext}"
+
+if Config::CONFIG['host_os'] =~ /darwin/ then
+ # how fucking cool is this???
+ puts "taking screenshot for thumbnailing benchmarks"
+ system "screencapture -SC #{file}"
+else
+ abort "You need to plonk down #{file} or buy a mac"
+end unless test ?f, "#{file}"
+
+ImageScience.with_image(file.sub(/#{ext}$/, 'png')) do |img|
+ img.save(file)
+end if ext != "png"
+
+puts "# of iterations = #{max}"
+Benchmark::bm(20) do |x|
+ x.report("null_time") {
+ for i in 0..max do
+ # do nothing
+ end
+ }
+
+ x.report("cropped") {
+ for i in 0..max do
+ ImageScience.with_image(file) do |img|
+ img.cropped_thumbnail(100) do |thumb|
+ thumb.save("blah_cropped.#{ext}")
+ end
+ end
+ end
+ }
+
+ x.report("proportional") {
+ for i in 0..max do
+ ImageScience.with_image(file) do |img|
+ img.thumbnail(100) do |thumb|
+ thumb.save("blah_thumb.#{ext}")
+ end
+ end
+ end
+ }
+
+ x.report("resize") {
+ for i in 0..max do
+ ImageScience.with_image(file) do |img|
+ img.resize(200, 200) do |resize|
+ resize.save("blah_resize.#{ext}")
+ end
+ end
+ end
+ }
+end
+
+# File.unlink(*Dir["blah*#{ext}"])
Added: trunk/image_voodoo/samples/checkerboard.jpg
(Binary files differ)
Property changes on: trunk/image_voodoo/samples/checkerboard.jpg
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Modified: trunk/image_voodoo/samples/file_greyscale.rb (955 => 956)
--- trunk/image_voodoo/samples/file_greyscale.rb 2008-03-24 20:20:43 UTC (rev 955)
+++ trunk/image_voodoo/samples/file_greyscale.rb 2008-03-27 20:15:36 UTC (rev 956)
@@ -4,6 +4,10 @@
# writing to the file specified by ARGV[1]
ImageVoodoo.with_image(ARGV[0]) do |img|
img.greyscale do |img2|
- img2.save(ARGV[1])
+ if ARGV[1]
+ img2.save(ARGV[1])
+ else
+ img2.preview
+ end
end
end
Modified: trunk/image_voodoo/samples/file_thumbnail.rb (955 => 956)
--- trunk/image_voodoo/samples/file_thumbnail.rb 2008-03-24 20:20:43 UTC (rev 955)
+++ trunk/image_voodoo/samples/file_thumbnail.rb 2008-03-27 20:15:36 UTC (rev 956)
@@ -1,11 +1,14 @@
-require 'image_voodoo'
+require 'image_science'
# reads in the file specified by ARGV[0], transforms it into a 32-pixel thumbnail,
# and writes it out to the file specified by ARGV[1], using that extension as the
# target format.
-ImageVoodoo.with_image(ARGV[0]) do |img|
+ImageScience.with_image(ARGV[0]) do |img|
img.thumbnail(32) do |img2|
- img2.save(ARGV[1])
+ if ARGV[1]
+ img2.save(ARGV[1])
+ else
+ img2.preview
+ end
end
end
-
Added: trunk/image_voodoo/samples/file_view.rb (0 => 956)
--- trunk/image_voodoo/samples/file_view.rb (rev 0)
+++ trunk/image_voodoo/samples/file_view.rb 2008-03-27 20:15:36 UTC (rev 956)
@@ -0,0 +1,6 @@
+require 'image_voodoo'
+
+# preview the file specified by ARGV[0] in a swing window
+ImageVoodoo.with_image(ARGV[0]) do |img|
+ img.preview
+end