Title: [997] trunk/image_voodoo: -Added adjust_brightness method
Revision
997
Author
enebo
Date
2008-05-19 18:17:57 -0400 (Mon, 19 May 2008)

Log Message

-Added adjust_brightness method
-Added negative (reverse pixel values)
-Made greyscale work with any supported format (only RGB before)
-Allow all methods to allow block to be optional (makes image_voodoo script
  look quite a bit nicer)

Modified Paths

Diff

Modified: trunk/image_voodoo/bin/image_voodoo (996 => 997)


--- trunk/image_voodoo/bin/image_voodoo	2008-05-19 13:36:43 UTC (rev 996)
+++ trunk/image_voodoo/bin/image_voodoo	2008-05-19 22:17:57 UTC (rev 997)
@@ -27,16 +27,30 @@
   opts.separator ""
   opts.separator "Actions:"
 
+  opts.on("-b", "--brightness SCALE,OFFSET", "Adjust brightness") do |args|
+    scale, offset = args.split(/\,/i).map {|v| v.to_f}
+    opts.usage "You need to specify proper scale and offset" unless scale && offset
+    actions << lambda {|img| img.adjust_brightness(scale, offset) }
+  end
+
   opts.on("-d", "--dimensions", "Print the image dimensions") do
     actions << lambda {|img| puts "#{img.width}x#{img.height}"; img }
   end
 
+  opts.on("-g", "--greyscale", "Convert image to greyscale") do
+    actions << lambda {|img| img.greyscale }
+  end
+
+  opts.on("-n", "--negative", "Make a negative out of the image") do
+    actions << lambda {|img| img.negative }
+  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 }
+    actions << lambda {|img| img.thumbnail(size) }
   end
 
   opts.on("-p", "--preview", "Preview the image. Close the frame window",
@@ -60,7 +74,7 @@
   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 }
+    actions << lambda {|img| img.resize(width,height) }
   end
 
   opts.on_tail("-h", "--help", "Show this message") do

Modified: trunk/image_voodoo/lib/image_voodoo/version.rb (996 => 997)


--- trunk/image_voodoo/lib/image_voodoo/version.rb	2008-05-19 13:36:43 UTC (rev 996)
+++ trunk/image_voodoo/lib/image_voodoo/version.rb	2008-05-19 22:17:57 UTC (rev 997)
@@ -1,3 +1,3 @@
 class ImageVoodoo
-  VERSION = "0.1"
-end
\ No newline at end of file
+  VERSION = "0.2"
+end

Modified: trunk/image_voodoo/lib/image_voodoo.rb (996 => 997)


--- trunk/image_voodoo/lib/image_voodoo.rb	2008-05-19 13:36:43 UTC (rev 996)
+++ trunk/image_voodoo/lib/image_voodoo.rb	2008-05-19 22:17:57 UTC (rev 997)
@@ -12,20 +12,25 @@
 #      end
 #    end
 class ImageVoodoo
-  VERSION = "0.1"
-
   include Java
 
   import java.awt.RenderingHints
+  import java.awt.color.ColorSpace
   import java.awt.geom.AffineTransform
+  import java.awt.image.ByteLookupTable
+  import java.awt.image.ColorConvertOp
+  import java.awt.image.LookupOp
+  import java.awt.image.RescaleOp
   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
+  import javax.imageio.ImageIO
+  import javax.swing.JFrame
 
+  NEGATIVE_OP = LookupOp.new(ByteLookupTable.new(0, (0...254).to_a.reverse.to_java(:byte)), nil)
+  GREY_OP = ColorConvertOp.new(ColorSpace.getInstance(ColorSpace::CS_GRAY), nil)
+
   class JImagePanel < javax.swing.JPanel
     def initialize(image, x=0, y=0)
       super()
@@ -47,13 +52,22 @@
     @src = ""
   end
 
+  # Foreach pixel new_pixel = pixel * scale + offset
+  def adjust_brightness(scale, offset)
+    image = ImageVoodoo.new internal_transform(RescaleOp.new(scale, offset, nil))
+    block_given? ? yield(image) : image
+  end
+
   def cropped_thumbnail(size)
     l, t, r, b, half = 0, 0, width, height, (width - height).abs / 2
     l, r = half, half + height if width > height
     t, b = half, half + width if height > width
 
