rmagick4j 0.3.5
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +84 -0
- data/LICENSE.txt +9 -0
- data/Manifest.txt +142 -0
- data/README.txt +25 -0
- data/Rakefile +109 -0
- data/lib/RMagick.rb +1861 -0
- data/lib/jhlabs-filters.jar +0 -0
- data/lib/magick4j.jar +0 -0
- data/lib/rmagick4j/constants.rb +21 -0
- data/lib/rmagick4j/draw.rb +86 -0
- data/lib/rmagick4j/enum.rb +120 -0
- data/lib/rmagick4j/gradient_fill.rb +14 -0
- data/lib/rmagick4j/image.rb +289 -0
- data/lib/rmagick4j/image_list.rb +21 -0
- data/lib/rmagick4j/pixel.rb +170 -0
- data/lib/rmagick4j/rmagick4j.rb +19 -0
- 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 +48 -0
- data/lib/rvg/container.rb +131 -0
- data/lib/rvg/deep_equal.rb +56 -0
- data/lib/rvg/describable.rb +53 -0
- data/lib/rvg/embellishable.rb +417 -0
- data/lib/rvg/misc.rb +739 -0
- data/lib/rvg/paint.rb +55 -0
- data/lib/rvg/pathdata.rb +131 -0
- data/lib/rvg/rvg.rb +283 -0
- data/lib/rvg/stretchable.rb +168 -0
- data/lib/rvg/stylable.rb +118 -0
- data/lib/rvg/text.rb +187 -0
- data/lib/rvg/transformable.rb +133 -0
- data/lib/rvg/units.rb +66 -0
- data/lib/svgsalamander.jar +0 -0
- data/test/RMagickTestSuite.rb +129 -0
- data/test/eyetests/bullseye.rb +150 -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_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 +20 -0
- data/test/eyetests/tests/draw_pattern_1.rb +35 -0
- data/test/eyetests/tests/draw_polygon_affine.rb +21 -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_rectangle_affine.rb +16 -0
- data/test/eyetests/tests/draw_rectangle_basic.rb +16 -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_roundrectangle_affine.rb +19 -0
- data/test/eyetests/tests/draw_roundrectangle_basic.rb +16 -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_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_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 +24 -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 +28 -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 +16 -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 +120 -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 +283 -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_legend.rb +71 -0
- data/test/gruff_tests/test/test_line.rb +493 -0
- data/test/gruff_tests/test/test_mini_bar.rb +32 -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_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 +24 -0
- data/test/spec/image_constants.rb +76 -0
- data/test/spec/image_spec.rb +23 -0
- data/test/spec/pixel_spec.rb +84 -0
- data/test/spec/stories/geometry_runner.rb +13 -0
- data/test/spec/stories/geometry_steps.rb +24 -0
- data/test/spec/stories/geometry_story.rb +116 -0
- data/test/spec/stories/image_filling_runner.rb +13 -0
- data/test/spec/stories/image_filling_steps.rb +64 -0
- data/test/spec/stories/image_filling_story.rb +41 -0
- metadata +215 -0
Binary file
|
data/lib/magick4j.jar
ADDED
Binary file
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Magick
|
2
|
+
Magick4J = Java::magick4j
|
3
|
+
RMagick4J = Java::rmagick4j
|
4
|
+
|
5
|
+
|
6
|
+
QuantumDepth = 8
|
7
|
+
QuantumRange = 2**QuantumDepth-1
|
8
|
+
QuantumScale = 1.0/QuantumRange.to_f
|
9
|
+
|
10
|
+
# Geometries
|
11
|
+
JGeometry = Magick4J::Geometry
|
12
|
+
|
13
|
+
JGeometries = [
|
14
|
+
JGeometry,
|
15
|
+
Magick4J::PercentGeometry,
|
16
|
+
Magick4J::AspectGeometry,
|
17
|
+
Magick4J::LessGeometry,
|
18
|
+
Magick4J::GreaterGeometry,
|
19
|
+
Magick4J::AreaGeometry
|
20
|
+
]
|
21
|
+
end
|
@@ -0,0 +1,86 @@
|
|
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
|
+
@draw.annotate(img._image, width, height, x, y, text)
|
8
|
+
self
|
9
|
+
end
|
10
|
+
|
11
|
+
def draw(image)
|
12
|
+
@draw.clone.draw(image._image, Magick4J.CommandParser.parse(@primitives))
|
13
|
+
self
|
14
|
+
end
|
15
|
+
|
16
|
+
def fill= fill
|
17
|
+
@draw.fill = Magick4J.ColorDatabase.query_default(fill)
|
18
|
+
self
|
19
|
+
end
|
20
|
+
|
21
|
+
def font_family= font_family
|
22
|
+
@draw.font_family = font_family
|
23
|
+
self
|
24
|
+
end
|
25
|
+
|
26
|
+
def font_weight= font_weight
|
27
|
+
font_weight = {BoldWeight => 700, NormalWeight => 400}[font_weight]
|
28
|
+
@draw.font_weight = font_weight
|
29
|
+
end
|
30
|
+
|
31
|
+
def get_type_metrics(*args)
|
32
|
+
raise ArgumentError.new('wrong number of arguments (#{args.length})') if not (1..2) === args.length
|
33
|
+
string = args.last
|
34
|
+
image = args.first._image if args.length == 2
|
35
|
+
jmetrics = @draw.getTypeMetrics(string, image)
|
36
|
+
metrics = TypeMetric.new
|
37
|
+
metrics.ascent = jmetrics.getAscent
|
38
|
+
metrics.descent = jmetrics.getDescent
|
39
|
+
metrics.height = jmetrics.getHeight
|
40
|
+
metrics.max_advance = jmetrics.getMaxAdvance
|
41
|
+
metrics.width = jmetrics.getWidth
|
42
|
+
metrics
|
43
|
+
end
|
44
|
+
|
45
|
+
def font= font
|
46
|
+
# TODO
|
47
|
+
end
|
48
|
+
|
49
|
+
def gravity= gravity
|
50
|
+
@draw.setGravity(gravity._val)
|
51
|
+
end
|
52
|
+
|
53
|
+
def initialize
|
54
|
+
# Docs say that you can initialize with a block, but it doesn't really work because it inits an ImageInfo not a DrawInfo.
|
55
|
+
# instance_eval &add if add
|
56
|
+
@draw = Magick4J::DrawInfo.new
|
57
|
+
@primitives = ''
|
58
|
+
end
|
59
|
+
|
60
|
+
def inspect
|
61
|
+
@primitives
|
62
|
+
end
|
63
|
+
|
64
|
+
def pointsize= pointsize
|
65
|
+
@draw.setPointSize(pointsize)
|
66
|
+
end
|
67
|
+
|
68
|
+
def primitive primitive
|
69
|
+
# TODO Concat in a string like they do, then use helper to parse later
|
70
|
+
@primitives << "\n" unless @primitives.empty?
|
71
|
+
@primitives << primitive.gsub(/[\r|\n]/, '')
|
72
|
+
self
|
73
|
+
end
|
74
|
+
|
75
|
+
def rotation= rotation
|
76
|
+
@draw.rotate(rotation)
|
77
|
+
self
|
78
|
+
end
|
79
|
+
|
80
|
+
def stroke= stroke
|
81
|
+
@draw.setStroke(Magick4J.ColorDatabase.queryDefault(stroke))
|
82
|
+
self
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
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,289 @@
|
|
1
|
+
|
2
|
+
module Magick
|
3
|
+
class Image
|
4
|
+
|
5
|
+
def self.from_blob(blob, &add)
|
6
|
+
# TODO multiple images in file
|
7
|
+
[Image.from_image(Magick4J.MagickImage.from_blob(blob.to_java_bytes), &add)]
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.read(file, &add)
|
11
|
+
info = Info.new(&add)
|
12
|
+
image = Magick4J.ImageDatabase.createDefault(file.to_s, info._info) || Magick4J.MagickImage.new(java.io.File.new(file.to_s))
|
13
|
+
[Image.from_image(image,&add)]
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.from_image(image, &add)
|
17
|
+
raise ArgumentError, 'First parameter must be a MagickImage instance.' unless image.is_a? Magick4J.MagickImage
|
18
|
+
magick_image = Image.new(image.getWidth(), image.getHeight(), &add)
|
19
|
+
magick_image._image = image
|
20
|
+
magick_image
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.allocate(*args, &add)
|
24
|
+
info = Info.new(&add)
|
25
|
+
if args.length == 1
|
26
|
+
case args[0]
|
27
|
+
when String then
|
28
|
+
# TODO Respect Dir.getwd
|
29
|
+
name = args[0]
|
30
|
+
@image = Magick4J.ImageDatabase.createDefault(name, info._info) || Magick4J.MagickImage.new(java.io.File.new(name))
|
31
|
+
when Magick4J.MagickImage then
|
32
|
+
@image = args[0]
|
33
|
+
when Image then
|
34
|
+
@image = args[0]._image
|
35
|
+
else
|
36
|
+
raise ArgumentError, "The argument just can be a String, a MagickImage or an Image instance."
|
37
|
+
end
|
38
|
+
else
|
39
|
+
@image = Magick4J.MagickImage.new(args[0], args[1], info._info)
|
40
|
+
if args.length == 3
|
41
|
+
args[2].fill(self)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def background_color
|
47
|
+
@image.getBackgroundColor
|
48
|
+
end
|
49
|
+
|
50
|
+
def background_color=(value)
|
51
|
+
raise TypeError, "argument must be color name or pixel (#{value.class} given)" unless value.is_a?(String) || value.is_a?(Pixel)
|
52
|
+
value = Pixel.from_color(value) if value.is_a?(String)
|
53
|
+
@image.setBackgroundColor(value)
|
54
|
+
end
|
55
|
+
|
56
|
+
def blur_image(radius=0.0, sigma=1.0)
|
57
|
+
# Swap order on purpose. I wanted them the other way around in Magick4J.
|
58
|
+
Image.from_image(@image.blurred(sigma, radius))
|
59
|
+
end
|
60
|
+
|
61
|
+
def change_geometry(geometry)
|
62
|
+
geometry = Geometry.from_s(geometry.to_s) unless geometry.is_a? Geometry
|
63
|
+
index = if geometry.flag.nil?
|
64
|
+
0
|
65
|
+
else
|
66
|
+
geometry.flag._val
|
67
|
+
end
|
68
|
+
geometry = JGeometries[index].new( geometry.width, geometry.height,
|
69
|
+
geometry.x, geometry.y)
|
70
|
+
yield geometry.calculate_width(self._image),
|
71
|
+
geometry.calculate_height(self._image),
|
72
|
+
self
|
73
|
+
end
|
74
|
+
|
75
|
+
def columns
|
76
|
+
@image.getWidth
|
77
|
+
end
|
78
|
+
|
79
|
+
def composite(*args)
|
80
|
+
# image, x, y, composite_op
|
81
|
+
args[0] = args[0]._image
|
82
|
+
args.map! {|arg| arg.is_a?(Enum) ? arg._val : arg}
|
83
|
+
Image.from_image(@image.composited(*args))
|
84
|
+
end
|
85
|
+
|
86
|
+
def copy
|
87
|
+
Image.from_image(@image.clone)
|
88
|
+
end
|
89
|
+
|
90
|
+
def crop(*args)
|
91
|
+
copy.crop!(*args)
|
92
|
+
end
|
93
|
+
|
94
|
+
def crop!(*args)
|
95
|
+
# gravity, x, y, width, height, reset_offset
|
96
|
+
# Defaults.
|
97
|
+
gravity = nil
|
98
|
+
x = y = -1
|
99
|
+
reset_offset = false
|
100
|
+
# Find available args.
|
101
|
+
if args.first.is_a? GravityType
|
102
|
+
gravity = args.shift._val
|
103
|
+
end
|
104
|
+
if [FalseClass, TrueClass].member? args.last.class
|
105
|
+
reset = args.pop
|
106
|
+
end
|
107
|
+
if args.length == 4
|
108
|
+
x, y = args[0..1]
|
109
|
+
end
|
110
|
+
width, height = args[-2..-1]
|
111
|
+
# Call Java.
|
112
|
+
# TODO Why wouldn't we reset offset information? Do we need to use that?
|
113
|
+
@image = unless gravity.nil?
|
114
|
+
if x == -1 || y == -1
|
115
|
+
@image.crop(gravity, width, height)
|
116
|
+
else
|
117
|
+
@image.crop(gravity, x, y, width, height)
|
118
|
+
end
|
119
|
+
else
|
120
|
+
@image.crop(x,y,width,height)
|
121
|
+
end
|
122
|
+
self
|
123
|
+
end
|
124
|
+
|
125
|
+
def display
|
126
|
+
@image.display
|
127
|
+
self
|
128
|
+
end
|
129
|
+
|
130
|
+
def erase!
|
131
|
+
@image.erase
|
132
|
+
end
|
133
|
+
|
134
|
+
def format
|
135
|
+
@image.getFormat
|
136
|
+
end
|
137
|
+
|
138
|
+
def format= format
|
139
|
+
@image.setFormat(format)
|
140
|
+
self
|
141
|
+
end
|
142
|
+
|
143
|
+
def flip
|
144
|
+
copy.flip
|
145
|
+
end
|
146
|
+
|
147
|
+
def flip!
|
148
|
+
@image.flip
|
149
|
+
self
|
150
|
+
end
|
151
|
+
|
152
|
+
def _image
|
153
|
+
@image
|
154
|
+
end
|
155
|
+
|
156
|
+
def _image=(new_image)
|
157
|
+
@image = new_image
|
158
|
+
end
|
159
|
+
|
160
|
+
def _info
|
161
|
+
@info
|
162
|
+
end
|
163
|
+
|
164
|
+
def _info=(new_info)
|
165
|
+
@info = new_info
|
166
|
+
end
|
167
|
+
|
168
|
+
def initialize(columns, rows, fill=nil, &info_block)
|
169
|
+
info = Info.new(&info_block)
|
170
|
+
@image = Magick4J.MagickImage.new(columns, rows, info._info)
|
171
|
+
fill.fill(self) if fill.respond_to? :fill
|
172
|
+
end
|
173
|
+
|
174
|
+
def matte= matte
|
175
|
+
@image.setMatte(matte)
|
176
|
+
end
|
177
|
+
|
178
|
+
def quantize(number_colors=256, colorspace=RGBColorspace, dither=true, tree_depth=0, measure_error=false)
|
179
|
+
Image.from_image(@image.quantized(number_colors, colorspace._val, dither, tree_depth, measure_error))
|
180
|
+
end
|
181
|
+
|
182
|
+
def raise(width=6, height=6, raise=true)
|
183
|
+
Image.from_image(@image.raised(width, height, raise))
|
184
|
+
end
|
185
|
+
|
186
|
+
def resize(*args)
|
187
|
+
copy.resize!(*args)
|
188
|
+
end
|
189
|
+
|
190
|
+
def resize!(*args)
|
191
|
+
@image = if args.length == 1
|
192
|
+
@image.resized(args[0])
|
193
|
+
elsif args.length == 2 # It must be 4 nor 2, but two of them are not yet implemented
|
194
|
+
# TODO Implement the other two arguments.
|
195
|
+
# arg[0] --> new_width
|
196
|
+
# arg[1] --> new_height
|
197
|
+
# arg[2] --> filter=LanczosFilter
|
198
|
+
# arg[3] --> support=1.0
|
199
|
+
@image.resized(args[0],args[1])
|
200
|
+
else
|
201
|
+
Kernel.raise ArgumentError, "wrong number of parameters(#{args.length} for 1 or 4)"
|
202
|
+
end
|
203
|
+
self
|
204
|
+
end
|
205
|
+
|
206
|
+
def rotate(amount, qualifier=nil)
|
207
|
+
copy.rotate!(amount,qualifier)
|
208
|
+
end
|
209
|
+
|
210
|
+
def rotate!(amount, qualifier=nil)
|
211
|
+
if qualifier == '<' && columns < rows
|
212
|
+
@image.rotate(amount)
|
213
|
+
self
|
214
|
+
elsif qualifier == '>' && columns > rows
|
215
|
+
@image.rotate(amount)
|
216
|
+
self
|
217
|
+
elsif qualifier.nil?
|
218
|
+
@image.rotate(amount)
|
219
|
+
self
|
220
|
+
else
|
221
|
+
nil
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
def rows
|
226
|
+
@image.getHeight
|
227
|
+
end
|
228
|
+
|
229
|
+
def store_pixels(x, y, columns, rows, pixels)
|
230
|
+
ria_size = columns*rows
|
231
|
+
raise IndexError, "not enough elements in array - expecting #{ria_size}, got #{pixels.size}" if pixels.size < ria_size
|
232
|
+
@image.storePixels(x,y,columns,rows,pixels.to_java)
|
233
|
+
end
|
234
|
+
|
235
|
+
def to_blob(&add)
|
236
|
+
info = Info.new(&add)
|
237
|
+
@image.setFormat(info.format) if info.format
|
238
|
+
String.from_java_bytes(@image.toBlob)
|
239
|
+
end
|
240
|
+
|
241
|
+
def watermark(mark, lightness=1.0, saturation=1.0, gravity=nil, x_offset=0, y_offset=0)
|
242
|
+
if gravity.is_a? Numeric
|
243
|
+
# gravity is technically an optional argument in the middle.
|
244
|
+
gravity = nil
|
245
|
+
y_offset = x_offset
|
246
|
+
x_offset = gravity
|
247
|
+
end
|
248
|
+
# TODO Perform watermark.
|
249
|
+
self
|
250
|
+
end
|
251
|
+
|
252
|
+
def write(file, &add)
|
253
|
+
# TODO I'm having trouble finding out how this info is used, so I'll skip using it for now.
|
254
|
+
info = Info.new(&add)
|
255
|
+
# TODO Resolve pwd as needed
|
256
|
+
@image.write(file)
|
257
|
+
self
|
258
|
+
end
|
259
|
+
|
260
|
+
class Info
|
261
|
+
|
262
|
+
# TODO Replace with call to Java, or is this the better way? Should it be converted to the Java version only later?
|
263
|
+
def background_color= background_color
|
264
|
+
@info.setBackgroundColor(Magick4J.ColorDatabase.queryDefault(background_color))
|
265
|
+
end
|
266
|
+
|
267
|
+
attr_accessor :format
|
268
|
+
|
269
|
+
def _info
|
270
|
+
@info
|
271
|
+
end
|
272
|
+
|
273
|
+
def initialize(&add)
|
274
|
+
@info = Magick4J.ImageInfo.new
|
275
|
+
instance_eval &add if add
|
276
|
+
end
|
277
|
+
|
278
|
+
def size= size
|
279
|
+
size = Geometry.from_s(size) if size.is_a? String
|
280
|
+
geometry = Magick4J.Geometry.new
|
281
|
+
geometry.setWidth(size.width)
|
282
|
+
geometry.setHeight(size.height)
|
283
|
+
@info.setSize(geometry)
|
284
|
+
end
|
285
|
+
|
286
|
+
end
|
287
|
+
|
288
|
+
end
|
289
|
+
end
|