chunky_png 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/chunky_png.gemspec +2 -2
- data/lib/chunky_png.rb +1 -1
- data/lib/chunky_png/canvas.rb +15 -10
- data/lib/chunky_png/canvas/drawing.rb +22 -19
- data/lib/chunky_png/color.rb +20 -9
- data/spec/chunky_png/canvas/drawing_spec.rb +3 -9
- data/spec/chunky_png/color_spec.rb +35 -19
- metadata +3 -3
data/chunky_png.gemspec
CHANGED
@@ -3,8 +3,8 @@ Gem::Specification.new do |s|
|
|
3
3
|
|
4
4
|
# Do not change the version and date fields by hand. This will be done
|
5
5
|
# automatically by the gem release script.
|
6
|
-
s.version = "1.0.
|
7
|
-
s.date = "2011-03-
|
6
|
+
s.version = "1.0.1"
|
7
|
+
s.date = "2011-03-08"
|
8
8
|
|
9
9
|
s.summary = "Pure ruby library for read/write, chunk-level access to PNG files"
|
10
10
|
s.description = <<-EOT
|
data/lib/chunky_png.rb
CHANGED
@@ -25,7 +25,7 @@ module ChunkyPNG
|
|
25
25
|
|
26
26
|
# The current version of ChunkyPNG. This value will be updated
|
27
27
|
# automatically by them <tt>gem:release</tt> rake task.
|
28
|
-
VERSION = "1.0.
|
28
|
+
VERSION = "1.0.1"
|
29
29
|
|
30
30
|
###################################################
|
31
31
|
# PNG international standard defined constants
|
data/lib/chunky_png/canvas.rb
CHANGED
@@ -74,7 +74,7 @@ module ChunkyPNG
|
|
74
74
|
if initial.kind_of?(Array) && initial.length == width * height
|
75
75
|
@pixels = initial
|
76
76
|
else
|
77
|
-
@pixels = Array.new(width * height, ChunkyPNG::Color(initial))
|
77
|
+
@pixels = Array.new(width * height, ChunkyPNG::Color.parse(initial))
|
78
78
|
end
|
79
79
|
end
|
80
80
|
|
@@ -128,10 +128,9 @@ module ChunkyPNG
|
|
128
128
|
#
|
129
129
|
# @raise [ChunkyPNG::OutOfBounds] when the coordinates are outside of the image's dimensions.
|
130
130
|
# @see #set_pixel
|
131
|
-
def []=(
|
132
|
-
|
133
|
-
|
134
|
-
@pixels[point.y * width + point.x] = args.last
|
131
|
+
def []=(x, y, color)
|
132
|
+
assert_xy!(x, y)
|
133
|
+
@pixels[y * width + x] = ChunkyPNG::Color.parse(color)
|
135
134
|
end
|
136
135
|
|
137
136
|
# Replaces a single pixel in this canvas, without bounds checking.
|
@@ -175,10 +174,9 @@ module ChunkyPNG
|
|
175
174
|
#
|
176
175
|
# @raise [ChunkyPNG::OutOfBounds] when the coordinates are outside of the image's dimensions.
|
177
176
|
# @see #get_pixel
|
178
|
-
def [](
|
179
|
-
|
180
|
-
|
181
|
-
@pixels[point.y * width + point.x]
|
177
|
+
def [](x, y)
|
178
|
+
assert_xy!(x, y)
|
179
|
+
@pixels[y * width + x]
|
182
180
|
end
|
183
181
|
|
184
182
|
# Returns a single pixel from this canvas, without checking bounds. The return value for
|
@@ -235,7 +233,14 @@ module ChunkyPNG
|
|
235
233
|
end
|
236
234
|
|
237
235
|
alias_method :include?, :include_point?
|
238
|
-
|
236
|
+
|
237
|
+
# Checks whether the given x- and y-coordinate are in the range of the canvas
|
238
|
+
# @param [Integer] x The x-coordinate of the pixel (column)
|
239
|
+
# @param [Integer] y The y-coordinate of the pixel (row)
|
240
|
+
# @return [true, false] True if the x- and y-coordinate is in the range of this canvas.
|
241
|
+
def include_xy?(x, y)
|
242
|
+
y >= 0 && y < height && x >= 0 && x < width
|
243
|
+
end
|
239
244
|
|
240
245
|
# Checks whether the given y-coordinate is in the range of the canvas
|
241
246
|
# @param [Integer] y The y-coordinate of the pixel (row)
|
@@ -12,18 +12,21 @@ module ChunkyPNG
|
|
12
12
|
module Drawing
|
13
13
|
|
14
14
|
# Composes a pixel on the canvas by alpha blending a color with its background color.
|
15
|
-
# @
|
16
|
-
#
|
17
|
-
#
|
18
|
-
#
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
15
|
+
# @param [Integer] x The x-coordinate of the pixel to blend.
|
16
|
+
# @param [Integer] y The y-coordinate of the pixel to blend.
|
17
|
+
# @param [Integer] color The foreground color to blend with
|
18
|
+
# @return [Integer] The composed color.
|
19
|
+
def compose_pixel(x, y, color)
|
20
|
+
return unless include_xy?(x, y)
|
21
|
+
compose_pixel_unsafe(x, y, ChunkyPNG::Color.parse(color))
|
22
|
+
end
|
23
|
+
|
24
|
+
# Composes a pixel on the canvas by alpha blending a color with its background color,
|
25
|
+
# without bounds checking.
|
26
|
+
# @param (see #compose_pixel)
|
27
|
+
# @return [Integer] The composed color.
|
28
|
+
def compose_pixel_unsafe(x, y, color)
|
29
|
+
set_pixel(x, y, ChunkyPNG::Color.compose(color, get_pixel(x, y)))
|
27
30
|
end
|
28
31
|
|
29
32
|
# Draws an anti-aliased line using Xiaolin Wu's algorithm.
|
@@ -38,7 +41,7 @@ module ChunkyPNG
|
|
38
41
|
# @return [ChunkyPNG::Canvas] Itself, with the line drawn.
|
39
42
|
def line_xiaolin_wu(x0, y0, x1, y1, stroke_color, inclusive = true)
|
40
43
|
|
41
|
-
stroke_color = ChunkyPNG::Color(stroke_color)
|
44
|
+
stroke_color = ChunkyPNG::Color.parse(stroke_color)
|
42
45
|
|
43
46
|
dx = x1 - x0
|
44
47
|
sx = dx < 0 ? -1 : 1
|
@@ -109,8 +112,8 @@ module ChunkyPNG
|
|
109
112
|
vector = ChunkyPNG::Vector(*path)
|
110
113
|
raise ArgumentError, "A polygon requires at least 3 points" if path.length < 3
|
111
114
|
|
112
|
-
stroke_color = ChunkyPNG::Color(stroke_color)
|
113
|
-
fill_color = ChunkyPNG::Color(fill_color)
|
115
|
+
stroke_color = ChunkyPNG::Color.parse(stroke_color)
|
116
|
+
fill_color = ChunkyPNG::Color.parse(fill_color)
|
114
117
|
|
115
118
|
# Fill
|
116
119
|
unless fill_color == ChunkyPNG::Color::TRANSPARENT
|
@@ -150,8 +153,8 @@ module ChunkyPNG
|
|
150
153
|
# @return [ChunkyPNG::Canvas] Itself, with the rectangle drawn.
|
151
154
|
def rect(x0, y0, x1, y1, stroke_color = ChunkyPNG::Color::BLACK, fill_color = ChunkyPNG::Color::TRANSPARENT)
|
152
155
|
|
153
|
-
stroke_color = ChunkyPNG::Color(stroke_color)
|
154
|
-
fill_color = ChunkyPNG::Color(fill_color)
|
156
|
+
stroke_color = ChunkyPNG::Color.parse(stroke_color)
|
157
|
+
fill_color = ChunkyPNG::Color.parse(fill_color)
|
155
158
|
|
156
159
|
# Fill
|
157
160
|
unless fill_color == ChunkyPNG::Color::TRANSPARENT
|
@@ -181,8 +184,8 @@ module ChunkyPNG
|
|
181
184
|
# @return [ChunkyPNG::Canvas] Itself, with the circle drawn.
|
182
185
|
def circle(x0, y0, radius, stroke_color = ChunkyPNG::Color::BLACK, fill_color = ChunkyPNG::Color::TRANSPARENT)
|
183
186
|
|
184
|
-
stroke_color = ChunkyPNG::Color(stroke_color)
|
185
|
-
fill_color = ChunkyPNG::Color(fill_color)
|
187
|
+
stroke_color = ChunkyPNG::Color.parse(stroke_color)
|
188
|
+
fill_color = ChunkyPNG::Color.parse(fill_color)
|
186
189
|
|
187
190
|
f = 1 - radius
|
188
191
|
ddF_x = 1
|
data/lib/chunky_png/color.rb
CHANGED
@@ -25,18 +25,13 @@ module ChunkyPNG
|
|
25
25
|
# @return [Integer] The determined color value as RGBA integer.
|
26
26
|
# @raise [ArgumentError] if the arguments weren't understood as a color.
|
27
27
|
# @see ChunkyPNG::Color
|
28
|
+
# @see ChunkyPNG::Color.parse
|
28
29
|
def self.Color(*args)
|
29
30
|
case args.length
|
30
|
-
when
|
31
|
+
when 1; ChunkyPNG::Color.parse(args.first)
|
32
|
+
when 2; (ChunkyPNG::Color.parse(args.first) & 0xffffff00) | args[1].to_i
|
31
33
|
when 3; ChunkyPNG::Color.rgb(*args)
|
32
|
-
when
|
33
|
-
when 1
|
34
|
-
case source = args.first.to_s
|
35
|
-
when Integer, /^\d+$/; source.to_i
|
36
|
-
when ChunkyPNG::Color::HEX_COLOR_REGEXP; ChunkyPNG::Color.from_hex(source)
|
37
|
-
when ChunkyPNG::Color::HTML_COLOR_REGEXP; ChunkyPNG::Color.html_color(source)
|
38
|
-
else raise ArgumentError, "Don't know how to create a color from #{source.inspect}!"
|
39
|
-
end
|
34
|
+
when 4; ChunkyPNG::Color.rgba(*args)
|
40
35
|
else raise ArgumentError, "Don't know how to create a color from #{args.inspect}!"
|
41
36
|
end
|
42
37
|
end
|
@@ -72,6 +67,22 @@ module ChunkyPNG
|
|
72
67
|
# CONSTRUCTING COLOR VALUES
|
73
68
|
####################################################################
|
74
69
|
|
70
|
+
# Parses a color value given a numeric or string argument.
|
71
|
+
#
|
72
|
+
# It supports color numbers, colors in hex notation and named HTML colors.
|
73
|
+
#
|
74
|
+
# @param [Integer, String] The color value.
|
75
|
+
# @return [Integer] The color value, with the opacity applied if one was given.
|
76
|
+
def parse(source)
|
77
|
+
return source if source.kind_of?(Integer)
|
78
|
+
case source.to_s
|
79
|
+
when /^\d+$/; source.to_s.to_i
|
80
|
+
when ChunkyPNG::Color::HEX_COLOR_REGEXP; ChunkyPNG::Color.from_hex(source.to_s)
|
81
|
+
when ChunkyPNG::Color::HTML_COLOR_REGEXP; ChunkyPNG::Color.html_color(source.to_s)
|
82
|
+
else raise ArgumentError, "Don't know how to create a color from #{source.inspect}!"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
75
86
|
# Creates a new color using an r, g, b triple and an alpha value.
|
76
87
|
# @param [Integer] r The r-component (0-255)
|
77
88
|
# @param [Integer] g The g-component (0-255)
|
@@ -2,27 +2,21 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe ChunkyPNG::Canvas::Drawing do
|
4
4
|
|
5
|
-
describe '#
|
5
|
+
describe '#compose_pixel' do
|
6
6
|
subject { ChunkyPNG::Canvas.new(1, 1, ChunkyPNG::Color.rgb(200, 150, 100)) }
|
7
7
|
|
8
8
|
it "should compose colors correctly" do
|
9
9
|
subject.compose_pixel(0,0, ChunkyPNG::Color(100, 150, 200, 128))
|
10
|
-
subject[
|
10
|
+
subject[0, 0].should == ChunkyPNG::Color(150, 150, 150)
|
11
11
|
end
|
12
12
|
|
13
13
|
it "should return the composed color" do
|
14
14
|
subject.compose_pixel(0, 0, ChunkyPNG::Color.rgba(100, 150, 200, 128)).should == ChunkyPNG::Color.rgb(150, 150, 150)
|
15
15
|
end
|
16
16
|
|
17
|
-
it "should accept point-like arguments as well" do
|
18
|
-
lambda { subject.compose_pixel('0,0', ChunkyPNG::Color.rgba(100, 150, 200, 128)) }.should change { subject['0,0'] }
|
19
|
-
lambda { subject.compose_pixel({:x => 0, :y => 0}, ChunkyPNG::Color.rgba(100, 150, 200, 128)) }.should change { subject['0,0'] }
|
20
|
-
lambda { subject.compose_pixel(ChunkyPNG::Point.new(0, 0), ChunkyPNG::Color.rgba(100, 150, 200, 128)) } .should change { subject['0,0'] }
|
21
|
-
end
|
22
|
-
|
23
17
|
it "should do nothing when the coordinates are out of bounds" do
|
24
18
|
subject.compose_pixel(1, -1, :black).should be_nil
|
25
|
-
lambda { subject.compose_pixel(1, -1, :black) }.should_not change { subject[
|
19
|
+
lambda { subject.compose_pixel(1, -1, :black) }.should_not change { subject[0, 0] }
|
26
20
|
end
|
27
21
|
end
|
28
22
|
|
@@ -1,5 +1,25 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
+
describe 'ChunyPNG.Color' do
|
4
|
+
it "should interpret 4 arguments as RGBA values" do
|
5
|
+
ChunkyPNG::Color(1, 2, 3, 4).should == ChunkyPNG::Color.rgba(1, 2, 3, 4)
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should interpret 3 arguments as RGBA values" do
|
9
|
+
ChunkyPNG::Color(1, 2, 3).should == ChunkyPNG::Color.rgb(1, 2, 3)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should interpret 2 arguments as a color to parse and an opacity value" do
|
13
|
+
ChunkyPNG::Color('0x0a649664', 0xaa).should == 0x0a6496aa
|
14
|
+
ChunkyPNG::Color('spring green @ 0.6666', 0xff).should == 0x00ff7fff
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should interpret 1 argument as a color to parse" do
|
18
|
+
ChunkyPNG::Color.should_receive(:parse).with('0x0a649664')
|
19
|
+
ChunkyPNG::Color('0x0a649664')
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
3
23
|
describe ChunkyPNG::Color do
|
4
24
|
include ChunkyPNG::Color
|
5
25
|
|
@@ -11,25 +31,21 @@ describe ChunkyPNG::Color do
|
|
11
31
|
@fully_transparent = 0x0a649600
|
12
32
|
end
|
13
33
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
ChunkyPNG::Color('spring green').should == 0x00ff7fff
|
30
|
-
ChunkyPNG::Color('spring green @ 0.6666').should == 0x00ff7faa
|
31
|
-
ChunkyPNG::Color('spring green', 0xaa).should == 0x00ff7faa
|
32
|
-
ChunkyPNG::Color('spring green @ 0.6666', 0xff).should == 0x00ff7fff
|
34
|
+
describe '#parse' do
|
35
|
+
it "should interpret a hex string correctly" do
|
36
|
+
parse('0x0a649664').should == ChunkyPNG::Color.from_hex('#0a649664')
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should interpret a color name correctly" do
|
40
|
+
parse(:spring_green).should == 0x00ff7fff
|
41
|
+
parse('spring green').should == 0x00ff7fff
|
42
|
+
parse('spring green @ 0.6666').should == 0x00ff7faa
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should return numbers as is" do
|
46
|
+
parse('12345').should == 12345
|
47
|
+
parse(12345).should == 12345
|
48
|
+
end
|
33
49
|
end
|
34
50
|
|
35
51
|
describe '#pixel_bytesize' do
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 1
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: 1.0.
|
8
|
+
- 1
|
9
|
+
version: 1.0.1
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Willem van Bergen
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2011-03-
|
17
|
+
date: 2011-03-08 00:00:00 -05:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|