lib/image_voodoo.rb in image_voodoo-0.4 vs lib/image_voodoo.rb in image_voodoo-0.5
- old
+ new
@@ -28,23 +28,26 @@
include Java
import java.awt.RenderingHints
import java.awt.color.ColorSpace
import java.awt.geom.AffineTransform
+ import java.awt.image.BufferedImage
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
JFile = java.io.File
import java.io.ByteArrayInputStream
import 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)
+ ARGB = BufferedImage::TYPE_INT_ARGB
+ RGB = BufferedImage::TYPE_INT_RGB
+ SCALE_SMOOTH = java.awt.Image::SCALE_SMOOTH
def initialize(src)
@src = src
end
@@ -59,51 +62,47 @@
border_width = options[:width].to_i || 2
color = hex_to_color(options[:color]) || hex_to_color("000000")
style = options[:style]
style = nil if style.to_sym == :plain
new_width, new_height = width + 2*border_width, height + 2*border_width
- target = BufferedImage.new(new_width, new_height, color_type)
- graphics = target.graphics
- graphics.color = color
- if style
- raised = style.to_sym == :raised ? true : false
- graphics.fill3DRect(0, 0, new_width, new_height, raised)
- else
- graphics.fill_rect(0, 0, new_width, new_height)
+ target = paint(BufferedImage.new(new_width, new_height, color_type)) do |g|
+ g.color = color
+ if style
+ raised = style.to_sym == :raised ? true : false
+ g.fill3DRect(0, 0, new_width, new_height, raised)
+ else
+ g.fill_rect(0, 0, new_width, new_height)
+ end
+ g.draw_image(@src, nil, border_width, border_width)
end
- graphics.draw_image(@src, nil, border_width, border_width)
- graphics.dispose
- target = ImageVoodoo.new target
block_given? ? yield(target) : target
end
#
# Adjusts the brightness of each pixel in image by the following formula:
# new_pixel = pixel * scale + offset
#
def adjust_brightness(scale, offset)
- image = ImageVoodoo.new internal_transform(RescaleOp.new(scale, offset, nil))
+ image = internal_transform(RescaleOp.new(scale, offset, nil))
block_given? ? yield(image) : image
end
#
# Converts rgb hex color value to an alpha value an yields/returns the new
# image.
#
def alpha(rgb)
color = hex_to_color(rgb)
- target = BufferedImage.new(width, height, BufferedImage::TYPE_INT_ARGB)
- graphics = target.graphics
- graphics.set_composite(java.awt.AlphaComposite::Src)
- graphics.draw_image(@src, nil, 0, 0)
- graphics.dispose
- 0.upto(height-1) do |i|
- 0.upto(width-1) do |j|
- target.setRGB(j, i, 0x8F1C1C) if target.getRGB(j, i) == color.getRGB
+ target = paint(BufferedImage.new(width, height, ARGB)) do |g|
+ g.set_composite(java.awt.AlphaComposite::Src)
+ g.draw_image(@src, nil, 0, 0)
+ 0.upto(height-1) do |i|
+ 0.upto(width-1) do |j|
+ target.setRGB(j, i, 0x8F1C1C) if target.getRGB(j, i) == color.getRGB
+ end
end
end
- target = ImageVoodoo.new target
block_given? ? yield(target) : target
end
#
# Write current image out as a stream of bytes using provided format.
@@ -129,63 +128,52 @@
#
# Flips the image horizontally and yields/returns the new image.
#
def flip_horizontally
- target = BufferedImage.new(width, height, color_type)
- graphics = target.graphics
- graphics.draw_image(@src, 0, 0, width, height, width, 0, 0, height, nil)
- graphics.dispose
- target = ImageVoodoo.new target
+ target = paint do |g|
+ g.draw_image @src, 0, 0, width, height, width, 0, 0, height, nil
+ end
block_given? ? yield(target) : target
end
#
# Flips the image vertically and yields/returns the new image.
#
def flip_vertically
- target = BufferedImage.new(width, height, color_type)
- graphics = target.graphics
- graphics.draw_image(@src, 0, 0, width, height, 0, height, width, 0, nil)
- graphics.dispose
- target = ImageVoodoo.new target
+ target = paint do |g|
+ g.draw_image @src, 0, 0, width, height, 0, height, width, 0, nil
+ end
block_given? ? yield(target) : target
end
#
# Creates a grayscale version of image and yields/returns the new image.
#
def greyscale
- image = ImageVoodoo.new internal_transform(GREY_OP)
- block_given? ? yield(image) : image
+ target = internal_transform(GREY_OP)
+ block_given? ? yield(target) : target
end
alias_method :grayscale, :greyscale
#
# Creates a negative and yields/returns the new image.
#
def negative
- image = ImageVoodoo.new internal_transform(NEGATIVE_OP)
- block_given? ? yield(image) : image
+ target = internal_transform(NEGATIVE_OP)
+ block_given? ? yield(target) : target
end
#
# Resizes the image to width and height using bicubic interpolation and
# yields/returns the new image.
#
def resize(width, height)
- target = BufferedImage.new(width, height, color_type)
- 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
-
- target = ImageVoodoo.new target
+ target = paint(BufferedImage.new(width, height, color_type)) do |g|
+ scaled_image = @src.get_scaled_instance width, height, SCALE_SMOOTH
+ g.draw_image scaled_image, 0, 0, nil
+ end
block_given? ? yield(target) : target
rescue NativeException => ne
raise ArgumentError, ne.message
end
@@ -205,11 +193,10 @@
# Resize (scale) the current image by the provided ratio and yield/return
# the new image.
#
def scale(ratio)
new_width, new_height = (width * ratio).to_i, (height * ratio).to_i
-
target = resize(new_width, new_height)
block_given? ? yield(target) : target
end
#
@@ -247,11 +234,11 @@
def getPreferredSize
java.awt.Dimension.new(@image.width, @image.height)
end
def paintComponent(graphics)
- graphics.drawImage(@image.to_java, @x, @y, nil)
+ graphics.draw_image(@image.to_java, @x, @y, nil)
end
end
# Internal class for closing preview window
class WindowClosed
@@ -282,15 +269,13 @@
url = java.net.URL.new(source)
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
+ target = paint(BufferedImage.new(image.width, image.height, RGB)) do |g|
+ g.draw_image image, 0, 0, nil
+ end
block_given? ? yield(target) : target
rescue java.io.IOException, java.net.MalformedURLException
raise ArgumentError.new "Trouble retrieving image: #{$!.message}"
end
@@ -349,20 +334,34 @@
#
# Determines the best colorspace for a new image based on whether the
# existing image contains an alpha channel or not.
#
def color_type
- return BufferedImage::TYPE_INT_ARGB if @src.color_model.has_alpha
- BufferedImage::TYPE_INT_RGB
+ @src.color_model.has_alpha ? ARGB : RGB
end
#
+ # DRY up drawing setup+teardown
+ #
+ def paint(src=dup_src)
+ yield src.graphics
+ src.graphics.dispose
+ ImageVoodoo.new src
+ end
+
+ #
+ # Make a duplicate of the underlying Java src image
+ #
+ def dup_src
+ BufferedImage.new width, height, color_type
+ end
+
+ #
# Do simple AWT operation transformation to target.
#
- 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
+ def internal_transform(operation, target=dup_src)
+ paint(target) do |g|
+ g.draw_image(@src, 0, 0, nil)
+ g.draw_image(operation.filter(target, nil), 0, 0, nil)
+ end
end
end