image_voodoo 0.8.2 → 0.8.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/History.txt +14 -0
- data/{README.txt → README.md} +16 -7
- data/bin/image_voodoo +7 -3
- data/lib/image_voodoo.rb +43 -4
- data/lib/image_voodoo/awt.rb +112 -79
- data/lib/image_voodoo/awt/shapes.rb +47 -0
- data/lib/image_voodoo/gae.rb +5 -4
- data/lib/image_voodoo/version.rb +1 -1
- data/samples/file_view.rb +1 -4
- data/samples/lossy.rb +10 -0
- metadata +52 -59
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a9243b6d594469a7eebc05a90f3291fedeb889ef
|
4
|
+
data.tar.gz: fe2365817b840e5207b164037f59f88d6d27a752
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 1c7aa69a18b2675ed80522d0a114313fe76684e4af47f1c4f2f055fbb603de23f61b8ace562a5837d3546c959ee14e3e92b0e38c6122131282f2be1fc3b79038
|
7
|
+
data.tar.gz: cb704e65beb74228b77fcdfdaf8165e21721e32aee230a00a789ed212bd95264ea0688885f9ae6ce0ebac8a06b805c68199299147563ccfcb0eaa4f00cc872d4
|
data/History.txt
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
== 0.8.3
|
2
|
+
|
3
|
+
- NEGATE_OP does not hit all valid values
|
4
|
+
- src_dup was making new empty image instead of dup'ing image data
|
5
|
+
- new shape support for writing shapes on images (see shapes.rb under awt)
|
6
|
+
|
7
|
+
== 0.8.2
|
8
|
+
|
9
|
+
- My mind experiment to see how releases affect perception
|
10
|
+
|
11
|
+
== 0.8.1
|
12
|
+
|
13
|
+
- Convert from hoe to using bundler for gem releasing
|
14
|
+
|
1
15
|
== 0.8.0
|
2
16
|
|
3
17
|
- Fix "too big for byte: 253" error
|
data/{README.txt → README.md}
RENAMED
@@ -1,20 +1,20 @@
|
|
1
|
-
|
1
|
+
# ImageVoodoo
|
2
2
|
|
3
|
-
|
3
|
+
## DESCRIPTION:
|
4
4
|
|
5
5
|
ImageVoodoo is an Image manipulation library with a ImageScience-compatible API
|
6
6
|
for JRuby.
|
7
7
|
|
8
|
-
http://jruby-extras.rubyforge.org/image_voodoo/
|
9
8
|
http://github.com/jruby/image_voodoo
|
10
9
|
|
11
|
-
|
10
|
+
## FEATURES/PROBLEMS:
|
12
11
|
|
13
12
|
* Uses java.awt and javax.image APIs native to Java to perform image manipulation; no other dependencies needed.
|
14
13
|
* Includes image_voodoo command-line utility for quick resizing of images, "image_voodoo --help" for usage.
|
15
14
|
|
16
|
-
|
15
|
+
## SYNOPSIS:
|
17
16
|
|
17
|
+
```ruby
|
18
18
|
ImageVoodoo.with_image(ARGV[0]) do |img|
|
19
19
|
img.cropped_thumbnail(100) { |img2| img2.save "CTH.jpg" }
|
20
20
|
img.with_crop(100, 200, 400, 600) { |img2| img2.save "CR.jpg" }
|
@@ -23,13 +23,22 @@ http://github.com/jruby/image_voodoo
|
|
23
23
|
img2.save "HEH.jpg"
|
24
24
|
img2.save "HEH.png"
|
25
25
|
end
|
26
|
+
img.quality(0.75).save("reduced.jpg")
|
26
27
|
end
|
28
|
+
```
|
27
29
|
|
30
|
+
image_voodoo can also be run from the commandline:
|
28
31
|
|
29
|
-
|
32
|
+
```text
|
33
|
+
% image_voodoo -p a.gif --thumbnail 50 -p --save a_thumb.gif
|
34
|
+
```
|
35
|
+
|
36
|
+
In this command-line you will preview a.gif which will pop up a rendered a.gif on your screen; Then you will scale your image to a thumb to a 50 pixel size; then preview the new thumbnail image; then save it to a_thumb.gif. The CLI tool uses the same names as the API and can be a very handly command-line tool.
|
37
|
+
|
38
|
+
## REQUIREMENTS:
|
30
39
|
|
31
40
|
* JRuby
|
32
41
|
|
33
|
-
|
42
|
+
## INSTALL:
|
34
43
|
|
35
44
|
* jruby -S gem install image_voodoo
|
data/bin/image_voodoo
CHANGED
@@ -16,7 +16,7 @@ opts = OptionParser.new do |opts|
|
|
16
16
|
opts.separator " image_voodoo --dim small.jpg"
|
17
17
|
opts.separator ""
|
18
18
|
opts.separator " # Convert to a thumbnail, preview, and then save the result"
|
19
|
-
opts.separator " image_voodoo --
|
19
|
+
opts.separator " image_voodoo --thumbnail 50 --preview --save thumb.png large.jpg"
|
20
20
|
opts.separator ""
|
21
21
|
opts.separator " # Convert source to 3 thumbnails, showing dimensions and"
|
22
22
|
opts.separator " # previewing along the way"
|
@@ -35,13 +35,13 @@ opts = OptionParser.new do |opts|
|
|
35
35
|
end
|
36
36
|
|
37
37
|
opts.on("-b", "--brightness SCALE,OFFSET", "Adjust brightness") do |args|
|
38
|
-
scale, offset = args.split(
|
38
|
+
scale, offset = args.split(/,/).map {|v| v.to_f}
|
39
39
|
opts.usage "You need to specify proper scale and offset" unless scale && offset
|
40
40
|
actions << lambda {|img| img.adjust_brightness(scale, offset) }
|
41
41
|
end
|
42
42
|
|
43
43
|
opts.on("-B", "--border WIDTH,COLOR,STYLE", "Add a simple border") do |args|
|
44
|
-
width, color, style = args.split(
|
44
|
+
width, color, style = args.split(/,/)
|
45
45
|
options = {:width => width, :color => color, :style => style }
|
46
46
|
|
47
47
|
actions << lambda {|img| img.add_border(options) }
|
@@ -63,6 +63,10 @@ opts = OptionParser.new do |opts|
|
|
63
63
|
actions << lambda {|img| img.negative }
|
64
64
|
end
|
65
65
|
|
66
|
+
opts.on("-q", "--quality 0..1", Float, "Set % of quality for lossy compression") do |quality|
|
67
|
+
actions << lambda {|img| img.quality(quality) }
|
68
|
+
end
|
69
|
+
|
66
70
|
opts.on("-s", "--save FILENAME", "Save the results to a new file") do |f|
|
67
71
|
actions << lambda {|img| img.save(f); img }
|
68
72
|
end
|
data/lib/image_voodoo.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
##
|
1
2
|
#
|
2
3
|
# = ImageVoodoo
|
3
4
|
# == Description
|
@@ -25,10 +26,13 @@
|
|
25
26
|
# negative_img = img.negative
|
26
27
|
#
|
27
28
|
class ImageVoodoo
|
29
|
+
attr_accessor :quality
|
30
|
+
|
28
31
|
include Java
|
29
32
|
|
30
33
|
JFile = java.io.File
|
31
34
|
|
35
|
+
##
|
32
36
|
# FIXME: This has an issue when used in test/unit where the classcastexception
|
33
37
|
# is throwing the stack trace to output. This does not happen when used
|
34
38
|
# directly. Not sure....
|
@@ -42,8 +46,10 @@ class ImageVoodoo
|
|
42
46
|
|
43
47
|
def initialize(src)
|
44
48
|
@src = src
|
49
|
+
@quality = nil # nil means no specific quality ever specified
|
45
50
|
end
|
46
51
|
|
52
|
+
##
|
47
53
|
#
|
48
54
|
# Adjusts the brightness of each pixel in image by the following formula:
|
49
55
|
# new_pixel = pixel * scale + offset
|
@@ -52,7 +58,8 @@ class ImageVoodoo
|
|
52
58
|
image = guard { adjust_brightness_impl(scale, offset) }
|
53
59
|
block_given? ? yield(image) : image
|
54
60
|
end
|
55
|
-
|
61
|
+
|
62
|
+
##
|
56
63
|
#
|
57
64
|
# Converts rgb hex color value to an alpha value an yields/returns the new
|
58
65
|
# image.
|
@@ -62,6 +69,7 @@ class ImageVoodoo
|
|
62
69
|
block_given? ? yield(target) : target
|
63
70
|
end
|
64
71
|
|
72
|
+
##
|
65
73
|
#
|
66
74
|
# Get current image bytes as a String using provided format. Format parameter
|
67
75
|
# is the informal name of an image type - for instance,
|
@@ -73,6 +81,7 @@ class ImageVoodoo
|
|
73
81
|
String.from_java_bytes java_bytes
|
74
82
|
end
|
75
83
|
|
84
|
+
##
|
76
85
|
#
|
77
86
|
# Creates a square thumbnail of the image cropping the longest edge to
|
78
87
|
# match the shortest edge, resizes to size, and yields/returns the new image.
|
@@ -86,6 +95,7 @@ class ImageVoodoo
|
|
86
95
|
block_given? ? yield(target) : target
|
87
96
|
end
|
88
97
|
|
98
|
+
##
|
89
99
|
#
|
90
100
|
# Flips the image horizontally and yields/returns the new image.
|
91
101
|
#
|
@@ -94,6 +104,7 @@ class ImageVoodoo
|
|
94
104
|
block_given? ? yield(target) : target
|
95
105
|
end
|
96
106
|
|
107
|
+
##
|
97
108
|
#
|
98
109
|
# Flips the image vertically and yields/returns the new image.
|
99
110
|
#
|
@@ -102,6 +113,7 @@ class ImageVoodoo
|
|
102
113
|
block_given? ? yield(target) : target
|
103
114
|
end
|
104
115
|
|
116
|
+
##
|
105
117
|
#
|
106
118
|
# Creates a grayscale version of image and yields/returns the new image.
|
107
119
|
#
|
@@ -111,6 +123,7 @@ class ImageVoodoo
|
|
111
123
|
end
|
112
124
|
alias_method :grayscale, :greyscale
|
113
125
|
|
126
|
+
##
|
114
127
|
#
|
115
128
|
# Creates a negative and yields/returns the new image.
|
116
129
|
#
|
@@ -119,6 +132,22 @@ class ImageVoodoo
|
|
119
132
|
block_given? ? yield(target) : target
|
120
133
|
end
|
121
134
|
|
135
|
+
##
|
136
|
+
#
|
137
|
+
# Set quality you want resulting image to be once you save or extract
|
138
|
+
# bytes for the image. Note: This will only work for lossy image
|
139
|
+
# formats like PNG of JPEG. For others it will be ignored.
|
140
|
+
def quality(amount)
|
141
|
+
if amount < 0.0 || amount > 1.0
|
142
|
+
raise ArgumentError.new "Quality must be between 0.0 and 1.0"
|
143
|
+
end
|
144
|
+
|
145
|
+
target = self.dup
|
146
|
+
target.quality = amount
|
147
|
+
block_given? ? yield(target) : target
|
148
|
+
end
|
149
|
+
|
150
|
+
##
|
122
151
|
#
|
123
152
|
# Resizes the image to width and height and yields/returns the new image.
|
124
153
|
#
|
@@ -129,6 +158,7 @@ class ImageVoodoo
|
|
129
158
|
raise ArgumentError, ne.message
|
130
159
|
end
|
131
160
|
|
161
|
+
##
|
132
162
|
#
|
133
163
|
# Saves the image out to path. Changing the file extension will convert
|
134
164
|
# the file type to the appropriate format.
|
@@ -141,6 +171,7 @@ class ImageVoodoo
|
|
141
171
|
true
|
142
172
|
end
|
143
173
|
|
174
|
+
##
|
144
175
|
#
|
145
176
|
# Resize (scale) the current image by the provided ratio and yield/return
|
146
177
|
# the new image.
|
@@ -151,6 +182,7 @@ class ImageVoodoo
|
|
151
182
|
block_given? ? yield(target) : target
|
152
183
|
end
|
153
184
|
|
185
|
+
##
|
154
186
|
#
|
155
187
|
# Creates a proportional thumbnail of the image scaled so its longest
|
156
188
|
# edge is resized to size and yields/returns the new image.
|
@@ -160,6 +192,7 @@ class ImageVoodoo
|
|
160
192
|
block_given? ? yield(target) : target
|
161
193
|
end
|
162
194
|
|
195
|
+
##
|
163
196
|
#
|
164
197
|
# Crops an image to left, top, right, and bottom and then yields/returns the
|
165
198
|
# new image.
|
@@ -169,15 +202,17 @@ class ImageVoodoo
|
|
169
202
|
block_given? ? yield(image) : image
|
170
203
|
end
|
171
204
|
|
205
|
+
##
|
172
206
|
#
|
173
207
|
# A top-level image loader opens path and then yields/returns the image.
|
174
208
|
#
|
175
|
-
def self.with_image(
|
176
|
-
raise ArgumentError, "file does not exist" unless File.file?(
|
177
|
-
image = guard { with_image_impl(JFile.new(
|
209
|
+
def self.with_image(path)
|
210
|
+
raise ArgumentError, "file does not exist" unless File.file?(path)
|
211
|
+
image = guard { with_image_impl(JFile.new(path)) }
|
178
212
|
image && block_given? ? yield(image) : image
|
179
213
|
end
|
180
214
|
|
215
|
+
##
|
181
216
|
#
|
182
217
|
# A top-level image loader reads bytes and then yields/returns the image.
|
183
218
|
#
|
@@ -191,6 +226,7 @@ class ImageVoodoo
|
|
191
226
|
alias_method :with_image_from_memory, :with_bytes
|
192
227
|
end
|
193
228
|
|
229
|
+
##
|
194
230
|
#
|
195
231
|
# *_impl providers only need provide the implementation if it can
|
196
232
|
# support it. Otherwise, this method will detect that the method is
|
@@ -207,6 +243,7 @@ class ImageVoodoo
|
|
207
243
|
ImageVoodoo.guard(&block)
|
208
244
|
end
|
209
245
|
|
246
|
+
##
|
210
247
|
#
|
211
248
|
# Returns the height of the image, in pixels.
|
212
249
|
#
|
@@ -214,6 +251,7 @@ class ImageVoodoo
|
|
214
251
|
@src.height
|
215
252
|
end
|
216
253
|
|
254
|
+
##
|
217
255
|
#
|
218
256
|
# Returns the width of the image, in pixels.
|
219
257
|
#
|
@@ -221,6 +259,7 @@ class ImageVoodoo
|
|
221
259
|
@src.width
|
222
260
|
end
|
223
261
|
|
262
|
+
##
|
224
263
|
#
|
225
264
|
# Returns the underlying Java class associated with this object. Note:
|
226
265
|
# Depending on whether you are using AWT or GAE/J you will get a totally
|
data/lib/image_voodoo/awt.rb
CHANGED
@@ -1,4 +1,8 @@
|
|
1
|
+
require 'image_voodoo/awt/shapes'
|
2
|
+
|
1
3
|
class ImageVoodoo
|
4
|
+
include ImageVoodoo::Shapes
|
5
|
+
|
2
6
|
java_import java.awt.RenderingHints
|
3
7
|
java_import java.awt.color.ColorSpace
|
4
8
|
java_import java.awt.geom.AffineTransform
|
@@ -10,18 +14,16 @@ class ImageVoodoo
|
|
10
14
|
java_import java.io.ByteArrayInputStream
|
11
15
|
java_import java.io.ByteArrayOutputStream
|
12
16
|
java_import javax.imageio.ImageIO
|
17
|
+
java_import javax.imageio.IIOImage
|
18
|
+
java_import javax.imageio.ImageWriteParam
|
19
|
+
java_import javax.imageio.stream.FileImageOutputStream
|
13
20
|
java_import javax.swing.JFrame
|
14
21
|
|
15
|
-
|
16
|
-
|
17
|
-
ARGB = BufferedImage::TYPE_INT_ARGB
|
18
|
-
RGB = BufferedImage::TYPE_INT_RGB
|
19
|
-
SCALE_SMOOTH = java.awt.Image::SCALE_SMOOTH
|
20
|
-
|
22
|
+
# FIXME: Move and rewrite in terms of new shape
|
23
|
+
##
|
21
24
|
#
|
22
|
-
# AWT
|
23
|
-
#
|
24
|
-
# options are supported:
|
25
|
+
# *AWT* (experimental) Add a border to the image and yield/return a new
|
26
|
+
# image. The following options are supported:
|
25
27
|
# - width: How thick is the border (default: 3)
|
26
28
|
# - color: Which color is the border (in rrggbb hex value)
|
27
29
|
# - style: etched, raised, plain (default: plain)
|
@@ -45,65 +47,7 @@ class ImageVoodoo
|
|
45
47
|
block_given? ? yield(target) : target
|
46
48
|
end
|
47
49
|
|
48
|
-
|
49
|
-
transform(RescaleOp.new(scale, offset, nil))
|
50
|
-
end
|
51
|
-
|
52
|
-
# AWT-only
|
53
|
-
def alpha_impl(rgb)
|
54
|
-
color = hex_to_color(rgb)
|
55
|
-
target = paint(BufferedImage.new(width, height, ARGB)) do |g|
|
56
|
-
g.set_composite(java.awt.AlphaComposite::Src)
|
57
|
-
g.draw_image(@src, nil, 0, 0)
|
58
|
-
0.upto(height-1) do |i|
|
59
|
-
0.upto(width-1) do |j|
|
60
|
-
target.setRGB(j, i, 0x8F1C1C) if target.getRGB(j, i) == color.getRGB
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
def bytes_impl(format)
|
67
|
-
out = ByteArrayOutputStream.new
|
68
|
-
ImageIO.write(@src, format, out)
|
69
|
-
out.to_byte_array
|
70
|
-
end
|
71
|
-
|
72
|
-
def flip_horizontally_impl
|
73
|
-
paint {|g| g.draw_image @src, 0, 0, width, height, width, 0, 0, height, nil}
|
74
|
-
end
|
75
|
-
|
76
|
-
def flip_vertically_impl
|
77
|
-
paint {|g| g.draw_image @src, 0, 0, width, height, 0, height, width, 0, nil}
|
78
|
-
end
|
79
|
-
|
80
|
-
def greyscale_impl
|
81
|
-
transform(GREY_OP)
|
82
|
-
end
|
83
|
-
|
84
|
-
def negative_impl
|
85
|
-
transform(NEGATIVE_OP)
|
86
|
-
end
|
87
|
-
|
88
|
-
def resize_impl(width, height)
|
89
|
-
paint(BufferedImage.new(width, height, color_type)) do |g|
|
90
|
-
scaled_image = @src.get_scaled_instance width, height, SCALE_SMOOTH
|
91
|
-
g.draw_image scaled_image, 0, 0, nil
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
#
|
96
|
-
# Save using the format string (jpg, gif, etc..) to the open Java File
|
97
|
-
# instance passed in.
|
98
|
-
#
|
99
|
-
def save_impl(format, file)
|
100
|
-
ImageIO.write(@src, format, file)
|
101
|
-
end
|
102
|
-
|
103
|
-
def with_crop_impl(left, top, right, bottom)
|
104
|
-
ImageVoodoo.new @src.get_subimage(left, top, right-left, bottom-top)
|
105
|
-
end
|
106
|
-
|
50
|
+
##
|
107
51
|
#
|
108
52
|
# A simple swing wrapper around an image voodoo object.
|
109
53
|
#
|
@@ -127,6 +71,8 @@ class ImageVoodoo
|
|
127
71
|
end
|
128
72
|
end
|
129
73
|
|
74
|
+
ImageVoodoo::JImagePanel.__persistent__ = true
|
75
|
+
|
130
76
|
# Internal class for closing preview window
|
131
77
|
class WindowClosed
|
132
78
|
def initialize(block = nil)
|
@@ -136,8 +82,9 @@ class ImageVoodoo
|
|
136
82
|
def windowClosing(event); @block.call; end
|
137
83
|
end
|
138
84
|
|
85
|
+
##
|
139
86
|
#
|
140
|
-
# Creates a viewable frame displaying current image within it.
|
87
|
+
# *AWT* Creates a viewable frame displaying current image within it.
|
141
88
|
#
|
142
89
|
def preview(&block)
|
143
90
|
frame = JFrame.new("Preview")
|
@@ -147,6 +94,16 @@ class ImageVoodoo
|
|
147
94
|
frame.visible = true
|
148
95
|
end
|
149
96
|
|
97
|
+
##
|
98
|
+
# *AWT* paint/render to the source
|
99
|
+
#
|
100
|
+
def paint(src=dup_src)
|
101
|
+
yield src.graphics
|
102
|
+
src.graphics.dispose
|
103
|
+
ImageVoodoo.new src
|
104
|
+
end
|
105
|
+
|
106
|
+
##
|
150
107
|
#
|
151
108
|
# TODO: Figure out how to determine whether source has alpha or not
|
152
109
|
# Experimental: Read an image from the url source and yield/return that
|
@@ -166,6 +123,22 @@ class ImageVoodoo
|
|
166
123
|
raise ArgumentError.new "Trouble retrieving image: #{$!.message}"
|
167
124
|
end
|
168
125
|
|
126
|
+
##
|
127
|
+
# *AWT* Create an image of width x height filled with a single color.
|
128
|
+
#
|
129
|
+
def self.canvas(width, height, rgb='000000')
|
130
|
+
image = ImageVoodoo.new(BufferedImage.new(width, height, ARGB))
|
131
|
+
image.rect(0, 0, width, height, rgb)
|
132
|
+
end
|
133
|
+
|
134
|
+
private
|
135
|
+
|
136
|
+
NEGATIVE_OP = LookupOp.new(ShortLookupTable.new(0, (0...256).to_a.reverse.to_java(:short)), nil)
|
137
|
+
GREY_OP = ColorConvertOp.new(ColorSpace.getInstance(ColorSpace::CS_GRAY), nil)
|
138
|
+
ARGB = BufferedImage::TYPE_INT_ARGB
|
139
|
+
RGB = BufferedImage::TYPE_INT_RGB
|
140
|
+
SCALE_SMOOTH = java.awt.Image::SCALE_SMOOTH
|
141
|
+
|
169
142
|
def self.with_image_impl(file)
|
170
143
|
buffered_image = ImageIO.read(file)
|
171
144
|
buffered_image ? ImageVoodoo.new(buffered_image) : nil
|
@@ -175,13 +148,11 @@ class ImageVoodoo
|
|
175
148
|
ImageVoodoo.new ImageIO.read(ByteArrayInputStream.new(bytes))
|
176
149
|
end
|
177
150
|
|
178
|
-
private
|
179
|
-
|
180
151
|
#
|
181
152
|
# Converts a RGB hex value into a java.awt.Color object or dies trying
|
182
153
|
# with an ArgumentError.
|
183
154
|
#
|
184
|
-
def hex_to_color(rgb)
|
155
|
+
def self.hex_to_color(rgb)
|
185
156
|
raise ArgumentError.new "hex rrggbb needed" if rgb !~ /[[:xdigit:]]{6,6}/
|
186
157
|
|
187
158
|
java.awt.Color.new(rgb[0,2].to_i(16), rgb[2,2].to_i(16), rgb[4,2].to_i(16))
|
@@ -199,7 +170,7 @@ class ImageVoodoo
|
|
199
170
|
# Make a duplicate of the underlying Java src image
|
200
171
|
#
|
201
172
|
def dup_src
|
202
|
-
BufferedImage.new
|
173
|
+
BufferedImage.new to_java.color_model, to_java.raster, true, nil
|
203
174
|
end
|
204
175
|
|
205
176
|
#
|
@@ -212,12 +183,74 @@ class ImageVoodoo
|
|
212
183
|
end
|
213
184
|
end
|
214
185
|
|
186
|
+
def adjust_brightness_impl(scale, offset)
|
187
|
+
transform(RescaleOp.new(scale, offset, nil))
|
188
|
+
end
|
189
|
+
|
190
|
+
def alpha_impl(rgb)
|
191
|
+
color = hex_to_color(rgb)
|
192
|
+
target = paint(BufferedImage.new(width, height, ARGB)) do |g|
|
193
|
+
g.set_composite(java.awt.AlphaComposite::Src)
|
194
|
+
g.draw_image(@src, nil, 0, 0)
|
195
|
+
0.upto(height-1) do |i|
|
196
|
+
0.upto(width-1) do |j|
|
197
|
+
target.setRGB(j, i, 0x8F1C1C) if target.getRGB(j, i) == color.getRGB
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
def bytes_impl(format)
|
204
|
+
out = ByteArrayOutputStream.new
|
205
|
+
write_new_image format, out
|
206
|
+
out.to_byte_array
|
207
|
+
end
|
208
|
+
|
209
|
+
def flip_horizontally_impl
|
210
|
+
paint {|g| g.draw_image @src, 0, 0, width, height, width, 0, 0, height, nil}
|
211
|
+
end
|
212
|
+
|
213
|
+
def flip_vertically_impl
|
214
|
+
paint {|g| g.draw_image @src, 0, 0, width, height, 0, height, width, 0, nil}
|
215
|
+
end
|
216
|
+
|
217
|
+
def greyscale_impl
|
218
|
+
transform(GREY_OP)
|
219
|
+
end
|
220
|
+
|
221
|
+
def negative_impl
|
222
|
+
transform(NEGATIVE_OP)
|
223
|
+
end
|
224
|
+
|
225
|
+
def resize_impl(width, height)
|
226
|
+
paint(BufferedImage.new(width, height, color_type)) do |g|
|
227
|
+
scaled_image = @src.get_scaled_instance width, height, SCALE_SMOOTH
|
228
|
+
g.draw_image scaled_image, 0, 0, nil
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
215
232
|
#
|
216
|
-
#
|
217
|
-
#
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
233
|
+
# Save using the format string (jpg, gif, etc..) to the open Java File
|
234
|
+
# instance passed in.
|
235
|
+
#
|
236
|
+
def save_impl(format, file)
|
237
|
+
write_new_image format, FileImageOutputStream.new(file)
|
238
|
+
end
|
239
|
+
|
240
|
+
def with_crop_impl(left, top, right, bottom)
|
241
|
+
ImageVoodoo.new @src.get_subimage(left, top, right-left, bottom-top)
|
242
|
+
end
|
243
|
+
|
244
|
+
def write_new_image(format, stream)
|
245
|
+
writer = ImageIO.getImageWritersByFormatName(format).next
|
246
|
+
writer.output = stream
|
247
|
+
|
248
|
+
param = writer.default_write_param
|
249
|
+
if param.can_write_compressed && @quality
|
250
|
+
param.compression_mode = ImageWriteParam::MODE_EXPLICIT
|
251
|
+
param.compression_quality = @quality
|
252
|
+
end
|
253
|
+
|
254
|
+
writer.write nil, IIOImage.new(@src, nil, nil), param
|
222
255
|
end
|
223
256
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
class ImageVoodoo
|
2
|
+
module Shapes
|
3
|
+
##
|
4
|
+
# *AWT* Draw a square
|
5
|
+
#
|
6
|
+
def square(x, y, dim, rgb, fill=true)
|
7
|
+
square_rounded(x, y, dim, rgb, 0, fill)
|
8
|
+
end
|
9
|
+
|
10
|
+
##
|
11
|
+
# *AWT* Draw a rectangle
|
12
|
+
#
|
13
|
+
def rect(x, y, width, height, rgb, fill=true)
|
14
|
+
rect_rounded(x, y, width, height, rgb, 0, 0, fill)
|
15
|
+
end
|
16
|
+
|
17
|
+
##
|
18
|
+
# *AWT* Draw a rounded square
|
19
|
+
#
|
20
|
+
def square_rounded(x, y, dim, rgb, arc_width=0, fill=true)
|
21
|
+
rect_rounded(x,y, dim, dim, rgb, arc_width, arc_width, fill)
|
22
|
+
end
|
23
|
+
|
24
|
+
##
|
25
|
+
# *AWT* Draw a rounded rectangle
|
26
|
+
#
|
27
|
+
def rect_rounded(x, y, width, height, rgb, arc_width=0, arc_height=0, fill=true)
|
28
|
+
as_color(ImageVoodoo.hex_to_color(rgb)) do |g|
|
29
|
+
if fill
|
30
|
+
g.fill_round_rect x, y, width, height, arc_width, arc_height
|
31
|
+
else
|
32
|
+
g.draw_round_rect x, y, width, height, arc_width, arc_height
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def as_color(color)
|
38
|
+
paint do |g|
|
39
|
+
old_color = g.color
|
40
|
+
g.color = color
|
41
|
+
yield g
|
42
|
+
g.color = old_color
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
data/lib/image_voodoo/gae.rb
CHANGED
@@ -10,8 +10,8 @@ class ImageVoodoo
|
|
10
10
|
# Value Add methods for this backend
|
11
11
|
#++
|
12
12
|
|
13
|
-
|
14
|
-
#GAE
|
13
|
+
##
|
14
|
+
# *GAE* Automatically adjust contrast and color levels.
|
15
15
|
def i_am_feeling_lucky
|
16
16
|
transform(ImagesServiceFactory.make_im_feeling_lucky)
|
17
17
|
end
|
@@ -19,10 +19,13 @@ class ImageVoodoo
|
|
19
19
|
#--
|
20
20
|
# Implementations of standard features
|
21
21
|
#++
|
22
|
+
|
23
|
+
private
|
22
24
|
|
23
25
|
def flip_horizontally_impl
|
24
26
|
transform(ImagesServiceFactory.make_horizontal_flip)
|
25
27
|
end
|
28
|
+
private :flip_horizontally_impl
|
26
29
|
|
27
30
|
def flip_vertically_impl
|
28
31
|
transform(ImagesServiceFactory.make_vertical_flip)
|
@@ -40,8 +43,6 @@ class ImageVoodoo
|
|
40
43
|
ImageVoodoo.new ImageServicesFactory.make_image(bytes)
|
41
44
|
end
|
42
45
|
|
43
|
-
private
|
44
|
-
|
45
46
|
def from_java_bytes
|
46
47
|
String.from_java_bytes @src.image_data
|
47
48
|
end
|
data/lib/image_voodoo/version.rb
CHANGED
data/samples/file_view.rb
CHANGED
data/samples/lossy.rb
ADDED
metadata
CHANGED
@@ -1,77 +1,70 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: image_voodoo
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
version: 0.8.2
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.8.3
|
6
5
|
platform: ruby
|
7
|
-
authors:
|
8
|
-
|
6
|
+
authors:
|
7
|
+
- Thomas E. Enebo, Charles Nutter, Nick Sieger
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
|
13
|
-
date: 2012-05-01 00:00:00 Z
|
11
|
+
date: 2014-08-08 00:00:00.000000000 Z
|
14
12
|
dependencies: []
|
15
|
-
|
16
13
|
description: Image manipulation in JRuby with ImageScience compatible API
|
17
14
|
email: tom.enebo@gmail.com
|
18
|
-
executables:
|
19
|
-
|
15
|
+
executables:
|
16
|
+
- image_voodoo
|
20
17
|
extensions: []
|
21
|
-
|
22
18
|
extra_rdoc_files: []
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
19
|
+
files:
|
20
|
+
- ".gitignore"
|
21
|
+
- ".hgignore"
|
22
|
+
- ".hgtags"
|
23
|
+
- History.txt
|
24
|
+
- LICENSE.txt
|
25
|
+
- Manifest.txt
|
26
|
+
- README.md
|
27
|
+
- Rakefile
|
28
|
+
- bin/image_voodoo
|
29
|
+
- image_voodoo.gemspec
|
30
|
+
- lib/image_science.rb
|
31
|
+
- lib/image_voodoo.rb
|
32
|
+
- lib/image_voodoo/awt.rb
|
33
|
+
- lib/image_voodoo/awt/shapes.rb
|
34
|
+
- lib/image_voodoo/gae.rb
|
35
|
+
- lib/image_voodoo/version.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
|
+
- samples/lossy.rb
|
43
|
+
- test/pix.png
|
44
|
+
- test/test_image_science.rb
|
48
45
|
homepage: http://github.com/jruby/image_voodoo
|
49
46
|
licenses: []
|
50
|
-
|
47
|
+
metadata: {}
|
51
48
|
post_install_message:
|
52
49
|
rdoc_options: []
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
- - ">="
|
66
|
-
- !ruby/object:Gem::Version
|
67
|
-
version: "0"
|
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
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
68
62
|
requirements: []
|
69
|
-
|
70
63
|
rubyforge_project: image_voodoo
|
71
|
-
rubygems_version:
|
64
|
+
rubygems_version: 2.2.2
|
72
65
|
signing_key:
|
73
|
-
specification_version:
|
66
|
+
specification_version: 4
|
74
67
|
summary: Image manipulation in JRuby with ImageScience compatible API
|
75
|
-
test_files:
|
76
|
-
|
77
|
-
|
68
|
+
test_files:
|
69
|
+
- test/pix.png
|
70
|
+
- test/test_image_science.rb
|