chunky_png 0.5.3 → 0.5.4
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.
- data/README.rdoc +6 -8
- data/chunky_png.gemspec +4 -4
- data/lib/chunky_png.rb +4 -2
- data/lib/chunky_png/canvas.rb +11 -1
- data/lib/chunky_png/canvas/drawing.rb +60 -0
- data/lib/chunky_png/canvas/png_encoding.rb +2 -1
- data/lib/chunky_png/chunk.rb +114 -4
- data/lib/chunky_png/color.rb +10 -1
- data/lib/chunky_png/datastream.rb +8 -7
- data/lib/chunky_png/rmagick.rb +1 -1
- data/spec/chunky_png/canvas/drawing_spec.rb +29 -0
- data/spec/resources/lines.png +0 -0
- metadata +5 -2
data/README.rdoc
CHANGED
|
@@ -16,7 +16,7 @@ Issue tracker:: http://github.com/wvanbergen/chunky_png/issues
|
|
|
16
16
|
color modes and all transparency, interlacing and filtering options.
|
|
17
17
|
* Encodes images supports all color modes (true color, grayscale and indexed)
|
|
18
18
|
and transparency for all these color modes. The best color mode will be
|
|
19
|
-
chosen automatically, based on the
|
|
19
|
+
chosen automatically, based on the amount of used colors.
|
|
20
20
|
* R/W access to the image's pixels.
|
|
21
21
|
* R/W access to all image metadata that is stored in chunks.
|
|
22
22
|
* Memory efficient (uses a Fixnum, i.e. 4 bytes of memory, per pixel)
|
|
@@ -26,12 +26,12 @@ Issue tracker:: http://github.com/wvanbergen/chunky_png/issues
|
|
|
26
26
|
|
|
27
27
|
== Classes
|
|
28
28
|
|
|
29
|
-
The main classes used within ChunkyPNG are:
|
|
29
|
+
The main classes and modules used within ChunkyPNG are:
|
|
30
30
|
|
|
31
31
|
<tt>ChunkyPNG::Image</tt> :: create PNG images from scratch or based on another PNG image.
|
|
32
32
|
<tt>ChunkyPNG::Datastream</tt> :: low-level read and write access to PNG images from or to a file or stream.
|
|
33
33
|
<tt>ChunkyPNG::Canvas</tt> :: represents an image canvas as a matrix of pixels.
|
|
34
|
-
<tt>ChunkyPNG::Color</tt> ::
|
|
34
|
+
<tt>ChunkyPNG::Color</tt> :: to handle Fixnums as color values.
|
|
35
35
|
|
|
36
36
|
== Usage
|
|
37
37
|
|
|
@@ -53,19 +53,17 @@ The main classes used within ChunkyPNG are:
|
|
|
53
53
|
image = ChunkyPNG::Image.from_file('with_metadata.png')
|
|
54
54
|
puts image.metadata['Title']
|
|
55
55
|
image.metadata['Author'] = 'Willem van Bergen'
|
|
56
|
-
image.save('with_metadata.png') # Overwrite
|
|
56
|
+
image.save('with_metadata.png') # Overwrite file
|
|
57
57
|
|
|
58
58
|
# Low level access to PNG chunks
|
|
59
59
|
png_stream = ChunkyPNG::Datastream.from_file('filename.png')
|
|
60
60
|
png_stream.each_chunk { |chunk| p chunk.type }
|
|
61
61
|
|
|
62
|
-
(Note: this is subject to change while work is in progress)
|
|
63
|
-
|
|
64
62
|
== About
|
|
65
63
|
|
|
66
64
|
The library is written by Willem van Bergen for Floorplanner.com, and released
|
|
67
65
|
under the MIT license (see LICENSE). Please contact me for questions or
|
|
68
|
-
remarks. Patches are greatly appreciated!
|
|
66
|
+
remarks. Patches are greatly appreciated!
|
|
69
67
|
|
|
70
68
|
P.S.: The name of this library is intentionally similar to Chunky Bacon and
|
|
71
|
-
Chunky GIF. Use Google if you want to know _why.
|
|
69
|
+
Chunky GIF. Use Google if you want to know _why. :-)
|
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 = "0.5.
|
|
7
|
-
s.date = "2010-01-
|
|
6
|
+
s.version = "0.5.4"
|
|
7
|
+
s.date = "2010-01-18"
|
|
8
8
|
|
|
9
9
|
s.summary = "Pure ruby library for read/write, chunk-level access to PNG files"
|
|
10
10
|
s.description = <<-EOT
|
|
@@ -32,6 +32,6 @@ Gem::Specification.new do |s|
|
|
|
32
32
|
|
|
33
33
|
# Do not change the files and test_files fields by hand. This will be done
|
|
34
34
|
# automatically by the gem release script.
|
|
35
|
-
s.files = %w(spec/spec_helper.rb spec/resources/ztxt_chunk.png spec/resources/text_chunk.png spec/resources/replaced.png spec/resources/pixelstream.rgb spec/resources/indexed_4bit.png spec/resources/gray_10x10_grayscale.png spec/resources/damaged_signature.png spec/resources/damaged_chunk.png spec/chunky_png/canvas/png_encoding_spec.rb lib/chunky_png/canvas/stream_exporting.rb spec/resources/gray_10x10.png lib/chunky_png/color.rb lib/chunky_png/canvas/operations.rb .gitignore spec/resources/gray_10x10_truecolor_alpha.png spec/chunky_png/canvas_spec.rb LICENSE spec/resources/gray_10x10_truecolor.png spec/resources/composited.png spec/chunky_png/color_spec.rb spec/chunky_png/canvas/adam7_interlacing_spec.rb lib/chunky_png/chunk.rb lib/chunky_png/canvas/stream_importing.rb lib/chunky_png/canvas/png_encoding.rb lib/chunky_png/canvas/adam7_interlacing.rb spec/resources/operations.png spec/chunky_png/canvas/png_decoding_spec.rb lib/chunky_png/canvas.rb Rakefile spec/resources/transparent_gray_10x10.png spec/resources/pixelstream.rgba spec/resources/cropped.png README.rdoc spec/resources/gray_10x10_indexed.png spec/resources/16x16_non_interlaced.png spec/chunky_png_spec.rb lib/chunky_png/palette.rb lib/chunky_png/datastream.rb chunky_png.gemspec tasks/github-gem.rake spec/resources/pixelstream_reference.png spec/resources/gray_10x10_grayscale_alpha.png spec/resources/16x16_interlaced.png spec/chunky_png/image_spec.rb lib/chunky_png/canvas/drawing.rb spec/resources/adam7.png lib/chunky_png/rmagick.rb lib/chunky_png/image.rb spec/chunky_png/rmagick_spec.rb spec/chunky_png/datastream_spec.rb lib/chunky_png/canvas/png_decoding.rb lib/chunky_png.rb)
|
|
36
|
-
s.test_files = %w(spec/chunky_png/canvas/png_encoding_spec.rb spec/chunky_png/canvas_spec.rb spec/chunky_png/color_spec.rb spec/chunky_png/canvas/adam7_interlacing_spec.rb spec/chunky_png/canvas/png_decoding_spec.rb spec/chunky_png_spec.rb spec/chunky_png/image_spec.rb spec/chunky_png/rmagick_spec.rb spec/chunky_png/datastream_spec.rb)
|
|
35
|
+
s.files = %w(spec/spec_helper.rb spec/resources/ztxt_chunk.png spec/resources/text_chunk.png spec/resources/replaced.png spec/resources/pixelstream.rgb spec/resources/indexed_4bit.png spec/resources/gray_10x10_grayscale.png spec/resources/damaged_signature.png spec/resources/damaged_chunk.png spec/chunky_png/canvas/png_encoding_spec.rb lib/chunky_png/canvas/stream_exporting.rb spec/resources/gray_10x10.png lib/chunky_png/color.rb lib/chunky_png/canvas/operations.rb .gitignore spec/resources/gray_10x10_truecolor_alpha.png spec/chunky_png/canvas_spec.rb LICENSE spec/resources/gray_10x10_truecolor.png spec/resources/composited.png spec/chunky_png/color_spec.rb spec/chunky_png/canvas/adam7_interlacing_spec.rb lib/chunky_png/chunk.rb lib/chunky_png/canvas/stream_importing.rb lib/chunky_png/canvas/png_encoding.rb lib/chunky_png/canvas/adam7_interlacing.rb spec/resources/operations.png spec/chunky_png/canvas/png_decoding_spec.rb lib/chunky_png/canvas.rb Rakefile spec/resources/transparent_gray_10x10.png spec/resources/pixelstream.rgba spec/resources/cropped.png README.rdoc spec/resources/gray_10x10_indexed.png spec/resources/16x16_non_interlaced.png spec/chunky_png_spec.rb spec/chunky_png/canvas/drawing_spec.rb lib/chunky_png/palette.rb lib/chunky_png/datastream.rb chunky_png.gemspec tasks/github-gem.rake spec/resources/pixelstream_reference.png spec/resources/lines.png spec/resources/gray_10x10_grayscale_alpha.png spec/resources/16x16_interlaced.png spec/chunky_png/image_spec.rb lib/chunky_png/canvas/drawing.rb spec/resources/adam7.png lib/chunky_png/rmagick.rb lib/chunky_png/image.rb spec/chunky_png/rmagick_spec.rb spec/chunky_png/datastream_spec.rb lib/chunky_png/canvas/png_decoding.rb lib/chunky_png.rb)
|
|
36
|
+
s.test_files = %w(spec/chunky_png/canvas/png_encoding_spec.rb spec/chunky_png/canvas_spec.rb spec/chunky_png/color_spec.rb spec/chunky_png/canvas/adam7_interlacing_spec.rb spec/chunky_png/canvas/png_decoding_spec.rb spec/chunky_png_spec.rb spec/chunky_png/canvas/drawing_spec.rb spec/chunky_png/image_spec.rb spec/chunky_png/rmagick_spec.rb spec/chunky_png/datastream_spec.rb)
|
|
37
37
|
end
|
data/lib/chunky_png.rb
CHANGED
|
@@ -16,15 +16,17 @@ require 'chunky_png/canvas/drawing'
|
|
|
16
16
|
require 'chunky_png/canvas'
|
|
17
17
|
require 'chunky_png/image'
|
|
18
18
|
|
|
19
|
-
# ChunkyPNG
|
|
19
|
+
# ChunkyPNG - the pury ruby library to access PNG files.
|
|
20
20
|
#
|
|
21
21
|
# The ChunkyPNG module defines some constants that are used in the
|
|
22
22
|
# PNG specification.
|
|
23
|
+
#
|
|
24
|
+
# @author Willem van Bergen
|
|
23
25
|
module ChunkyPNG
|
|
24
26
|
|
|
25
27
|
# The current version of ChunkyPNG. This value will be updated automatically
|
|
26
28
|
# by them gem:release rake task.
|
|
27
|
-
VERSION = "0.5.
|
|
29
|
+
VERSION = "0.5.4"
|
|
28
30
|
|
|
29
31
|
###################################################
|
|
30
32
|
# PNG international standard defined constants
|
data/lib/chunky_png/canvas.rb
CHANGED
|
@@ -108,6 +108,15 @@ module ChunkyPNG
|
|
|
108
108
|
def [](x, y)
|
|
109
109
|
@pixels[y * width + x]
|
|
110
110
|
end
|
|
111
|
+
|
|
112
|
+
# Checks whether the given coordinates are in the range of the canvas
|
|
113
|
+
# @param [Integer] x The x-coordinate of the pixel (column)
|
|
114
|
+
# @param [Integer] y The y-coordinate of the pixel (row)
|
|
115
|
+
# @return [true, false] True if the x and y coordinate are in the range
|
|
116
|
+
# of this canvas.
|
|
117
|
+
def include?(x, y)
|
|
118
|
+
(0...width).include?(x) && (0...height).include?(y)
|
|
119
|
+
end
|
|
111
120
|
|
|
112
121
|
# Returns the palette used for this canvas.
|
|
113
122
|
# @return [ChunkyPNG::Palette] A pallete which contains all the colors that are
|
|
@@ -131,7 +140,8 @@ module ChunkyPNG
|
|
|
131
140
|
# EXPORTING
|
|
132
141
|
#################################################################
|
|
133
142
|
|
|
134
|
-
# Creates an ChunkyPNG::Image object from this canvas
|
|
143
|
+
# Creates an ChunkyPNG::Image object from this canvas.
|
|
144
|
+
# @return [ChunkyPNG::Image] This canvas wrapped in an Image instance.
|
|
135
145
|
def to_image
|
|
136
146
|
ChunkyPNG::Image.from_canvas(self)
|
|
137
147
|
end
|
|
@@ -3,6 +3,66 @@ module ChunkyPNG
|
|
|
3
3
|
|
|
4
4
|
module Drawing
|
|
5
5
|
|
|
6
|
+
# Sets a point on the canvas by composing a pixel with its background color.
|
|
7
|
+
def point(x, y, color)
|
|
8
|
+
self[x, y] = ChunkyPNG::Color.compose(color, self[x, y])
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# Draws an anti-aliased line using Xiaolin Wu's algorithm.
|
|
12
|
+
#
|
|
13
|
+
def line_xiaolin_wu(x0, y0, x1, y1, color)
|
|
14
|
+
y0, y1, x0, x1 = y1, y0, x1, x0 if y0 > y1
|
|
15
|
+
dx = x1 - x0
|
|
16
|
+
sx = dx < 0 ? -1 : 1
|
|
17
|
+
dx *= sx
|
|
18
|
+
dy = y1 - y0
|
|
19
|
+
|
|
20
|
+
if dy == 0 # vertical line
|
|
21
|
+
Range.new(*[x0,x1].sort).each do |x|
|
|
22
|
+
point(x, y0, color)
|
|
23
|
+
end
|
|
24
|
+
elsif dx == 0 # horizontal line
|
|
25
|
+
(y0..y1).each do |y|
|
|
26
|
+
point(x0, y, color)
|
|
27
|
+
end
|
|
28
|
+
elsif dx == dy # diagonal
|
|
29
|
+
x0.step(x1, sx) do |x|
|
|
30
|
+
point(x, y0, color)
|
|
31
|
+
y0 += 1
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
elsif dy > dx # vertical displacement
|
|
35
|
+
point(x0, y0, color)
|
|
36
|
+
e_acc = 0
|
|
37
|
+
e = ((dx << 16) / dy.to_f).round
|
|
38
|
+
(y0...y1-1).each do |i|
|
|
39
|
+
e_acc_temp, e_acc = e_acc, (e_acc + e) & 0xffff
|
|
40
|
+
x0 = x0 + sx if (e_acc <= e_acc_temp)
|
|
41
|
+
w = 0xff - (e_acc >> 8)
|
|
42
|
+
point(x0, y0, ChunkyPNG::Color.fade(color, w)) if include?(x0, y0)
|
|
43
|
+
y0 = y0 + 1
|
|
44
|
+
point(x0 + sx, y0, ChunkyPNG::Color.fade(color, 0xff - w)) if include?(x0 + sx, y0)
|
|
45
|
+
end
|
|
46
|
+
point(x1, y1, color)
|
|
47
|
+
|
|
48
|
+
else # horizontal displacement
|
|
49
|
+
point(x0, y0, color)
|
|
50
|
+
e_acc = 0
|
|
51
|
+
e = (dy << 16) / dx
|
|
52
|
+
(dx - 1).downto(0) do |i|
|
|
53
|
+
e_acc_temp, e_acc = e_acc, (e_acc + e) & 0xffff
|
|
54
|
+
y0 += 1 if (e_acc <= e_acc_temp)
|
|
55
|
+
w = 0xff - (e_acc >> 8)
|
|
56
|
+
point(x0, y0, ChunkyPNG::Color.fade(color, w)) if include?(x0, y0)
|
|
57
|
+
x0 += sx
|
|
58
|
+
point(x0, y0 + 1, ChunkyPNG::Color.fade(color, 0xff - w)) if include?(x0, y0 + 1)
|
|
59
|
+
end
|
|
60
|
+
point(x1, y1, color)
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
alias :line :line_xiaolin_wu
|
|
65
|
+
|
|
6
66
|
end
|
|
7
67
|
end
|
|
8
68
|
end
|
|
@@ -141,7 +141,8 @@ module ChunkyPNG
|
|
|
141
141
|
end
|
|
142
142
|
|
|
143
143
|
# Passes to this canvas of pixel values line by line.
|
|
144
|
-
# @yield [
|
|
144
|
+
# @yield [line] Yields the scanlines of this image one by one.
|
|
145
|
+
# @yieldparam [Array<Fixnum>] line An line of fixnums representing pixels
|
|
145
146
|
def each_scanline(&block)
|
|
146
147
|
for line_no in 0...height do
|
|
147
148
|
scanline = pixels[width * line_no, width]
|
data/lib/chunky_png/chunk.rb
CHANGED
|
@@ -9,6 +9,8 @@ module ChunkyPNG
|
|
|
9
9
|
# represented by the {ChunkyPNG::Chunk::Header} class. These specialized
|
|
10
10
|
# classes help accessing the content of the chunk. All other chunks are
|
|
11
11
|
# represented by the {ChunkyPNG::Chunk::Generic} class.
|
|
12
|
+
#
|
|
13
|
+
# @see ChunkyPNG::Datastream
|
|
12
14
|
module Chunk
|
|
13
15
|
|
|
14
16
|
# Reads a chunk from an IO stream.
|
|
@@ -37,37 +39,79 @@ module ChunkyPNG
|
|
|
37
39
|
raise "Chuck CRC mismatch!" if found_crc != expected_crc
|
|
38
40
|
end
|
|
39
41
|
|
|
42
|
+
# The base chunk class is the superclass for every chunk type. It contains
|
|
43
|
+
# methods to write the chunk to an output stream.
|
|
44
|
+
#
|
|
45
|
+
# A subclass should implement the +content+ method, which gets called when
|
|
46
|
+
# the chunk gets written to a PNG datastream
|
|
47
|
+
#
|
|
48
|
+
# @abstract
|
|
40
49
|
class Base
|
|
50
|
+
|
|
51
|
+
# The four-character type indicator for the chunk. This field is used to
|
|
52
|
+
# find the correct class for a chunk when it is loaded from a PNG stream.
|
|
53
|
+
# @return [String]
|
|
41
54
|
attr_accessor :type
|
|
42
55
|
|
|
56
|
+
# Initializes the chunk instance.
|
|
57
|
+
# @param [String] type The four character chunk type indicator.
|
|
58
|
+
# @param [Hash] attributes A hash of attributes to set on this chunk.
|
|
43
59
|
def initialize(type, attributes = {})
|
|
44
60
|
self.type = type
|
|
45
61
|
attributes.each { |k, v| send("#{k}=", v) }
|
|
46
62
|
end
|
|
47
63
|
|
|
64
|
+
# Writes the chunk to the IO stream, using the provided content.
|
|
65
|
+
# The checksum will be calculated and appended to the stream.
|
|
66
|
+
# @param [IO] io The IO stream to write to.
|
|
67
|
+
# @param [String] content The content for this chunk.
|
|
48
68
|
def write_with_crc(io, content)
|
|
49
69
|
io << [content.length].pack('N') << type << content
|
|
50
70
|
io << [Zlib.crc32(content, Zlib.crc32(type))].pack('N')
|
|
51
71
|
end
|
|
52
72
|
|
|
73
|
+
# Writes the chunk to the IO stream.
|
|
74
|
+
#
|
|
75
|
+
# It will call te +content+ method to get the content for this chunk,
|
|
76
|
+
# and will calculate and append the checksum automatically.
|
|
77
|
+
# @param [IO] io The IO stream to write to.
|
|
53
78
|
def write(io)
|
|
54
79
|
write_with_crc(io, content || '')
|
|
55
80
|
end
|
|
56
81
|
end
|
|
57
82
|
|
|
83
|
+
# The Generic chunk type will read the content from the chunk as it,
|
|
84
|
+
# and will write it back as it was read.
|
|
58
85
|
class Generic < Base
|
|
59
86
|
|
|
87
|
+
# The attribute to store the content from the chunk, which gets
|
|
88
|
+
# written by the +write+ method.
|
|
60
89
|
attr_accessor :content
|
|
61
90
|
|
|
91
|
+
|
|
62
92
|
def initialize(type, content = '')
|
|
63
93
|
super(type, :content => content)
|
|
64
94
|
end
|
|
65
95
|
|
|
96
|
+
# Creates an instance, given the chunk's type and content.
|
|
97
|
+
# @param [String] type The four character chunk type indicator.
|
|
98
|
+
# @param [String] content The content read from the chunk.
|
|
99
|
+
# @return [ChunkyPNG::Chunk::Generic] The new chunk instance.
|
|
66
100
|
def self.read(type, content)
|
|
67
101
|
self.new(type, content)
|
|
68
102
|
end
|
|
69
103
|
end
|
|
70
104
|
|
|
105
|
+
# The header (IHDR) chunk is the first chunk of every PNG image, and
|
|
106
|
+
# contains information about the image: i.e. its width, height, color
|
|
107
|
+
# depth, color mode, compression method, filtering method and interlace
|
|
108
|
+
# method.
|
|
109
|
+
#
|
|
110
|
+
# ChunkyPNG supports all values for these variables that are defined in
|
|
111
|
+
# the PNG spec, except for color depth: Only 8-bit depth images are
|
|
112
|
+
# supported. Note that it is still possible to access the chunk for such
|
|
113
|
+
# an image, but ChunkyPNG will raise an exception if you try to access
|
|
114
|
+
# the pixel data.
|
|
71
115
|
class Header < Base
|
|
72
116
|
|
|
73
117
|
attr_accessor :width, :height, :depth, :color, :compression, :filtering, :interlace
|
|
@@ -81,35 +125,63 @@ module ChunkyPNG
|
|
|
81
125
|
@interlace ||= ChunkyPNG::INTERLACING_NONE
|
|
82
126
|
end
|
|
83
127
|
|
|
128
|
+
# Reads the 13 bytes of content from the header chunk to set the image attributes.
|
|
129
|
+
# @param [String] type The four character chunk type indicator (= "IHDR").
|
|
130
|
+
# @param [String] content The 13 bytes of content read from the chunk.
|
|
131
|
+
# @return [ChunkyPNG::Chunk::End] The new Header chunk instance with the
|
|
132
|
+
# variables set to the values according to the content.
|
|
84
133
|
def self.read(type, content)
|
|
85
134
|
fields = content.unpack('NNC5')
|
|
86
135
|
self.new(:width => fields[0], :height => fields[1], :depth => fields[2], :color => fields[3],
|
|
87
136
|
:compression => fields[4], :filtering => fields[5], :interlace => fields[6])
|
|
88
137
|
end
|
|
89
138
|
|
|
139
|
+
# Returns the content for this chunk when it gets written to a file, by packing the
|
|
140
|
+
# image information variables into the correct format.
|
|
141
|
+
# @return [String] The 13-byte content for the header chunk.
|
|
90
142
|
def content
|
|
91
143
|
[width, height, depth, color, compression, filtering, interlace].pack('NNC5')
|
|
92
144
|
end
|
|
93
145
|
end
|
|
94
146
|
|
|
147
|
+
# The End (IEND) chunk indicates the last chunk of a PNG stream. It does not
|
|
148
|
+
# contain any data.
|
|
95
149
|
class End < Base
|
|
150
|
+
|
|
96
151
|
def initialize
|
|
97
152
|
super('IEND')
|
|
98
153
|
end
|
|
99
|
-
|
|
154
|
+
|
|
155
|
+
# Reads the END chunk. It will check if the content is empty.
|
|
156
|
+
# @param [String] type The four character chunk type indicator (= "IEND").
|
|
157
|
+
# @param [String] content The content read from the chunk. Should be empty.
|
|
158
|
+
# @return [ChunkyPNG::Chunk::End] The new End chunk instance.
|
|
159
|
+
# @raise [RuntimeError] Raises an exception if the content was not empty.
|
|
100
160
|
def self.read(type, content)
|
|
101
161
|
raise 'The IEND chunk should be empty!' if content != ''
|
|
102
162
|
self.new
|
|
103
163
|
end
|
|
104
164
|
|
|
165
|
+
# Returns an empty string, because this chunk should always be empty.
|
|
166
|
+
# @return [""] An empty string.
|
|
105
167
|
def content
|
|
106
168
|
''
|
|
107
169
|
end
|
|
108
170
|
end
|
|
109
171
|
|
|
172
|
+
# The Palette (PLTE) chunk contains the image's palette, i.e. the
|
|
173
|
+
# 8-bit RGB colors this image is using.
|
|
174
|
+
#
|
|
175
|
+
# @see ChunkyPNG::Chunk::Transparency
|
|
176
|
+
# @see ChunkyPNG::Palette
|
|
110
177
|
class Palette < Generic
|
|
111
178
|
end
|
|
112
179
|
|
|
180
|
+
# A transparency (tRNS) chunk contains the alpha channel for the colors
|
|
181
|
+
# defined in the Palette (PLTE) chunk
|
|
182
|
+
#
|
|
183
|
+
# @see ChunkyPNG::Chunk::Palette
|
|
184
|
+
# @see ChunkyPNG::Palette
|
|
113
185
|
class Transparency < Generic
|
|
114
186
|
end
|
|
115
187
|
|
|
@@ -126,6 +198,14 @@ module ChunkyPNG
|
|
|
126
198
|
end
|
|
127
199
|
end
|
|
128
200
|
|
|
201
|
+
# The Text (tEXt) chunk contains keyword/value metadata about the PNG stream.
|
|
202
|
+
# In this chunk, the value is stored uncompressed.
|
|
203
|
+
#
|
|
204
|
+
# The tEXt chunk only supports Latin-1 encoded textual data. If you need UTF-8
|
|
205
|
+
# support, check out the InternationalText chunk type.
|
|
206
|
+
#
|
|
207
|
+
# @see ChunkyPNG::Chunk::CompressedText
|
|
208
|
+
# @see ChunkyPNG::Chunk::InternationalText
|
|
129
209
|
class Text < Base
|
|
130
210
|
|
|
131
211
|
attr_accessor :keyword, :value
|
|
@@ -140,17 +220,27 @@ module ChunkyPNG
|
|
|
140
220
|
new(keyword, value)
|
|
141
221
|
end
|
|
142
222
|
|
|
223
|
+
# Creates the content to write to the stream, by concatenating the keyword
|
|
224
|
+
# with the value, joined by a null character.
|
|
225
|
+
#
|
|
226
|
+
# @return The content that should be written to the datastream.
|
|
143
227
|
def content
|
|
144
228
|
[keyword, value].pack('Z*a*')
|
|
145
229
|
end
|
|
146
230
|
end
|
|
147
231
|
|
|
232
|
+
# The CompressedText (zTXt) chunk contains keyword/value metadata about
|
|
233
|
+
# the PNG stream. In this chunk, the value is compressed using Deflate
|
|
234
|
+
# compression.
|
|
235
|
+
#
|
|
236
|
+
# @see ChunkyPNG::Chunk::CompressedText
|
|
237
|
+
# @see ChunkyPNG::Chunk::InternationalText
|
|
148
238
|
class CompressedText < Base
|
|
149
239
|
|
|
150
240
|
attr_accessor :keyword, :value
|
|
151
241
|
|
|
152
242
|
def initialize(keyword, value)
|
|
153
|
-
super('
|
|
243
|
+
super('zTXt')
|
|
154
244
|
@keyword, @value = keyword, value
|
|
155
245
|
end
|
|
156
246
|
|
|
@@ -160,17 +250,37 @@ module ChunkyPNG
|
|
|
160
250
|
new(keyword, Zlib::Inflate.inflate(value))
|
|
161
251
|
end
|
|
162
252
|
|
|
253
|
+
# Creates the content to write to the stream, by concatenating the keyword
|
|
254
|
+
# with the deflated value, joined by a null character.
|
|
255
|
+
#
|
|
256
|
+
# @return The content that should be written to the datastream.
|
|
163
257
|
def content
|
|
164
258
|
[keyword, ChunkyPNG::COMPRESSION_DEFAULT, Zlib::Deflate.deflate(value)].pack('Z*Ca*')
|
|
165
259
|
end
|
|
166
260
|
end
|
|
167
261
|
|
|
262
|
+
# The Text (iTXt) chunk contains keyword/value metadata about the PNG stream.
|
|
263
|
+
# The metadata in this chunk can be encoded using UTF-8 characters. Moreover,
|
|
264
|
+
# it is possible to define the language of the metadata, and give a translation
|
|
265
|
+
# of the keyword name. Finally, it supports bot compressed and uncompressed
|
|
266
|
+
# values.
|
|
267
|
+
#
|
|
268
|
+
# @todo This chunk is currently not implemented, but merely read and written
|
|
269
|
+
# back intact.
|
|
270
|
+
#
|
|
271
|
+
# @see ChunkyPNG::Chunk::Text
|
|
272
|
+
# @see ChunkyPNG::Chunk::CompressedText
|
|
168
273
|
class InternationalText < Generic
|
|
274
|
+
|
|
169
275
|
# TODO
|
|
170
276
|
end
|
|
171
277
|
|
|
172
|
-
# Maps chunk types to classes
|
|
173
|
-
#
|
|
278
|
+
# Maps chunk types to classes, based on the four byte chunk type indicator at the
|
|
279
|
+
# beginning of a chunk.
|
|
280
|
+
#
|
|
281
|
+
# If a chunk type is not specified in this hash, the Generic chunk type will be used.
|
|
282
|
+
#
|
|
283
|
+
# @see ChunkyPNG::Chunk.read
|
|
174
284
|
CHUNK_TYPES = {
|
|
175
285
|
'IHDR' => Header, 'IEND' => End, 'IDAT' => ImageData, 'PLTE' => Palette, 'tRNS' => Transparency,
|
|
176
286
|
'tEXt' => Text, 'zTXt' => CompressedText, 'iTXt' => InternationalText
|
data/lib/chunky_png/color.rb
CHANGED
|
@@ -46,7 +46,7 @@ module ChunkyPNG
|
|
|
46
46
|
def grayscale_alpha(teint, a)
|
|
47
47
|
teint << 24 | teint << 16 | teint << 8 | a
|
|
48
48
|
end
|
|
49
|
-
|
|
49
|
+
|
|
50
50
|
####################################################################
|
|
51
51
|
# COLOR IMPORTING
|
|
52
52
|
####################################################################
|
|
@@ -222,6 +222,15 @@ module ChunkyPNG
|
|
|
222
222
|
(fg + bg) >> 1
|
|
223
223
|
end
|
|
224
224
|
|
|
225
|
+
# Lowers the intensity of a color, by lowering its alpha by a given factor.
|
|
226
|
+
# @param [Fixnum] color The color to adjust.
|
|
227
|
+
# @param [Fixnum] factor Fade factor as an integer between 0 and 255.
|
|
228
|
+
# @return [Fixnum] The faded color.
|
|
229
|
+
def fade(color, factor)
|
|
230
|
+
new_alpha = int8_mult(a(color), factor)
|
|
231
|
+
(color & 0xffffff00) | new_alpha
|
|
232
|
+
end
|
|
233
|
+
|
|
225
234
|
####################################################################
|
|
226
235
|
# CONVERSIONS
|
|
227
236
|
####################################################################
|
|
@@ -44,9 +44,9 @@ module ChunkyPNG
|
|
|
44
44
|
@data_chunks = []
|
|
45
45
|
end
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
##############################################################################
|
|
48
48
|
# LOADING DATASTREAMS
|
|
49
|
-
|
|
49
|
+
##############################################################################
|
|
50
50
|
|
|
51
51
|
class << self
|
|
52
52
|
|
|
@@ -102,16 +102,17 @@ module ChunkyPNG
|
|
|
102
102
|
end
|
|
103
103
|
end
|
|
104
104
|
|
|
105
|
-
|
|
105
|
+
##################################################################################
|
|
106
106
|
# CHUNKS
|
|
107
|
-
|
|
107
|
+
##################################################################################
|
|
108
108
|
|
|
109
109
|
# Enumerates the chunks in this datastream.
|
|
110
110
|
#
|
|
111
111
|
# This will iterate over the chunks using the order in which the chunks
|
|
112
112
|
# should appear in the PNG file.
|
|
113
113
|
#
|
|
114
|
-
# @yield [
|
|
114
|
+
# @yield [chunk] Yields the chunks in this datastrean, one by one in the correct order.
|
|
115
|
+
# @yieldparam [ChunkyPNG::Chunk::Base] chunk A chunk in this datastream.
|
|
115
116
|
# @see ChunkyPNG::Datastream#chunks
|
|
116
117
|
def each_chunk
|
|
117
118
|
yield(header_chunk)
|
|
@@ -138,9 +139,9 @@ module ChunkyPNG
|
|
|
138
139
|
metadata
|
|
139
140
|
end
|
|
140
141
|
|
|
141
|
-
|
|
142
|
+
##################################################################################
|
|
142
143
|
# WRITING DATASTREAMS
|
|
143
|
-
|
|
144
|
+
##################################################################################
|
|
144
145
|
|
|
145
146
|
# Writes the datastream to the given output stream.
|
|
146
147
|
# @param [IO] io The output stream to write to.
|
data/lib/chunky_png/rmagick.rb
CHANGED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe ChunkyPNG::Canvas::Drawing do
|
|
4
|
+
|
|
5
|
+
describe '#point' do
|
|
6
|
+
it "should compose colors correctly" do
|
|
7
|
+
canvas = ChunkyPNG::Canvas.new(1, 1, ChunkyPNG::Color.rgb(200, 150, 100))
|
|
8
|
+
canvas.point(0,0, ChunkyPNG::Color.rgba(100, 150, 200, 128))
|
|
9
|
+
canvas[0,0].should == ChunkyPNG::Color.rgb(150, 150, 150)
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
describe '#line' do
|
|
14
|
+
it "should draw lines correctly with anti-aliasing" do
|
|
15
|
+
canvas = ChunkyPNG::Canvas.new(32, 32, ChunkyPNG::Color::WHITE)
|
|
16
|
+
|
|
17
|
+
canvas.line( 0, 0, 31, 31, ChunkyPNG::Color::BLACK)
|
|
18
|
+
canvas.line( 0, 31, 31, 0, ChunkyPNG::Color::BLACK)
|
|
19
|
+
canvas.line(15, 31, 15, 0, ChunkyPNG::Color.rgba(200, 0, 0, 128))
|
|
20
|
+
canvas.line( 0, 15, 31, 15, ChunkyPNG::Color.rgba(200, 0, 0, 128))
|
|
21
|
+
canvas.line( 0, 15, 31, 31, ChunkyPNG::Color.rgba( 0, 200, 0, 128))
|
|
22
|
+
canvas.line( 0, 15, 31, 0, ChunkyPNG::Color.rgba( 0, 200, 0, 128))
|
|
23
|
+
canvas.line(15, 0, 31, 31, ChunkyPNG::Color.rgba( 0, 0, 200, 128))
|
|
24
|
+
canvas.line(15, 0, 0, 31, ChunkyPNG::Color.rgba( 0, 0, 200, 128))
|
|
25
|
+
|
|
26
|
+
canvas.should == reference_canvas('lines')
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
Binary file
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: chunky_png
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.5.
|
|
4
|
+
version: 0.5.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Willem van Bergen
|
|
@@ -9,7 +9,7 @@ autorequire:
|
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
11
|
|
|
12
|
-
date: 2010-01-
|
|
12
|
+
date: 2010-01-18 00:00:00 +01:00
|
|
13
13
|
default_executable:
|
|
14
14
|
dependencies:
|
|
15
15
|
- !ruby/object:Gem::Dependency
|
|
@@ -69,11 +69,13 @@ files:
|
|
|
69
69
|
- spec/resources/gray_10x10_indexed.png
|
|
70
70
|
- spec/resources/16x16_non_interlaced.png
|
|
71
71
|
- spec/chunky_png_spec.rb
|
|
72
|
+
- spec/chunky_png/canvas/drawing_spec.rb
|
|
72
73
|
- lib/chunky_png/palette.rb
|
|
73
74
|
- lib/chunky_png/datastream.rb
|
|
74
75
|
- chunky_png.gemspec
|
|
75
76
|
- tasks/github-gem.rake
|
|
76
77
|
- spec/resources/pixelstream_reference.png
|
|
78
|
+
- spec/resources/lines.png
|
|
77
79
|
- spec/resources/gray_10x10_grayscale_alpha.png
|
|
78
80
|
- spec/resources/16x16_interlaced.png
|
|
79
81
|
- spec/chunky_png/image_spec.rb
|
|
@@ -125,6 +127,7 @@ test_files:
|
|
|
125
127
|
- spec/chunky_png/canvas/adam7_interlacing_spec.rb
|
|
126
128
|
- spec/chunky_png/canvas/png_decoding_spec.rb
|
|
127
129
|
- spec/chunky_png_spec.rb
|
|
130
|
+
- spec/chunky_png/canvas/drawing_spec.rb
|
|
128
131
|
- spec/chunky_png/image_spec.rb
|
|
129
132
|
- spec/chunky_png/rmagick_spec.rb
|
|
130
133
|
- spec/chunky_png/datastream_spec.rb
|