Class: ImageVoodoo

Inherits:
Object
  • Object
show all
Includes:
Shapes, Java
Defined in:
lib/image_voodoo.rb,
lib/image_voodoo/awt.rb,
lib/image_voodoo/gae.rb,
lib/image_voodoo/version.rb,
lib/image_voodoo/awt/shapes.rb

Overview

ImageVoodoo

Description

ImageVoodoo is an ImageScience-API-compatible image manipulation library for JRuby.

Examples

Simple block-based examples

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

Non-block return (not image_science compatible)

img = ImageVoodoo.with_image(ARGV) negative_img = img.negative

Defined Under Namespace

Modules: Shapes Classes: JImagePanel, WindowClosed

Constant Summary collapse

JFile =
java.io.File
ImageService =
ImagesServiceFactory.images_service
VERSION =
"0.8.3"

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Shapes

#as_color, #rect, #rect_rounded, #square, #square_rounded

Constructor Details

#initialize(src) ⇒ ImageVoodoo

Returns a new instance of ImageVoodoo.



47
48
49
50
# File 'lib/image_voodoo.rb', line 47

def initialize(src)
  @src = src
  @quality = nil # nil means no specific quality ever specified
end

Instance Attribute Details

#quality(amount) ⇒ Object

Set quality you want resulting image to be once you save or extract bytes for the image. Note: This will only work for lossy image formats like PNG of JPEG. For others it will be ignored.



140
141
142
# File 'lib/image_voodoo.rb', line 140

def quality
  @quality
end

Class Method Details

.canvas(width, height, rgb = '000000') ⇒ Object

AWT Create an image of width x height filled with a single color.



129
130
131
132
# File 'lib/image_voodoo/awt.rb', line 129

def self.canvas(width, height, rgb='000000')
  image = ImageVoodoo.new(BufferedImage.new(width, height, ARGB))
  image.rect(0, 0, width, height, rgb)
end

.from_url(source) ⇒ Object

TODO: Figure out how to determine whether source has alpha or not Experimental: Read an image from the url source and yield/return that image.



112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/image_voodoo/awt.rb', line 112

def self.from_url(source)
  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 = 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

.guard(&block) ⇒ Object

*_impl providers only need provide the implementation if it can support it. Otherwise, this method will detect that the method is missing.



235
236
237
238
239
240
241
# File 'lib/image_voodoo.rb', line 235

def self.guard(&block)
  begin
    return block.call
  rescue NoMethodError => e
    "Unimplemented Feature: #{e}"
  end
end

.with_bytes(bytes) ⇒ Object Also known as: with_image_from_memory

A top-level image loader reads bytes and then yields/returns the image.



219
220
221
222
223
# File 'lib/image_voodoo.rb', line 219

def self.with_bytes(bytes)
  bytes = bytes.to_java_bytes if String === bytes
  image = guard { with_bytes_impl(bytes) }
  block_given? ? yield(image) : image
end

.with_image(path) ⇒ Object

A top-level image loader opens path and then yields/returns the image.

Raises:

  • (ArgumentError)


209
210
211
212
213
# File 'lib/image_voodoo.rb', line 209

def self.with_image(path)
  raise ArgumentError, "file does not exist" unless File.file?(path)
  image = guard { with_image_impl(JFile.new(path)) }
  image && block_given? ? yield(image) : image
end

Instance Method Details

#add_border(options = {}) ⇒ Object

FIXME: Move and rewrite in terms of new shape

AWT (experimental) Add a border to the image and yield/return a new image. The following options are supported:

- width: How thick is the border (default: 3)
- color: Which color is the border (in rrggbb hex value) 
- style: etched, raised, plain (default: plain)


31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/image_voodoo/awt.rb', line 31

def add_border(options = {})
  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 = 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
  block_given? ? yield(target) : target
end

#adjust_brightness(scale, offset) ⇒ Object

Adjusts the brightness of each pixel in image by the following formula: new_pixel = pixel * scale + offset



57
58
59
60
# File 'lib/image_voodoo.rb', line 57

def adjust_brightness(scale, offset)
  image = guard { adjust_brightness_impl(scale, offset) }
  block_given? ? yield(image) : image
end

#alpha(rgb) ⇒ Object

Converts rgb hex color value to an alpha value an yields/returns the new image.



67
68
69
70
# File 'lib/image_voodoo.rb', line 67

def alpha(rgb)
  target = guard { alpha_impl(rgb) }
  block_given? ? yield(target) : target
end

#bytes(format) ⇒ Object

Get current image bytes as a String using provided format. Format parameter is the informal name of an image type - for instance, “bmp” or “jpg”. If the backend is AWT the types available are listed in javax.imageio.ImageIO.getWriterFormatNames()



