rmagick4j 0.3.4-java → 0.3.9-java
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 +84 -0
- data/LICENSE.txt +31 -0
- data/README.txt +25 -0
- data/Rakefile +65 -0
- data/lib/magick4j.jar +0 -0
- data/lib/{RMagick.rb → rmagick.rb} +574 -405
- data/lib/rmagick4j/constants.rb +34 -0
- data/lib/rmagick4j/draw.rb +124 -0
- data/lib/rmagick4j/enum.rb +120 -0
- data/lib/rmagick4j/gradient_fill.rb +14 -0
- data/lib/rmagick4j/image.rb +351 -0
- data/lib/rmagick4j/image_list.rb +25 -0
- data/lib/rmagick4j/pixel.rb +170 -0
- data/lib/rmagick4j/rmagick4j.rb +15 -430
- data/lib/rmagick4j/texture_fill.rb +14 -0
- data/lib/rmagick4j/type_metric.rb +8 -0
- data/lib/rmagick4j/version.rb +5 -0
- data/lib/rvg/clippath.rb +2 -2
- data/lib/rvg/container.rb +2 -2
- data/lib/rvg/describable.rb +2 -2
- data/lib/rvg/embellishable.rb +2 -2
- data/lib/rvg/misc.rb +3 -3
- data/lib/rvg/paint.rb +7 -2
- data/lib/rvg/pathdata.rb +2 -2
- data/lib/rvg/rvg.rb +3 -3
- data/lib/rvg/stretchable.rb +15 -3
- data/lib/rvg/stylable.rb +2 -2
- data/lib/rvg/text.rb +2 -2
- data/lib/rvg/transformable.rb +2 -2
- data/lib/rvg/units.rb +2 -2
- data/test/RMagickTestSuite.rb +129 -0
- data/test/eyetests/bullseye.rb +151 -0
- data/test/eyetests/doc.rb +79 -0
- data/test/eyetests/tests/draw_arc_basic.rb +16 -0
- data/test/eyetests/tests/draw_circle_affine.rb +19 -0
- data/test/eyetests/tests/draw_circle_basic.rb +16 -0
- data/test/eyetests/tests/draw_clip_path.rb +44 -0
- data/test/eyetests/tests/draw_ellipse_affine.rb +19 -0
- data/test/eyetests/tests/draw_ellipse_basic.rb +16 -0
- data/test/eyetests/tests/draw_line_affine.rb +24 -0
- data/test/eyetests/tests/draw_line_basic.rb +21 -0
- data/test/eyetests/tests/draw_multiline_type_metrics.rb +42 -0
- data/test/eyetests/tests/draw_pattern_1.rb +35 -0
- data/test/eyetests/tests/draw_polygon_affine.rb +22 -0
- data/test/eyetests/tests/draw_polygon_basic.rb +19 -0
- data/test/eyetests/tests/draw_polyline_affine.rb +19 -0
- data/test/eyetests/tests/draw_polyline_basic.rb +18 -0
- data/test/eyetests/tests/draw_pop_push.rb +16 -0
- data/test/eyetests/tests/draw_pop_push_translate.rb +22 -0
- data/test/eyetests/tests/draw_rectangle_affine.rb +16 -0
- data/test/eyetests/tests/draw_rectangle_basic.rb +16 -0
- data/test/eyetests/tests/draw_rectangle_narrow.rb +18 -0
- data/test/eyetests/tests/draw_rmagick_test_01.rb +35 -0
- data/test/eyetests/tests/draw_rmagick_test_02.rb +40 -0
- data/test/eyetests/tests/draw_rmagick_test_03.rb +17 -0
- data/test/eyetests/tests/draw_rmagick_test_04.rb +21 -0
- data/test/eyetests/tests/draw_rotate_01.rb +33 -0
- data/test/eyetests/tests/draw_roundrectangle_affine.rb +19 -0
- data/test/eyetests/tests/draw_roundrectangle_basic.rb +16 -0
- data/test/eyetests/tests/draw_scale_01.rb +33 -0
- data/test/eyetests/tests/draw_skewx_01.rb +34 -0
- data/test/eyetests/tests/draw_skewy_01.rb +33 -0
- data/test/eyetests/tests/draw_stroke_miterlimit.rb +21 -0
- data/test/eyetests/tests/effect_blur.rb +9 -0
- data/test/eyetests/tests/effect_charcoal.rb +9 -0
- data/test/eyetests/tests/effect_edge.rb +9 -0
- data/test/eyetests/tests/effect_implode.rb +9 -0
- data/test/eyetests/tests/effect_negate.rb +9 -0
- data/test/eyetests/tests/effect_negate_true.rb +9 -0
- data/test/eyetests/tests/effect_normalize.rb +9 -0
- data/test/eyetests/tests/effect_shade.rb +9 -0
- data/test/eyetests/tests/effect_solarize.rb +10 -0
- data/test/eyetests/tests/effect_wave.rb +9 -0
- data/test/eyetests/tests/gradient_fill_horizontal_diagonal_fill.rb +9 -0
- data/test/eyetests/tests/gradient_fill_horizontal_fill.rb +9 -0
- data/test/eyetests/tests/gradient_fill_point_fill.rb +9 -0
- data/test/eyetests/tests/gradient_fill_vertical_diagonal_fill.rb +9 -0
- data/test/eyetests/tests/gradient_fill_vertical_fill.rb +9 -0
- data/test/eyetests/tests/gruff_accumulator_bar.rb +29 -0
- data/test/eyetests/tests/gruff_area_1.rb +16 -0
- data/test/eyetests/tests/gruff_area_2.rb +27 -0
- data/test/eyetests/tests/gruff_bar_1.rb +29 -0
- data/test/eyetests/tests/gruff_bar_2.rb +19 -0
- data/test/eyetests/tests/gruff_dot_1.rb +19 -0
- data/test/eyetests/tests/gruff_line_1.rb +13 -0
- data/test/eyetests/tests/gruff_line_2.rb +20 -0
- data/test/eyetests/tests/gruff_net_1.rb +16 -0
- data/test/eyetests/tests/gruff_net_2.rb +16 -0
- data/test/eyetests/tests/gruff_pie_1.rb +21 -0
- data/test/eyetests/tests/gruff_pie_2.rb +22 -0
- data/test/eyetests/tests/gruff_scene_1.rb +14 -0
- data/test/eyetests/tests/gruff_scene_2.rb +14 -0
- data/test/eyetests/tests/gruff_sidebar.rb +32 -0
- data/test/eyetests/tests/gruff_sidestacked_bar_1.rb +26 -0
- data/test/eyetests/tests/gruff_sidestacked_bar_2.rb +26 -0
- data/test/eyetests/tests/gruff_spider_1.rb +22 -0
- data/test/eyetests/tests/gruff_spider_2.rb +15 -0
- data/test/eyetests/tests/gruff_stacked_area_1.rb +23 -0
- data/test/eyetests/tests/gruff_stacked_bar_1.rb +23 -0
- data/test/eyetests/tests/gruff_stacked_bar_2.rb +26 -0
- data/test/eyetests/tests/hatch_fill.rb +9 -0
- data/test/eyetests/tests/image_list_flatten_images.rb +15 -0
- data/test/eyetests/tests/new_image.rb +31 -0
- data/test/eyetests/tests/path_a_command_01.rb +16 -0
- data/test/eyetests/tests/path_a_command_02.rb +19 -0
- data/test/eyetests/tests/path_c_command_01.rb +16 -0
- data/test/eyetests/tests/path_c_command_02.rb +16 -0
- data/test/eyetests/tests/path_complex_01.rb +16 -0
- data/test/eyetests/tests/path_espiral_01.rb +29 -0
- data/test/eyetests/tests/path_h_command_01.rb +16 -0
- data/test/eyetests/tests/path_h_command_02.rb +16 -0
- data/test/eyetests/tests/path_l_command_01.rb +16 -0
- data/test/eyetests/tests/path_l_command_02.rb +16 -0
- data/test/eyetests/tests/path_m_command_01.rb +16 -0
- data/test/eyetests/tests/path_m_command_02.rb +16 -0
- data/test/eyetests/tests/path_m_command_03.rb +16 -0
- data/test/eyetests/tests/path_q_command_01.rb +16 -0
- data/test/eyetests/tests/path_q_command_02.rb +16 -0
- data/test/eyetests/tests/path_q_command_03.rb +25 -0
- data/test/eyetests/tests/path_s_command_01.rb +16 -0
- data/test/eyetests/tests/path_s_command_02.rb +16 -0
- data/test/eyetests/tests/path_star_01.rb +19 -0
- data/test/eyetests/tests/path_t_command_01.rb +16 -0
- data/test/eyetests/tests/path_t_command_02.rb +16 -0
- data/test/eyetests/tests/path_v_command_01.rb +16 -0
- data/test/eyetests/tests/path_v_command_02.rb +16 -0
- data/test/eyetests/tests/store_pixel_smiley.rb +123 -0
- data/test/eyetests/tests/texture_fill.rb +11 -0
- data/test/gruff_tests/test/gruff_test_case.rb +123 -0
- data/test/gruff_tests/test/monkey_gruff.rb +7 -0
- data/test/gruff_tests/test/test_accumulator_bar.rb +50 -0
- data/test/gruff_tests/test/test_area.rb +134 -0
- data/test/gruff_tests/test/test_bar.rb +295 -0
- data/test/gruff_tests/test/test_base.rb +8 -0
- data/test/gruff_tests/test/test_bullet.rb +26 -0
- data/test/gruff_tests/test/test_dot.rb +273 -0
- data/test/gruff_tests/test/test_legend.rb +68 -0
- data/test/gruff_tests/test/test_line.rb +554 -0
- data/test/gruff_tests/test/test_mini_bar.rb +33 -0
- data/test/gruff_tests/test/test_mini_pie.rb +20 -0
- data/test/gruff_tests/test/test_mini_side_bar.rb +37 -0
- data/test/gruff_tests/test/test_net.rb +230 -0
- data/test/gruff_tests/test/test_photo.rb +41 -0
- data/test/gruff_tests/test/test_pie.rb +154 -0
- data/test/gruff_tests/test/test_scene.rb +100 -0
- data/test/gruff_tests/test/test_side_bar.rb +12 -0
- data/test/gruff_tests/test/test_sidestacked_bar.rb +89 -0
- data/test/gruff_tests/test/test_spider.rb +216 -0
- data/test/gruff_tests/test/test_stacked_area.rb +52 -0
- data/test/gruff_tests/test/test_stacked_bar.rb +52 -0
- data/test/images/clown.jpg +0 -0
- data/test/images/texture.jpg +0 -0
- data/test/implemented_methods.rb +18 -0
- data/test/spec/draw_spec.rb +43 -0
- data/test/spec/features/step_definitions/geometry_steps.rb +22 -0
- data/test/spec/features/step_definitions/image_filling_steps.rb +49 -0
- data/test/spec/features/support/env.rb +3 -0
- data/test/spec/image_constants.rb +76 -0
- data/test/spec/image_spec.rb +83 -0
- data/test/spec/pixel_spec.rb +89 -0
- metadata +333 -45
- data/lib/RMagick.jar +0 -0
- data/lib/jhlabs-filters.jar +0 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
|
|
2
|
+
module Magick
|
|
3
|
+
|
|
4
|
+
class ImageList < Array
|
|
5
|
+
|
|
6
|
+
def flatten_images
|
|
7
|
+
img = @images.map { |obj| obj._image }
|
|
8
|
+
|
|
9
|
+
image = img.inject do |memo, obj|
|
|
10
|
+
memo.flatten(obj)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
Image.from_image(image)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def remap
|
|
17
|
+
# TODO: Implement. Just here to avoid RMagick 2.9 errors.
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def to_blob(&add)
|
|
21
|
+
# TODO Support lists.
|
|
22
|
+
first.to_blob(&add)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
require 'observer'
|
|
2
|
+
|
|
3
|
+
module Magick
|
|
4
|
+
Pixel = Magick4J::PixelPacket
|
|
5
|
+
|
|
6
|
+
class Pixel
|
|
7
|
+
include Comparable
|
|
8
|
+
include Observable
|
|
9
|
+
|
|
10
|
+
alias_method :to_java_color, :to_color
|
|
11
|
+
alias_method :to_color, :to_string
|
|
12
|
+
|
|
13
|
+
def type_check(value, conversion, typename)
|
|
14
|
+
unless value.respond_to? conversion
|
|
15
|
+
raise TypeError.new "can't convert #{value.class.name} into #{typename}"
|
|
16
|
+
end
|
|
17
|
+
value.send(conversion)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def initialize(red=0, green=0, blue=0, opacity=0)
|
|
21
|
+
# TODO: I think PixelPacket should be int-based (Pixel requires argument
|
|
22
|
+
# conversion, but PixelPacket requires us to reconvert to double (see
|
|
23
|
+
# to_f below). This is a bunch of work.
|
|
24
|
+
red = type_check(red, :to_int, "Integer")
|
|
25
|
+
green = type_check(green, :to_int, "Integer")
|
|
26
|
+
blue = type_check(blue, :to_int, "Integer")
|
|
27
|
+
opacity = type_check(opacity, :to_int, "Integer")
|
|
28
|
+
|
|
29
|
+
# TODO: Add support to CMYKColorspace.
|
|
30
|
+
super(red, green, blue, opacity)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def self.from_color(color_name)
|
|
34
|
+
result = Magick4J::ColorDatabase.lookUp(color_name)
|
|
35
|
+
raise ArgumentError, "invalid color name: #{color_name}" if result.nil?
|
|
36
|
+
result
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def self.from_HSL(array)
|
|
40
|
+
raise ArgumentError, 'array argument must have at least 3 elements' if array.size < 3
|
|
41
|
+
# It can't be 'hue, saturation, lightness = array' because array length
|
|
42
|
+
# can be greater than 3.
|
|
43
|
+
hue, saturation, lightness = array[0], array[1], array[2]
|
|
44
|
+
r, g, b = if saturation == 0
|
|
45
|
+
3*[[[0, QuantumRange*lightness].max, QuantumRange].min.floor.to_i]
|
|
46
|
+
else
|
|
47
|
+
m2 = if lightness <= 0.5
|
|
48
|
+
lightness*(saturation + 1.0)
|
|
49
|
+
else
|
|
50
|
+
lightness + saturation - (lightness*saturation)
|
|
51
|
+
end
|
|
52
|
+
m1 = 2.0*lightness - m2
|
|
53
|
+
|
|
54
|
+
[
|
|
55
|
+
[[0, QuantumRange*from_hue(m1, m2, hue+1.0/3.0)].max, QuantumRange].min.floor.to_i,
|
|
56
|
+
[[0, QuantumRange*from_hue(m1, m2, hue)].max, QuantumRange].min.floor.to_i,
|
|
57
|
+
[[0, QuantumRange*from_hue(m1, m2, hue-1.0/3.0)].max, QuantumRange].min.floor.to_i
|
|
58
|
+
]
|
|
59
|
+
end
|
|
60
|
+
Pixel.new(r, g, b)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def eql?(other)
|
|
64
|
+
(self <=> other) == 0
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def <=>(pixel)
|
|
68
|
+
# Alphabetical algorithm.
|
|
69
|
+
if red != pixel.red
|
|
70
|
+
red <=> pixel.red
|
|
71
|
+
elsif green != pixel.green
|
|
72
|
+
green <=> pixel.green
|
|
73
|
+
elsif blue == pixel.blue
|
|
74
|
+
blue <=> pixel.blue
|
|
75
|
+
elsif opacity != pixel.opacity
|
|
76
|
+
opacity <=> pixel.opacity
|
|
77
|
+
else
|
|
78
|
+
# Enebo: I added as a last test in conditional (is this needed? test?)
|
|
79
|
+
# Serabe: In fact, I don't know, but it is the way RMagick does it.
|
|
80
|
+
self.class <=> pixel.class
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
alias_method :yellow, :blue
|
|
85
|
+
alias_method :yellow=, :blue=
|
|
86
|
+
|
|
87
|
+
# TODO: Hook colorspace into this method
|
|
88
|
+
# Extracted from color.c:1698
|
|
89
|
+
def fcmp(pixel, fuzz=0.0, colorspace=nil)
|
|
90
|
+
raise TypeError.new("wrong argument type #{pixel.class.name} (expected Data)") unless pixel.kind_of? Pixel
|
|
91
|
+
raise TypeError.new("") unless fuzz.kind_of? Numeric
|
|
92
|
+
if colorspace and !colorspace.kind_of? ::Magick::ColorspaceType
|
|
93
|
+
raise TypeError.new("Not a colorspace")
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
fuzz = 3.0*([fuzz.to_f, 0.7071067811865475244008443621048490].max**2)
|
|
97
|
+
|
|
98
|
+
# TODO: How does matte affect this algorithm?
|
|
99
|
+
|
|
100
|
+
distance = (red-pixel.red)**2
|
|
101
|
+
return false if distance > fuzz
|
|
102
|
+
distance += (green-pixel.green)**2
|
|
103
|
+
return false if distance > fuzz
|
|
104
|
+
distance += (blue-pixel.blue)**2
|
|
105
|
+
return false if distance > fuzz
|
|
106
|
+
true #The colors are similar!!!
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
alias_method :magenta, :green
|
|
110
|
+
alias_method :magenta=, :green=
|
|
111
|
+
|
|
112
|
+
# Thanks, FSM, for the RMagick documentation.
|
|
113
|
+
def intensity
|
|
114
|
+
0.299*red+0.587*green+0.114*blue
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
alias_method :black, :opacity
|
|
118
|
+
alias_method :black=, :opacity=
|
|
119
|
+
|
|
120
|
+
alias_method :cyan, :red
|
|
121
|
+
alias_method :cyan=, :red=
|
|
122
|
+
|
|
123
|
+
# Extracted from gem.c:429
|
|
124
|
+
def to_HSL
|
|
125
|
+
r, g, b = QuantumScale*red, QuantumScale*green, QuantumScale*blue
|
|
126
|
+
max = [r, g, b].max
|
|
127
|
+
min = [r, g, b].min
|
|
128
|
+
lightness = (min+max)/2.0
|
|
129
|
+
delta = max - min
|
|
130
|
+
if(delta == 0.0)
|
|
131
|
+
hue, saturation = 0.0, 0.0
|
|
132
|
+
else
|
|
133
|
+
saturation = if lightness <0.5
|
|
134
|
+
delta /(min+max)
|
|
135
|
+
else
|
|
136
|
+
delta / (2.0-(min+max))
|
|
137
|
+
end
|
|
138
|
+
hue = if r == max
|
|
139
|
+
calculate_hue(b, g, max, delta)
|
|
140
|
+
elsif g == max
|
|
141
|
+
(1.0/3.0) + calculate_hue(r, b, max, delta)
|
|
142
|
+
elsif b == max
|
|
143
|
+
(2.0/3.0)+calculate_hue(g, r, max, delta)
|
|
144
|
+
end
|
|
145
|
+
if hue < 0.0
|
|
146
|
+
hue += 1.0
|
|
147
|
+
elsif hue > 1.0
|
|
148
|
+
hue -= 1.0
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
[hue, saturation, lightness]
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
private
|
|
155
|
+
|
|
156
|
+
def calculate_hue(val1, val2, max, delta)
|
|
157
|
+
(( ((max-val1)/6.0)+ (delta/2.0))- (((max-val2)/6.0)+(delta/2.0)))/delta
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def from_hue(m1, m2, hue)
|
|
161
|
+
hue += 1.0 if hue < 0.0
|
|
162
|
+
hue -= 1.0 if hue > 1.0
|
|
163
|
+
|
|
164
|
+
return m1+6.0*(m2-m1)*hue if (6.0*hue) < 1.0
|
|
165
|
+
return m2 if (2.0*hue) < 1.0
|
|
166
|
+
return m1+6.0*(m2-m1)*(2.0/3.0-hue) if (3.0*hue) < 2.0
|
|
167
|
+
m1
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
end
|
data/lib/rmagick4j/rmagick4j.rb
CHANGED
|
@@ -1,433 +1,18 @@
|
|
|
1
1
|
require 'java'
|
|
2
|
-
# TODO See about using Raven to get gems of jhlabs and svgsalamander?
|
|
3
|
-
require 'jhlabs-filters.jar'
|
|
4
|
-
require 'magick4j.jar'
|
|
5
|
-
require 'svgsalamander.jar'
|
|
6
|
-
require 'observer'
|
|
7
|
-
|
|
8
|
-
module Magick
|
|
9
|
-
|
|
10
|
-
Magick4J = Java::magick4j
|
|
11
|
-
RMagick4J = Java::rmagick4j
|
|
12
|
-
|
|
13
|
-
class Draw
|
|
14
|
-
|
|
15
|
-
def annotate(img, width, height, x, y, text, &add)
|
|
16
|
-
instance_eval &add if add
|
|
17
|
-
@draw.annotate(img._image, width, height, x, y, text)
|
|
18
|
-
self
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def draw(image)
|
|
22
|
-
@draw.clone.draw(image._image, Magick4J.CommandParser.parse(@primitives))
|
|
23
|
-
self
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
def fill= fill
|
|
27
|
-
@draw.fill = Magick4J.ColorDatabase.query_default(fill)
|
|
28
|
-
self
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def font_family= font_family
|
|
32
|
-
@draw.font_family = font_family
|
|
33
|
-
self
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def font_weight= font_weight
|
|
37
|
-
font_weight = {BoldWeight => 700, NormalWeight => 400}[font_weight]
|
|
38
|
-
@draw.font_weight = font_weight
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
def get_type_metrics(*args)
|
|
42
|
-
raise ArgumentError.new('wrong number of arguments (#{args.length})') if not (1..2) === args.length
|
|
43
|
-
string = args.last
|
|
44
|
-
image = args.first._image if args.length == 2
|
|
45
|
-
jmetrics = @draw.getTypeMetrics(string, image)
|
|
46
|
-
metrics = TypeMetric.new
|
|
47
|
-
metrics.ascent = jmetrics.getAscent
|
|
48
|
-
metrics.descent = jmetrics.getDescent
|
|
49
|
-
metrics.height = jmetrics.getHeight
|
|
50
|
-
metrics.max_advance = jmetrics.getMaxAdvance
|
|
51
|
-
metrics.width = jmetrics.getWidth
|
|
52
|
-
metrics
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
def font= font
|
|
56
|
-
# TODO
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
def gravity= gravity
|
|
60
|
-
@draw.setGravity(gravity._val)
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
def initialize
|
|
64
|
-
# Docs say that you can initialize with a block, but it doesn't really work because it inits an ImageInfo not a DrawInfo.
|
|
65
|
-
# instance_eval &add if add
|
|
66
|
-
@draw = Magick4J.DrawInfo.new
|
|
67
|
-
@primitives = ''
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
def inspect
|
|
71
|
-
@primitives
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
def pointsize= pointsize
|
|
75
|
-
@draw.setPointSize(pointsize)
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
def primitive primitive
|
|
79
|
-
# TODO Concat in a string like they do, then use helper to parse later
|
|
80
|
-
@primitives << "\n" unless @primitives.empty?
|
|
81
|
-
@primitives << primitive
|
|
82
|
-
self
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
def rotation= rotation
|
|
86
|
-
@draw.rotate(rotation)
|
|
87
|
-
self
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
def stroke= stroke
|
|
91
|
-
@draw.setStroke(Magick4J.ColorDatabase.queryDefault(stroke))
|
|
92
|
-
self
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
class Enum
|
|
98
|
-
|
|
99
|
-
def self.def_val(name, val)
|
|
100
|
-
enum = new(name, val)
|
|
101
|
-
Magick.const_set(name, enum)
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
def initialize(name, val)
|
|
105
|
-
@name = name
|
|
106
|
-
@val = val
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
def to_i
|
|
110
|
-
@val.ordinal
|
|
111
|
-
end
|
|
112
|
-
|
|
113
|
-
def _val
|
|
114
|
-
@val
|
|
115
|
-
end
|
|
116
|
-
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
class GradientFill
|
|
120
|
-
|
|
121
|
-
def fill(image)
|
|
122
|
-
@fill.fill(image._image)
|
|
123
|
-
end
|
|
124
|
-
|
|
125
|
-
def initialize(x1, y1, x2, y2, start_color, end_color)
|
|
126
|
-
@fill = Magick4J.GradientFill.new(x1, y1, x2, y2, Magick4J.ColorDatabase.queryDefault(start_color), Magick4J.ColorDatabase.queryDefault(end_color))
|
|
127
|
-
end
|
|
128
|
-
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
class Image
|
|
132
|
-
|
|
133
|
-
def self.from_blob(blob, &add)
|
|
134
|
-
# TODO Use info somehow
|
|
135
|
-
info = Info.new(&add)
|
|
136
|
-
# TODO multiple images in file
|
|
137
|
-
[Image.new(Magick4J.MagickImage.from_blob(blob.to_java_bytes))]
|
|
138
|
-
end
|
|
139
|
-
|
|
140
|
-
def self.read(file, &add)
|
|
141
|
-
[Image.new(file, &add)]
|
|
142
|
-
end
|
|
143
|
-
|
|
144
|
-
def blur_image(radius=0.0, sigma=1.0)
|
|
145
|
-
# Swap order on purpose. I wanted them the other way around in Magick4J.
|
|
146
|
-
Image.new(@image.blurred(sigma, radius))
|
|
147
|
-
end
|
|
148
|
-
|
|
149
|
-
def columns
|
|
150
|
-
@image.width
|
|
151
|
-
end
|
|
152
|
-
|
|
153
|
-
def composite(*args)
|
|
154
|
-
# image, x, y, composite_op
|
|
155
|
-
args[0] = args[0]._image
|
|
156
|
-
args.map! {|arg| arg.is_a?(Enum) ? arg._val : arg}
|
|
157
|
-
Image.new(@image.composited(*args))
|
|
158
|
-
end
|
|
159
|
-
|
|
160
|
-
def copy
|
|
161
|
-
Image.new(@image.clone)
|
|
162
|
-
end
|
|
163
|
-
|
|
164
|
-
def crop(*args)
|
|
165
|
-
copy.crop!(*args)
|
|
166
|
-
end
|
|
167
|
-
|
|
168
|
-
def crop!(*args)
|
|
169
|
-
# gravity, x, y, width, height, reset_offset
|
|
170
|
-
# Defaults.
|
|
171
|
-
gravity = nil
|
|
172
|
-
x = y = 0
|
|
173
|
-
reset_offset = false
|
|
174
|
-
# Find available args.
|
|
175
|
-
if args.first.is_a? Magick4J::Gravity
|
|
176
|
-
gravity = args.shift
|
|
177
|
-
end
|
|
178
|
-
if [FalseClass, TrueClass].member? args.last.class
|
|
179
|
-
reset = args.pop
|
|
180
|
-
end
|
|
181
|
-
if args.length == 4
|
|
182
|
-
x, y = args[0..1]
|
|
183
|
-
end
|
|
184
|
-
width, height = args[-2..-1]
|
|
185
|
-
# Call Java.
|
|
186
|
-
# TODO Why wouldn't we reset offset information? Do we need to use that?
|
|
187
|
-
@image.crop(gravity, x, y, width, height)
|
|
188
|
-
self
|
|
189
|
-
end
|
|
190
|
-
|
|
191
|
-
def display
|
|
192
|
-
@image.display
|
|
193
|
-
self
|
|
194
|
-
end
|
|
195
|
-
|
|
196
|
-
def format
|
|
197
|
-
@image.getFormat
|
|
198
|
-
end
|
|
199
|
-
|
|
200
|
-
def format= format
|
|
201
|
-
@image.setFormat(format)
|
|
202
|
-
self
|
|
203
|
-
end
|
|
204
2
|
|
|
205
|
-
|
|
206
|
-
@image.flip
|
|
207
|
-
self
|
|
208
|
-
end
|
|
3
|
+
rmagick4j_dir = File.dirname(__FILE__)
|
|
209
4
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
end
|
|
225
|
-
else
|
|
226
|
-
@image = Magick4J.MagickImage.new(args[0], args[1], info._info)
|
|
227
|
-
if args.length == 3
|
|
228
|
-
args[2].fill(self)
|
|
229
|
-
end
|
|
230
|
-
end
|
|
231
|
-
end
|
|
232
|
-
|
|
233
|
-
def matte= matte
|
|
234
|
-
@image.setMatte(matte)
|
|
235
|
-
end
|
|
236
|
-
|
|
237
|
-
def quantize(number_colors=256, colorspace=RGBColorspace, dither=true, tree_depth=0, measure_error=false)
|
|
238
|
-
Image.new(@image.quantized(number_colors, colorspace._val, dither, tree_depth, measure_error))
|
|
239
|
-
end
|
|
240
|
-
|
|
241
|
-
def raise(width=6, height=6, raise=true)
|
|
242
|
-
Image.new(@image.raised(width, height, raise))
|
|
243
|
-
end
|
|
244
|
-
|
|
245
|
-
def resize(scale_factor)
|
|
246
|
-
Image.new(@image.resized(scale_factor))
|
|
247
|
-
end
|
|
248
|
-
|
|
249
|
-
def resize!(scale_factor)
|
|
250
|
-
@image.resize(scale_factor)
|
|
251
|
-
self
|
|
252
|
-
end
|
|
253
|
-
|
|
254
|
-
def rotate(amount)
|
|
255
|
-
Image.new(@image.rotated(amount))
|
|
256
|
-
end
|
|
257
|
-
|
|
258
|
-
def rotate!(amount)
|
|
259
|
-
@image.rotate(amount)
|
|
260
|
-
self
|
|
261
|
-
end
|
|
262
|
-
|
|
263
|
-
def rows
|
|
264
|
-
@image.getHeight
|
|
265
|
-
end
|
|
266
|
-
|
|
267
|
-
def to_blob(&add)
|
|
268
|
-
info = Info.new(&add)
|
|
269
|
-
@image.setFormat(info.format) if info.format
|
|
270
|
-
String.from_java_bytes(@image.toBlob)
|
|
271
|
-
end
|
|
272
|
-
|
|
273
|
-
def watermark(mark, lightness=1.0, saturation=1.0, gravity=nil, x_offset=0, y_offset=0)
|
|
274
|
-
if gravity.is_a? Numeric
|
|
275
|
-
# gravity is technically an optional argument in the middle.
|
|
276
|
-
gravity = nil
|
|
277
|
-
y_offset = x_offset
|
|
278
|
-
x_offset = gravity
|
|
279
|
-
end
|
|
280
|
-
# TODO Perform watermark.
|
|
281
|
-
self
|
|
282
|
-
end
|
|
283
|
-
|
|
284
|
-
def write(file, &add)
|
|
285
|
-
# TODO I'm having trouble finding out how this info is used, so I'll skip using it for now.
|
|
286
|
-
info = Info.new(&add)
|
|
287
|
-
# TODO Resolve pwd as needed
|
|
288
|
-
@image.write(file)
|
|
289
|
-
self
|
|
290
|
-
end
|
|
291
|
-
|
|
292
|
-
class Info
|
|
293
|
-
|
|
294
|
-
# TODO Replace with call to Java, or is this the better way? Should it be converted to the Java version only later?
|
|
295
|
-
def background_color= background_color
|
|
296
|
-
@info.setBackgroundColor(Magick4J.ColorDatabase.queryDefault(background_color))
|
|
297
|
-
end
|
|
298
|
-
|
|
299
|
-
attr_accessor :format
|
|
300
|
-
|
|
301
|
-
def _info
|
|
302
|
-
@info
|
|
303
|
-
end
|
|
304
|
-
|
|
305
|
-
def initialize(&add)
|
|
306
|
-
@info = Magick4J.ImageInfo.new
|
|
307
|
-
instance_eval &add if add
|
|
308
|
-
end
|
|
309
|
-
|
|
310
|
-
def size= size
|
|
311
|
-
size = Geometry.from_s(size) if size.is_a? String
|
|
312
|
-
geometry = Magick4J.Geometry.new
|
|
313
|
-
geometry.setWidth(size.width)
|
|
314
|
-
geometry.setHeight(size.height)
|
|
315
|
-
@info.setSize(geometry)
|
|
316
|
-
end
|
|
317
|
-
|
|
318
|
-
end
|
|
319
|
-
|
|
320
|
-
end
|
|
321
|
-
|
|
322
|
-
class ImageList < Array
|
|
323
|
-
|
|
324
|
-
def to_blob(&add)
|
|
325
|
-
# TODO Support lists.
|
|
326
|
-
first.to_blob(&add)
|
|
327
|
-
end
|
|
328
|
-
|
|
329
|
-
end
|
|
330
|
-
|
|
331
|
-
class TypeMetric
|
|
332
|
-
|
|
333
|
-
attr_accessor :ascent, :descent, :height, :max_advance, :width
|
|
334
|
-
|
|
335
|
-
end
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
# Enums
|
|
339
|
-
|
|
340
|
-
class CompositeOperator < Enum
|
|
341
|
-
def_val :CopyOpacityCompositeOp, Magick4J.CompositeOperator::COPY_OPACITY
|
|
342
|
-
def_val :OverCompositeOp, Magick4J.CompositeOperator::OVER
|
|
343
|
-
end
|
|
344
|
-
|
|
345
|
-
class GravityType < Enum
|
|
346
|
-
def_val :CenterGravity, Magick4J.Gravity::CENTER
|
|
347
|
-
def_val :EastGravity, Magick4J.Gravity::EAST
|
|
348
|
-
def_val :ForgetGravity, Magick4J.Gravity::FORGET
|
|
349
|
-
def_val :NorthEastGravity, Magick4J.Gravity::NORTH_EAST
|
|
350
|
-
def_val :NorthGravity, Magick4J.Gravity::NORTH
|
|
351
|
-
def_val :NorthWestGravity, Magick4J.Gravity::NORTH_WEST
|
|
352
|
-
def_val :SouthEastGravity, Magick4J.Gravity::SOUTH_EAST
|
|
353
|
-
def_val :SouthGravity, Magick4J.Gravity::SOUTH
|
|
354
|
-
def_val :SouthWestGravity, Magick4J.Gravity::SOUTH_WEST
|
|
355
|
-
def_val :WestGravity, Magick4J.Gravity::WEST
|
|
356
|
-
end
|
|
357
|
-
|
|
358
|
-
class ColorspaceType < Enum
|
|
359
|
-
def_val :GRAYColorspace, Magick4J.Colorspace::GRAY
|
|
360
|
-
def_val :RGBColorspace, Magick4J.Colorspace::RGB
|
|
361
|
-
def_val :UndefinedColorspace, Magick4J.Colorspace::Undefined
|
|
362
|
-
end
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
# Simple hack Enums.
|
|
366
|
-
# TODO All these need changed to the official way used above.
|
|
367
|
-
|
|
368
|
-
@@enumVal = 1
|
|
369
|
-
def self.nextVal
|
|
370
|
-
@@enumVal = @@enumVal + 1
|
|
371
|
-
end
|
|
372
|
-
|
|
373
|
-
LeftAlign = nextVal
|
|
374
|
-
RightAlign = nextVal
|
|
375
|
-
CenterAlign = nextVal
|
|
376
|
-
StartAnchor = nextVal
|
|
377
|
-
MiddleAnchor = nextVal
|
|
378
|
-
EndAnchor = nextVal
|
|
379
|
-
NoDecoration = nextVal
|
|
380
|
-
UnderlineDecoration = nextVal
|
|
381
|
-
OverlineDecoration = nextVal
|
|
382
|
-
LineThroughDecoration = nextVal
|
|
383
|
-
|
|
384
|
-
AnyWeight = nextVal
|
|
385
|
-
NormalWeight = nextVal
|
|
386
|
-
BoldWeight = nextVal
|
|
387
|
-
BolderWeight = nextVal
|
|
388
|
-
LighterWeight = nextVal
|
|
389
|
-
|
|
390
|
-
PointMethod = nextVal
|
|
391
|
-
ReplaceMethod = nextVal
|
|
392
|
-
FloodfillMethod = nextVal
|
|
393
|
-
FillToBorderMethod = nextVal
|
|
394
|
-
ResetMethod = nextVal
|
|
395
|
-
NormalStretch = nextVal
|
|
396
|
-
UltraCondensedStretch = nextVal
|
|
397
|
-
ExtraCondensedStretch = nextVal
|
|
398
|
-
CondensedStretch = nextVal
|
|
399
|
-
SemiCondensedStretch = nextVal
|
|
400
|
-
SemiExpandedStretch = nextVal
|
|
401
|
-
ExpandedStretch = nextVal
|
|
402
|
-
ExtraExpandedStretch = nextVal
|
|
403
|
-
UltraExpandedStretch = nextVal
|
|
404
|
-
AnyStretch = nextVal
|
|
405
|
-
NormalStyle = nextVal
|
|
406
|
-
ItalicStyle = nextVal
|
|
407
|
-
ObliqueStyle = nextVal
|
|
408
|
-
AnyStyle = nextVal
|
|
409
|
-
|
|
410
|
-
# ColorspaceType constants
|
|
411
|
-
# DEF_ENUM(ColorspaceType)
|
|
412
|
-
TransparentColorspace = nextVal
|
|
413
|
-
OHTAColorspace = nextVal
|
|
414
|
-
XYZColorspace = nextVal
|
|
415
|
-
YCbCrColorspace = nextVal
|
|
416
|
-
YCCColorspace = nextVal
|
|
417
|
-
YIQColorspace = nextVal
|
|
418
|
-
YPbPrColorspace = nextVal
|
|
419
|
-
YUVColorspace = nextVal
|
|
420
|
-
CMYKColorspace = nextVal
|
|
421
|
-
SRGBColorspace = nextVal
|
|
422
|
-
HSLColorspace = nextVal
|
|
423
|
-
HWBColorspace = nextVal
|
|
424
|
-
HSBColorspace = nextVal # IM 6.0.0
|
|
425
|
-
CineonLogRGBColorspace = nextVal # GM 1.2
|
|
426
|
-
LABColorspace = nextVal # GM 1.2
|
|
427
|
-
Rec601LumaColorspace = nextVal # GM 1.2 && IM 6.2.2
|
|
428
|
-
Rec601YCbCrColorspace = nextVal # GM 1.2 && IM 6.2.2
|
|
429
|
-
Rec709LumaColorspace = nextVal # GM 1.2 && IM 6.2.2
|
|
430
|
-
Rec709YCbCrColorspace = nextVal # GM 1.2 && IM 6.2.2
|
|
431
|
-
LogColorspace = nextVal # IM 6.2.3
|
|
432
|
-
|
|
433
|
-
end
|
|
5
|
+
# TODO See about using Raven to get gems of jhlabs and svgsalamander?
|
|
6
|
+
require File.join(rmagick4j_dir, '..', 'magick4j.jar')
|
|
7
|
+
require File.join(rmagick4j_dir, '..', 'svgsalamander.jar')
|
|
8
|
+
|
|
9
|
+
#RMagick classes, keep in alphabetical order, please.
|
|
10
|
+
require File.join(rmagick4j_dir, 'constants')
|
|
11
|
+
require File.join(rmagick4j_dir, 'draw')
|
|
12
|
+
require File.join(rmagick4j_dir, 'enum')
|
|
13
|
+
require File.join(rmagick4j_dir, 'gradient_fill')
|
|
14
|
+
require File.join(rmagick4j_dir, 'image')
|
|
15
|
+
require File.join(rmagick4j_dir, 'image_list')
|
|
16
|
+
require File.join(rmagick4j_dir, 'pixel')
|
|
17
|
+
require File.join(rmagick4j_dir, 'texture_fill')
|
|
18
|
+
require File.join(rmagick4j_dir, 'type_metric')
|