image_voodoo 0.8.2 → 0.8.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|