79
80
81
82
# File 'lib/image_voodoo.rb', line 79

def bytes(format)
  java_bytes = guard { bytes_impl(format) }
  String.from_java_bytes java_bytes
end

#cropped_thumbnail(size) ⇒ Object

Creates a square thumbnail of the image cropping the longest edge to match the shortest edge, resizes to size, and yields/returns the new image.



89
90
91
92
93
94
95
96
# File 'lib/image_voodoo.rb', line 89

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

  target = with_crop(l, t, r, b).thumbnail(size)
  block_given? ? yield(target) : target
end

#flip_horizontallyObject

Flips the image horizontally and yields/returns the new image.



102
103
104
105
# File 'lib/image_voodoo.rb', line 102

def flip_horizontally
  target = guard { flip_horizontally_impl }
  block_given? ? yield(target) : target
end

#flip_verticallyObject

Flips the image vertically and yields/returns the new image.



111
112
113
114
# File 'lib/image_voodoo.rb', line 111

def flip_vertically
  target = guard { flip_vertically_impl }
  block_given? ? yield(target) : target
end

#greyscaleObject Also known as: grayscale

Creates a grayscale version of image and yields/returns the new image.



120
121
122
123
# File 'lib/image_voodoo.rb', line 120

def greyscale
  target = guard { greyscale_impl }
  block_given? ? yield(target) : target
end

#guard(&block) ⇒ Object



242
243
244
# File 'lib/image_voodoo.rb', line 242

def guard(&block)
  ImageVoodoo.guard(&block)
end

#heightObject

Returns the height of the image, in pixels.



250
251
252
# File 'lib/image_voodoo.rb', line 250

def height
  @src.height
end

#i_am_feeling_luckyObject

GAE Automatically adjust contrast and color levels.



15
16
17
# File 'lib/image_voodoo/gae.rb', line 15

def i_am_feeling_lucky
  transform(ImagesServiceFactory.make_im_feeling_lucky)
end

#negativeObject

Creates a negative and yields/returns the new image.



130
131
132
133
# File 'lib/image_voodoo.rb', line 130

def negative
  target = guard { negative_impl }
  block_given? ? yield(target) : target
end

#paint(src = dup_src) {|src.graphics| ... } ⇒ Object

AWT paint/render to the source

Yields:

  • (src.graphics)


100
101
102
103
104
# File 'lib/image_voodoo/awt.rb', line 100

def paint(src=dup_src)
  yield src.graphics
  src.graphics.dispose
  ImageVoodoo.new src
end

#preview(&block) ⇒ Object

AWT Creates a viewable frame displaying current image within it.



89
90
91
92
93
94
95
# File 'lib/image_voodoo/awt.rb', line 89

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(self, 10, 10)
  frame.visible = true
end

#resize(width, height) ⇒ Object

Resizes the image to width and height and yields/returns the new image.



154
155
156
157
158
159
# File 'lib/image_voodoo.rb', line 154

def resize(width, height)
  target = guard { resize_impl(width, height) }
  block_given? ? yield(target) : target
rescue NativeException => ne
  raise ArgumentError, ne.message
end

#save(file) ⇒ Object

Saves the image out to path. Changing the file extension will convert the file type to the appropriate format.



166
167
168
169
170
171
172
# File 'lib/image_voodoo.rb', line 166

def save(file)
  format = File.extname(file)
  return false if format == ""
  format = format[1..-1].downcase
  guard { save_impl(format, JFile.new(file)) }
  true
end

#scale(ratio) ⇒ Object

Resize (scale) the current image by the provided ratio and yield/return the new image.



179
180
181
182
183
# File 'lib/image_voodoo.rb', line 179

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

#thumbnail(size) ⇒ Object

Creates a proportional thumbnail of the image scaled so its longest edge is resized to size and yields/returns the new image.



190
191
192
193
# File 'lib/image_voodoo.rb', line 190

def thumbnail(size)
  target = scale(size.to_f / (width > height ? width : height))
  block_given? ? yield(target) : target
end

#to_javaObject

Returns the underlying Java class associated with this object. Note: Depending on whether you are using AWT or GAE/J you will get a totally different Java class. So caveat emptor!



268
269
270
# File 'lib/image_voodoo.rb', line 268

def to_java
  @src
end

#widthObject

Returns the width of the image, in pixels.



258
259
260
# File 'lib/image_voodoo.rb', line 258

def width
  @src.width
end

#with_crop(left, top, right, bottom) ⇒ Object

Crops an image to left, top, right, and bottom and then yields/returns the new image.



200
201
202
203
# File 'lib/image_voodoo.rb', line 200

def with_crop(left, top, right, bottom)
  image = guard { with_crop_impl(left, top, right, bottom) }
  block_given? ? yield(image) : image
end