rmagick4j 0.3.4-java → 0.3.9-java
Sign up to get free protection for your applications and to get access to all the features.
- 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,34 @@
|
|
1
|
+
module Magick
|
2
|
+
Effects = Java::Magick4jEffects
|
3
|
+
Magick4J = Java::magick4j
|
4
|
+
RMagick4J = Java::rmagick4j
|
5
|
+
|
6
|
+
|
7
|
+
QuantumDepth = 8
|
8
|
+
QuantumRange = 2**QuantumDepth-1
|
9
|
+
QuantumScale = 1.0/QuantumRange.to_f
|
10
|
+
|
11
|
+
# Geometries
|
12
|
+
JGeometry = Magick4J::Geometry
|
13
|
+
|
14
|
+
JRelativeHeightDistance = Magick4J::RelativeHeightDistance
|
15
|
+
JRelativeWidthDistance = Magick4J::RelativeWidthDistance
|
16
|
+
|
17
|
+
JHeightDistances = [
|
18
|
+
Magick4J::SimpleValueHeightDistance,
|
19
|
+
Magick4J::PercentValueHeightDistance,
|
20
|
+
Magick4J::AspectValueHeightDistance,
|
21
|
+
Magick4J::LessValueHeightDistance,
|
22
|
+
Magick4J::GreaterValueHeightDistance,
|
23
|
+
Magick4J::AreaValueHeightDistance
|
24
|
+
]
|
25
|
+
|
26
|
+
JWidthDistances = [
|
27
|
+
Magick4J::SimpleValueWidthDistance,
|
28
|
+
Magick4J::PercentValueWidthDistance,
|
29
|
+
Magick4J::AspectValueWidthDistance,
|
30
|
+
Magick4J::LessValueWidthDistance,
|
31
|
+
Magick4J::GreaterValueWidthDistance,
|
32
|
+
Magick4J::AreaValueWidthDistance
|
33
|
+
]
|
34
|
+
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
|
2
|
+
module Magick
|
3
|
+
class Draw
|
4
|
+
|
5
|
+
def annotate(img, width, height, x, y, text, &add)
|
6
|
+
instance_eval &add if add
|
7
|
+
text = parse_string(text)
|
8
|
+
@draw.annotate(img._image, width, height, x, y, text)
|
9
|
+
self
|
10
|
+
end
|
11
|
+
|
12
|
+
def clone
|
13
|
+
b = Draw.new
|
14
|
+
b.primitives = @primitives.clone
|
15
|
+
b._draw = @draw.clone
|
16
|
+
b.freeze if self.frozen?
|
17
|
+
b
|
18
|
+
end
|
19
|
+
|
20
|
+
def draw(image)
|
21
|
+
@draw.clone.draw(image._image, Magick4J.CommandParser.parse(@primitives))
|
22
|
+
self
|
23
|
+
end
|
24
|
+
|
25
|
+
def fill= fill
|
26
|
+
@draw.fill = Magick4J.ColorDatabase.query_default(fill)
|
27
|
+
self
|
28
|
+
end
|
29
|
+
|
30
|
+
def font_family= font_family
|
31
|
+
@draw.font_family = font_family
|
32
|
+
self
|
33
|
+
end
|
34
|
+
|
35
|
+
def font_weight= font_weight
|
36
|
+
font_weight = {BoldWeight => 700, NormalWeight => 400}[font_weight]
|
37
|
+
@draw.font_weight = font_weight
|
38
|
+
end
|
39
|
+
|
40
|
+
def get_multiline_type_metrics(*args)
|
41
|
+
raise ArgumentError.new('wrong number of arguments (#{args.length})') if not (1..2) === args.length
|
42
|
+
string = parse_string(args.last)
|
43
|
+
image = args.first._image if args.length == 2
|
44
|
+
type_metrics_from_java(@draw.getMultilineTypeMetrics(string, image))
|
45
|
+
end
|
46
|
+
|
47
|
+
def get_type_metrics(*args)
|
48
|
+
raise ArgumentError.new('wrong number of arguments (#{args.length})') if not (1..2) === args.length
|
49
|
+
string = parse_string(args.last)
|
50
|
+
image = args.first._image if args.length == 2
|
51
|
+
type_metrics_from_java(@draw.getTypeMetrics(string, image))
|
52
|
+
end
|
53
|
+
|
54
|
+
def font= font
|
55
|
+
# TODO
|
56
|
+
end
|
57
|
+
|
58
|
+
def gravity= gravity
|
59
|
+
@draw.setGravity(gravity._val)
|
60
|
+
end
|
61
|
+
|
62
|
+
def initialize
|
63
|
+
# Docs say that you can initialize with a block, but it doesn't really work because it inits an ImageInfo not a DrawInfo.
|
64
|
+
# instance_eval &add if add
|
65
|
+
@draw = Magick4J::DrawInfo.new
|
66
|
+
@primitives = ''
|
67
|
+
end
|
68
|
+
|
69
|
+
def inspect
|
70
|
+
if @primitives == ''
|
71
|
+
'(no primitives defined)'
|
72
|
+
else
|
73
|
+
@primitives
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def pointsize= pointsize
|
78
|
+
@draw.setPointSize(pointsize)
|
79
|
+
end
|
80
|
+
|
81
|
+
def primitive primitive
|
82
|
+
# TODO Concat in a string like they do, then use helper to parse later
|
83
|
+
@primitives << "\n" unless @primitives.empty?
|
84
|
+
@primitives << primitive.gsub(/[\r|\n]/, '')
|
85
|
+
self
|
86
|
+
end
|
87
|
+
|
88
|
+
def rotation= rotation
|
89
|
+
@draw.rotate(rotation)
|
90
|
+
self
|
91
|
+
end
|
92
|
+
|
93
|
+
def stroke= stroke
|
94
|
+
@draw.setStroke(Magick4J.ColorDatabase.queryDefault(stroke))
|
95
|
+
self
|
96
|
+
end
|
97
|
+
|
98
|
+
private
|
99
|
+
|
100
|
+
def parse_string(text)
|
101
|
+
text.split(/\\n/).join("\n")
|
102
|
+
end
|
103
|
+
|
104
|
+
def type_metrics_from_java(jmetrics)
|
105
|
+
metrics = TypeMetric.new
|
106
|
+
metrics.ascent = jmetrics.getAscent
|
107
|
+
metrics.descent = jmetrics.getDescent
|
108
|
+
metrics.height = jmetrics.getHeight
|
109
|
+
metrics.max_advance = jmetrics.getMaxAdvance
|
110
|
+
metrics.width = jmetrics.getWidth
|
111
|
+
metrics
|
112
|
+
end
|
113
|
+
|
114
|
+
protected
|
115
|
+
|
116
|
+
def primitives=(value)
|
117
|
+
@primitives = value.to_str
|
118
|
+
end
|
119
|
+
|
120
|
+
def _draw=(value)
|
121
|
+
@draw = value
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
|
2
|
+
module Magick
|
3
|
+
|
4
|
+
class Enum
|
5
|
+
|
6
|
+
def self.def_val(name, val)
|
7
|
+
enum = new(name, val)
|
8
|
+
Magick.const_set(name, enum)
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(name, val)
|
12
|
+
@name = name
|
13
|
+
@val = val
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_i
|
17
|
+
@val.ordinal
|
18
|
+
end
|
19
|
+
|
20
|
+
def _val
|
21
|
+
@val
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
# Enums
|
27
|
+
|
28
|
+
class CompositeOperator < Enum
|
29
|
+
def_val :CopyOpacityCompositeOp, Magick4J.CompositeOperator::COPY_OPACITY
|
30
|
+
def_val :OverCompositeOp, Magick4J.CompositeOperator::OVER
|
31
|
+
end
|
32
|
+
|
33
|
+
class GravityType < Enum
|
34
|
+
def_val :CenterGravity, Magick4J.Gravity::CENTER
|
35
|
+
def_val :EastGravity, Magick4J.Gravity::EAST
|
36
|
+
def_val :ForgetGravity, Magick4J.Gravity::FORGET
|
37
|
+
def_val :NorthEastGravity, Magick4J.Gravity::NORTH_EAST
|
38
|
+
def_val :NorthGravity, Magick4J.Gravity::NORTH
|
39
|
+
def_val :NorthWestGravity, Magick4J.Gravity::NORTH_WEST
|
40
|
+
def_val :SouthEastGravity, Magick4J.Gravity::SOUTH_EAST
|
41
|
+
def_val :SouthGravity, Magick4J.Gravity::SOUTH
|
42
|
+
def_val :SouthWestGravity, Magick4J.Gravity::SOUTH_WEST
|
43
|
+
def_val :WestGravity, Magick4J.Gravity::WEST
|
44
|
+
end
|
45
|
+
|
46
|
+
class ColorspaceType < Enum
|
47
|
+
def_val :GRAYColorspace, Magick4J.Colorspace::GRAY
|
48
|
+
def_val :RGBColorspace, Magick4J.Colorspace::RGB
|
49
|
+
def_val :UndefinedColorspace, Magick4J.Colorspace::Undefined
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
# Simple hack Enums.
|
54
|
+
# TODO All these need changed to the official way used above.
|
55
|
+
|
56
|
+
@@enumVal = 1
|
57
|
+
def self.nextVal
|
58
|
+
@@enumVal = @@enumVal + 1
|
59
|
+
end
|
60
|
+
|
61
|
+
LeftAlign = nextVal
|
62
|
+
RightAlign = nextVal
|
63
|
+
CenterAlign = nextVal
|
64
|
+
StartAnchor = nextVal
|
65
|
+
MiddleAnchor = nextVal
|
66
|
+
EndAnchor = nextVal
|
67
|
+
NoDecoration = nextVal
|
68
|
+
UnderlineDecoration = nextVal
|
69
|
+
OverlineDecoration = nextVal
|
70
|
+
LineThroughDecoration = nextVal
|
71
|
+
|
72
|
+
AnyWeight = nextVal
|
73
|
+
NormalWeight = nextVal
|
74
|
+
BoldWeight = nextVal
|
75
|
+
BolderWeight = nextVal
|
76
|
+
LighterWeight = nextVal
|
77
|
+
|
78
|
+
PointMethod = nextVal
|
79
|
+
ReplaceMethod = nextVal
|
80
|
+
FloodfillMethod = nextVal
|
81
|
+
FillToBorderMethod = nextVal
|
82
|
+
ResetMethod = nextVal
|
83
|
+
NormalStretch = nextVal
|
84
|
+
UltraCondensedStretch = nextVal
|
85
|
+
ExtraCondensedStretch = nextVal
|
86
|
+
CondensedStretch = nextVal
|
87
|
+
SemiCondensedStretch = nextVal
|
88
|
+
SemiExpandedStretch = nextVal
|
89
|
+
ExpandedStretch = nextVal
|
90
|
+
ExtraExpandedStretch = nextVal
|
91
|
+
UltraExpandedStretch = nextVal
|
92
|
+
AnyStretch = nextVal
|
93
|
+
NormalStyle = nextVal
|
94
|
+
ItalicStyle = nextVal
|
95
|
+
ObliqueStyle = nextVal
|
96
|
+
AnyStyle = nextVal
|
97
|
+
|
98
|
+
# ColorspaceType constants
|
99
|
+
# DEF_ENUM(ColorspaceType)
|
100
|
+
TransparentColorspace = nextVal
|
101
|
+
OHTAColorspace = nextVal
|
102
|
+
XYZColorspace = nextVal
|
103
|
+
YCbCrColorspace = nextVal
|
104
|
+
YCCColorspace = nextVal
|
105
|
+
YIQColorspace = nextVal
|
106
|
+
YPbPrColorspace = nextVal
|
107
|
+
YUVColorspace = nextVal
|
108
|
+
CMYKColorspace = nextVal
|
109
|
+
SRGBColorspace = nextVal
|
110
|
+
HSLColorspace = nextVal
|
111
|
+
HWBColorspace = nextVal
|
112
|
+
HSBColorspace = nextVal # IM 6.0.0
|
113
|
+
CineonLogRGBColorspace = nextVal # GM 1.2
|
114
|
+
LABColorspace = nextVal # GM 1.2
|
115
|
+
Rec601LumaColorspace = nextVal # GM 1.2 && IM 6.2.2
|
116
|
+
Rec601YCbCrColorspace = nextVal # GM 1.2 && IM 6.2.2
|
117
|
+
Rec709LumaColorspace = nextVal # GM 1.2 && IM 6.2.2
|
118
|
+
Rec709YCbCrColorspace = nextVal # GM 1.2 && IM 6.2.2
|
119
|
+
LogColorspace = nextVal # IM 6.2.3
|
120
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
|
2
|
+
module Magick
|
3
|
+
class GradientFill
|
4
|
+
|
5
|
+
def fill(image)
|
6
|
+
@fill.fill(image._image)
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize(x1, y1, x2, y2, start_color, end_color)
|
10
|
+
@fill = Magick4J.GradientFill.new(x1, y1, x2, y2, Magick4J.ColorDatabase.queryDefault(start_color), Magick4J.ColorDatabase.queryDefault(end_color))
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,351 @@
|
|
1
|
+
module Magick
|
2
|
+
class Image
|
3
|
+
|
4
|
+
def self.from_blob(blob, &add)
|
5
|
+
# TODO multiple images in file
|
6
|
+
[Image.from_image(Magick4J.MagickImage.from_blob(blob.to_java_bytes), &add)]
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.read(file, &add)
|
10
|
+
info = Info.new(&add)
|
11
|
+
image = Magick4J.ImageDatabase.createDefault(file.to_s, info._info) || Magick4J.MagickImage.new(java.io.File.new(file.to_s))
|
12
|
+
[Image.from_image(image,&add)]
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.from_image(image, &add)
|
16
|
+
raise ArgumentError, 'First parameter must be a MagickImage instance.' unless image.is_a? Magick4J.MagickImage
|
17
|
+
magick_image = Image.new(image.getWidth(), image.getHeight(), &add)
|
18
|
+
magick_image._image = image
|
19
|
+
magick_image
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.allocate(*args, &add)
|
23
|
+
info = Info.new(&add)
|
24
|
+
if args.length == 1
|
25
|
+
case args[0]
|
26
|
+
when String then
|
27
|
+
# TODO Respect Dir.getwd
|
28
|
+
name = args[0]
|
29
|
+
@image = Magick4J.ImageDatabase.createDefault(name, info._info) || Magick4J.MagickImage.new(java.io.File.new(name))
|
30
|
+
when Magick4J.MagickImage then
|
31
|
+
@image = args[0]
|
32
|
+
when Image then
|
33
|
+
@image = args[0]._image
|
34
|
+
else
|
35
|
+
raise ArgumentError, "The argument just can be a String, a MagickImage or an Image instance."
|
36
|
+
end
|
37
|
+
else
|
38
|
+
@image = Magick4J.MagickImage.new(args[0], args[1], info._info)
|
39
|
+
if args.length == 3
|
40
|
+
args[2].fill(self)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def background_color
|
46
|
+
@image.getBackgroundColor
|
47
|
+
end
|
48
|
+
|
49
|
+
def background_color=(value)
|
50
|
+
raise TypeError, "argument must be color name or pixel (#{value.class} given)" unless value.is_a?(String) || value.is_a?(Pixel)
|
51
|
+
value = Pixel.from_color(value) if value.is_a?(String)
|
52
|
+
@image.setBackgroundColor(value)
|
53
|
+
end
|
54
|
+
|
55
|
+
def blur
|
56
|
+
@image.getBlur
|
57
|
+
end
|
58
|
+
|
59
|
+
def blur=(value)
|
60
|
+
raise TypeError, "no implicit conversion to float from #{value.class.to_s.downcase}" unless value.is_a? Numeric
|
61
|
+
@image.setBlur(value)
|
62
|
+
end
|
63
|
+
|
64
|
+
def blur_image(radius=0.0, sigma=1.0)
|
65
|
+
# Swap order on purpose. I wanted them the other way around in Magick4J.
|
66
|
+
Image.from_image(Effects.BlurEffect.new(radius,sigma).apply(_image))
|
67
|
+
end
|
68
|
+
|
69
|
+
def change_geometry(geometry)
|
70
|
+
geometry = Geometry.from_s(geometry.to_s) unless geometry.is_a? Geometry
|
71
|
+
index = if geometry.flag.nil?
|
72
|
+
0
|
73
|
+
else
|
74
|
+
geometry.flag._val
|
75
|
+
end
|
76
|
+
width_distance = geometry.width.nil? ?
|
77
|
+
JRelativeWidthDistance.new :
|
78
|
+
JWidthDistances[index].new(geometry.width)
|
79
|
+
height_distance = geometry.height.nil? ?
|
80
|
+
JRelativeHeightDistance.new :
|
81
|
+
JHeightDistances[index].new(geometry.height)
|
82
|
+
geometry = JGeometry.new(width_distance, height_distance,
|
83
|
+
geometry.x, geometry.y)
|
84
|
+
yield geometry.calculate_width(self._image),
|
85
|
+
geometry.calculate_height(self._image),
|
86
|
+
self
|
87
|
+
end
|
88
|
+
|
89
|
+
def charcoal(radius=0.0, sigma=1.0)
|
90
|
+
Image.from_image(Effects.CharcoalEffect.new(radius,sigma).apply(_image))
|
91
|
+
end
|
92
|
+
|
93
|
+
def columns
|
94
|
+
@image.getWidth
|
95
|
+
end
|
96
|
+
|
97
|
+
def composite(*args)
|
98
|
+
# image, x, y, composite_op
|
99
|
+
args[0] = args[0]._image
|
100
|
+
args.map! {|arg| arg.is_a?(Enum) ? arg._val : arg}
|
101
|
+
Image.from_image(@image.composited(*args))
|
102
|
+
end
|
103
|
+
|
104
|
+
def copy
|
105
|
+
Image.from_image(@image.clone)
|
106
|
+
end
|
107
|
+
|
108
|
+
def crop(*args)
|
109
|
+
copy.crop!(*args)
|
110
|
+
end
|
111
|
+
|
112
|
+
def crop!(*args)
|
113
|
+
# gravity, x, y, width, height, reset_offset
|
114
|
+
# Defaults.
|
115
|
+
gravity = nil
|
116
|
+
x = y = -1
|
117
|
+
reset_offset = false
|
118
|
+
# Find available args.
|
119
|
+
if args.first.is_a? GravityType
|
120
|
+
gravity = args.shift._val
|
121
|
+
end
|
122
|
+
if [FalseClass, TrueClass].member? args.last.class
|
123
|
+
reset = args.pop
|
124
|
+
end
|
125
|
+
if args.length == 4
|
126
|
+
x, y = args[0..1]
|
127
|
+
end
|
128
|
+
width, height = args[-2..-1]
|
129
|
+
# Call Java.
|
130
|
+
# TODO Why wouldn't we reset offset information? Do we need to use that?
|
131
|
+
@image = unless gravity.nil?
|
132
|
+
if x == -1 || y == -1
|
133
|
+
@image.crop(gravity, width, height)
|
134
|
+
else
|
135
|
+
@image.crop(gravity, x, y, width, height)
|
136
|
+
end
|
137
|
+
else
|
138
|
+
@image.crop(x,y,width,height)
|
139
|
+
end
|
140
|
+
self
|
141
|
+
end
|
142
|
+
|
143
|
+
def display
|
144
|
+
@image.display
|
145
|
+
self
|
146
|
+
end
|
147
|
+
|
148
|
+
def edge(radius=0.0)
|
149
|
+
Image.from_image(Effects.EdgeEffect.new(radius).apply(_image))
|
150
|
+
end
|
151
|
+
|
152
|
+
def erase!
|
153
|
+
@image.erase
|
154
|
+
end
|
155
|
+
|
156
|
+
def format
|
157
|
+
@image.getFormat
|
158
|
+
end
|
159
|
+
|
160
|
+
def format= format
|
161
|
+
@image.setFormat(format)
|
162
|
+
self
|
163
|
+
end
|
164
|
+
|
165
|
+
def flip
|
166
|
+
copy.flip
|
167
|
+
end
|
168
|
+
|
169
|
+
def flip!
|
170
|
+
@image.flip
|
171
|
+
self
|
172
|
+
end
|
173
|
+
|
174
|
+
def _image
|
175
|
+
@image
|
176
|
+
end
|
177
|
+
|
178
|
+
def _image=(new_image)
|
179
|
+
@image = new_image
|
180
|
+
end
|
181
|
+
|
182
|
+
def implode(amount=0.5)
|
183
|
+
Image.from_image(Effects.ImplodeEffect.new(amount).apply(_image))
|
184
|
+
end
|
185
|
+
|
186
|
+
def _info
|
187
|
+
@info
|
188
|
+
end
|
189
|
+
|
190
|
+
def _info=(new_info)
|
191
|
+
@info = new_info
|
192
|
+
end
|
193
|
+
|
194
|
+
def initialize(columns, rows, fill=nil, &info_block)
|
195
|
+
info = Info.new(&info_block)
|
196
|
+
@image = Magick4J.MagickImage.new(columns, rows, info._info)
|
197
|
+
fill.fill(self) if fill.respond_to? :fill
|
198
|
+
end
|
199
|
+
|
200
|
+
def matte
|
201
|
+
@image.getMatte
|
202
|
+
end
|
203
|
+
|
204
|
+
def matte= matte
|
205
|
+
@image.setMatte(matte)
|
206
|
+
end
|
207
|
+
|
208
|
+
def negate(grayscale=false)
|
209
|
+
Image.from_image(Effects.NegateEffect.new(grayscale).apply(_image))
|
210
|
+
end
|
211
|
+
|
212
|
+
def normalize
|
213
|
+
Image.from_image(Effects.NormalizeEffect.new().apply(_image))
|
214
|
+
end
|
215
|
+
|
216
|
+
def quantize(number_colors=256, colorspace=RGBColorspace, dither=true, tree_depth=0, measure_error=false)
|
217
|
+
Image.from_image(@image.quantized(number_colors, colorspace._val, dither, tree_depth, measure_error))
|
218
|
+
end
|
219
|
+
|
220
|
+
def raise(width=6, height=6, raise=true)
|
221
|
+
Image.from_image(@image.raised(width, height, raise))
|
222
|
+
end
|
223
|
+
|
224
|
+
def remap
|
225
|
+
# TODO: Implement. Just here to avoid warning in RMagick 2.9 file.
|
226
|
+
end
|
227
|
+
|
228
|
+
def resize(*args)
|
229
|
+
copy.resize!(*args)
|
230
|
+
end
|
231
|
+
|
232
|
+
def resize!(*args)
|
233
|
+
@image = if args.length == 1
|
234
|
+
@image.resized(args[0])
|
235
|
+
elsif args.length == 2 # It must be 4 nor 2, but two of them are not yet implemented
|
236
|
+
# TODO Implement the other two arguments.
|
237
|
+
# arg[0] --> new_width
|
238
|
+
# arg[1] --> new_height
|
239
|
+
# arg[2] --> filter=LanczosFilter
|
240
|
+
# arg[3] --> support=1.0
|
241
|
+
@image.resized(args[0],args[1])
|
242
|
+
else
|
243
|
+
Kernel.raise ArgumentError, "wrong number of parameters(#{args.length} for 1 or 4)"
|
244
|
+
end
|
245
|
+
self
|
246
|
+
end
|
247
|
+
|
248
|
+
def rotate(amount, qualifier=nil)
|
249
|
+
copy.rotate!(amount,qualifier)
|
250
|
+
end
|
251
|
+
|
252
|
+
def rotate!(amount, qualifier=nil)
|
253
|
+
if qualifier == '<' && columns < rows
|
254
|
+
@image.rotate(amount)
|
255
|
+
self
|
256
|
+
elsif qualifier == '>' && columns > rows
|
257
|
+
@image.rotate(amount)
|
258
|
+
self
|
259
|
+
elsif qualifier.nil?
|
260
|
+
@image.rotate(amount)
|
261
|
+
self
|
262
|
+
else
|
263
|
+
nil
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
def rows
|
268
|
+
@image.getHeight
|
269
|
+
end
|
270
|
+
|
271
|
+
def shade(shading=false,azimuth=30,elevation=30)
|
272
|
+
Image.from_image(Effects.ShadeEffect.new(shading,azimuth,elevation).apply(_image))
|
273
|
+
end
|
274
|
+
|
275
|
+
def solarize(threshold=50)
|
276
|
+
Image.from_image(Effects.SolarizeEffect.new(threshold).apply(_image))
|
277
|
+
end
|
278
|
+
|
279
|
+
def store_pixels(x, y, columns, rows, pixels)
|
280
|
+
ria_size = columns*rows
|
281
|
+
raise IndexError, "not enough elements in array - expecting #{ria_size}, got #{pixels.size}" if pixels.size < ria_size
|
282
|
+
@image.storePixels(x,y,columns,rows,pixels.to_java)
|
283
|
+
end
|
284
|
+
|
285
|
+
def to_blob(&add)
|
286
|
+
info = Info.new(&add)
|
287
|
+
@image.setFormat(info.format) if info.format
|
288
|
+
String.from_java_bytes(@image.toBlob)
|
289
|
+
end
|
290
|
+
|
291
|
+
def watermark(mark, lightness=1.0, saturation=1.0, gravity=nil, x_offset=0, y_offset=0)
|
292
|
+
if gravity.is_a? Numeric
|
293
|
+
# gravity is technically an optional argument in the middle.
|
294
|
+
gravity = nil
|
295
|
+
y_offset = x_offset
|
296
|
+
x_offset = gravity
|
297
|
+
end
|
298
|
+
# TODO Perform watermark.
|
299
|
+
self
|
300
|
+
end
|
301
|
+
|
302
|
+
def wave(amplitude=25.0, wavelength=150.0)
|
303
|
+
Image.from_image(Effects.WaveEffect.new(amplitude,wavelength).apply(_image))
|
304
|
+
end
|
305
|
+
|
306
|
+
def write(file, &add)
|
307
|
+
# TODO I'm having trouble finding out how this info is used, so I'll skip using it for now.
|
308
|
+
info = Info.new(&add)
|
309
|
+
# TODO Resolve pwd as needed
|
310
|
+
@image.write(file)
|
311
|
+
self
|
312
|
+
end
|
313
|
+
|
314
|
+
def file_type(file)
|
315
|
+
@image.file_type(file)
|
316
|
+
end
|
317
|
+
|
318
|
+
def file_path(file)
|
319
|
+
@image.file_path(file)
|
320
|
+
end
|
321
|
+
|
322
|
+
class Info
|
323
|
+
|
324
|
+
# TODO Replace with call to Java, or is this the better way? Should it be converted to the Java version only later?
|
325
|
+
def background_color= background_color
|
326
|
+
@info.setBackgroundColor(Magick4J.ColorDatabase.queryDefault(background_color))
|
327
|
+
end
|
328
|
+
|
329
|
+
attr_accessor :format
|
330
|
+
|
331
|
+
def _info
|
332
|
+
@info
|
333
|
+
end
|
334
|
+
|
335
|
+
def initialize(&add)
|
336
|
+
@info = Magick4J.ImageInfo.new
|
337
|
+
instance_eval &add if add
|
338
|
+
end
|
339
|
+
|
340
|
+
def size= size
|
341
|
+
size = Geometry.from_s(size) if size.is_a? String
|
342
|
+
geometry = Magick4J.Geometry.new
|
343
|
+
geometry.setWidth(size.width)
|
344
|
+
geometry.setHeight(size.height)
|
345
|
+
@info.setSize(geometry)
|
346
|
+
end
|
347
|
+
|
348
|
+
end
|
349
|
+
|
350
|
+
end
|
351
|
+
end
|