-    with_crop(l, t, r, b) do |img|
-      img.thumbnail(size) { |thumb| yield thumb }
+    with_crop(l, t, r, b) do |image|
+      image.thumbnail(size) do |thumb|
+        target = ImageVoodoo.new target
+        block_given? ? yield(target) : target
+      end
     end
   end
 
@@ -69,9 +83,9 @@
     @src
   end
 
-  def color_type
-    return BufferedImage::TYPE_INT_ARGB if @src.color_model.has_alpha
-    BufferedImage::TYPE_INT_RGB
+  def negative
+    image = ImageVoodoo.new internal_transform(NEGATIVE_OP)
+    block_given? ? yield(image) : image
   end
 
   def resize(width, height)
@@ -79,30 +93,21 @@
     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)
+    target = ImageVoodoo.new target
+    block_given? ? yield(target) : 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)
+    image = ImageVoodoo.new internal_transform(GREY_OP)
+    block_given? ? yield(image) : image
   end
 
   def save(file)
@@ -138,7 +143,10 @@
   def scale(ratio)
     new_width = (width * ratio).to_i
     new_height = (height * ratio).to_i
-    resize(new_width, new_height) {|image| yield image }
+    resize(new_width, new_height) do |image|
+      target = ImageVoodoo.new image
+      block_given? ? yield(target) : target
+    end
   end
 
   def thumbnail(size)
@@ -146,23 +154,53 @@
   end
 
   def with_crop(left, top, right, bottom)
-    subimage = @src.get_subimage(left, top, right - left, bottom - top)
-    yield ImageVoodoo.new(subimage)
+    image = ImageVoodoo.new(@src.get_subimage(left, top, right-left, bottom-top))
+    block_given? ? yield(image) : image
   end
 
+  # TODO: Figure out how to determine whether source has alpha or not
+  def self.from_url(source)
+    url = ""
+    image = java.awt.Toolkit.default_toolkit.create_image(url)
+    tracker = java.awt.MediaTracker.new(java.awt.Label.new(""))
+    tracker.addImage(image, 0);
+    tracker.waitForID(0)
+    target = BufferedImage.new(image.getWidth, image.getHeight, BufferedImage::TYPE_INT_RGB)
+    graphics = target.graphics
+    graphics.drawImage(image, 0, 0, nil)
+    graphics.dispose
+    target = ImageVoodoo.new target
+    block_given? ? yield(target) : target
+  rescue java.io.IOException, java.net.MalformedURLException
+    raise ArgumentError.new "Trouble retrieving image: #{$!.message}"
+  end
+
   def self.with_image(file)
     readers = ImageIO.getImageReadersBySuffix(File.extname(file)[1..-1])
     raise TypeError, "unrecognized format for #{file}" unless readers.hasNext
-    image = ImageIO.read(JFile.new(file))
-    yield ImageVoodoo.new(image)
+    image = ImageVoodoo.new ImageIO.read(JFile.new(file))
+    block_given? ? yield(image) : image
   rescue NativeException => ne
     nil
   end
 
   def self.with_bytes(bytes)
     bytes = bytes.to_java_bytes if String === bytes
+    image = ImageVoodoo.new ImageIO.read(BAIS.new(bytes))
+    block_given? ? yield(image) : image
+  end
 
-    image = ImageIO.read(BAIS.new(bytes))
-    yield ImageVoodoo.new(image)
+  private
+  def color_type
+    return BufferedImage::TYPE_INT_ARGB if @src.color_model.has_alpha
+    BufferedImage::TYPE_INT_RGB
   end
+
+  def internal_transform(operation, target=BufferedImage.new(width, height, color_type))
+    graphics = target.graphics
+    graphics.drawImage(@src, 0, 0, nil)
+    graphics.drawImage(operation.filter(target, nil), 0, 0, nil)
+    graphics.dispose
+    target
+  end
 end
_______________________________________________
Jruby-extras-devel mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/jruby-extras-devel

Reply via email to