Class: ChunkyPNG::Canvas

Inherits:
Object
  • Object
show all
Extended by:
Adam7Interlacing, PNGDecoding
Includes:
Drawing, Operations, PNGEncoding
Defined in:
lib/chunky_png/canvas.rb,
lib/chunky_png/canvas/drawing.rb,
lib/chunky_png/canvas/operations.rb,
lib/chunky_png/canvas/png_decoding.rb,
lib/chunky_png/canvas/png_encoding.rb,
lib/chunky_png/canvas/adam7_interlacing.rb

Overview

The ChunkPNG::Canvas class represents a raster image as a matrix of pixels.

This class supports loading a Canvas from a PNG datastream, and creating a PNG datastream based on this matrix. ChunkyPNG only supports 8-bit color depth, otherwise all of the PNG format’s variations are supported for both reading and writing.

This class offers per-pixel access to the matrix by using x,y coordinates. It uses a palette (see Palette) to keep track of the different colors used in this matrix.

The pixels in the canvas are stored as 4-byte fixnum, representing 32-bit RGBA colors (8 bit per channel). The module Color is provided to work more easily with these number as color values.

The module Operations is imported for operations on the whole canvas, like cropping and alpha compositing. Simple drawing functions are imported from the Drawing module.

Direct Known Subclasses

Image

Defined Under Namespace

Modules: Adam7Interlacing, Drawing, Operations, PNGDecoding, PNGEncoding

Constant Summary

Constants included from PNGEncoding

PNGEncoding::GRAYSCALE_ALPHA_ENCODER, PNGEncoding::GRAYSCALE_ENCODER, PNGEncoding::TRUECOLOR_ALPHA_ENCODER, PNGEncoding::TRUECOLOR_ENCODER

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from PNGDecoding

decode_png_pixelstream, from_blob, from_datastream, from_file, from_io

Methods included from Adam7Interlacing

adam7_extract_pass, adam7_merge_pass, adam7_multiplier_offset, adam7_pass_size, adam7_pass_sizes

Methods included from Operations

#compose, #crop, #replace

Methods included from PNGEncoding

#save, #to_blob, #to_datastream, #write

Constructor Details

#initialize(width, height, initial = ChunkyPNG::Color::TRANSPARENT) ⇒ Canvas

Initializes a new Canvas instance

Parameters:

  • width (Integer)

    The width in pixels of this canvas

  • width (Integer)

    The height in pixels of this canvas

  • initial (ChunkyPNG::Pixel, Array<ChunkyPNG::Color>) (defaults to: ChunkyPNG::Color::TRANSPARENT)

    The initial value of te pixels:

    • If a color is passed to this parameter, this color will be used as background color.

    • If an array of pixels is provided, these pixels will be used as initial value. Note that the amount of pixels in this array should equal width * height.



50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/chunky_png/canvas.rb', line 50

def initialize(width, height, initial = ChunkyPNG::Color::TRANSPARENT)

  @width, @height = width, height

  if initial.kind_of?(Fixnum)
    @pixels = Array.new(width * height, initial)
  elsif initial.kind_of?(Array) && initial.size == width * height
    @pixels = initial
  else
    raise "Cannot use this value as initial canvas: #{initial.inspect}!"
  end
end

Instance Attribute Details

#heightInteger (readonly)

Returns The number of rows in this canvas.

Returns:

  • (Integer)

    The number of rows in this canvas



35
36
37
# File 'lib/chunky_png/canvas.rb', line 35

def height
  @height
end

#pixelsArray<ChunkyPNG::Color> (readonly)

Returns The list of pixels in this canvas. This array always should have width * height elements.

Returns:

  • (Array<ChunkyPNG::Color>)

    The list of pixels in this canvas. This array always should have width * height elements.



39
40
41
# File 'lib/chunky_png/canvas.rb', line 39

def pixels
  @pixels
end

#widthInteger (readonly)

Returns The number of columns in this canvas.

Returns:

  • (Integer)

    The number of columns in this canvas



32
33
34
# File 'lib/chunky_png/canvas.rb', line 32

def width
  @width
end

Class Method Details

.from_canvas(canvas) ⇒ ChunkyPNG::Canvas

Creates a new canvas instance by duplicating another instance.

Parameters:

Returns:



120
121
122
# File 'lib/chunky_png/canvas.rb', line 120

def self.from_canvas(canvas)
  self.new(canvas.width, canvas.height, canvas.pixels.dup)
end

.from_rgb_stream(width, height, stream) ⇒ ChunkyPNG::Canvas

Creates a canvas by reading pixels from an RGB formatted stream with a provided with and height.

Every pixel should be represented by 3 bytes in the stream, in the correct RGB order. This format closely resembles the internal representation of a canvas object, so this kind of stream can be read extremely quickly.

Parameters:

  • width (Integer)

    The width of the new canvas.

  • height (Integer)

    The height of the new canvas.

  • stream (#read, String)

    The stream to read the pixel data from.

Returns:



135
136
137
138
139
140
141
# File 'lib/chunky_png/canvas.rb', line 135

def self.from_rgb_stream(width, height, stream)
  string = stream.respond_to?(:read) ? stream.read(3 * width * height) : stream.to_s[0, 3 * width * height]
  string << "\255" # Add a fourth byte to the last RGB triple.
  unpacker = 'NX' * (width * height)
  pixels = string.unpack(unpacker).map { |color| color | 0x000000ff }
  self.new(width, height, pixels)
end

.from_rgba_stream(width, height, stream) ⇒ ChunkyPNG::Canvas

Creates a canvas by reading pixels from an RGBA formatted stream with a provided with and height.

Every pixel should be represented by 4 bytes in the stream, in the correct RGBA order. This format is exactly like the internal representation of a canvas object, so this kind of stream can be read extremely quickly.

Parameters:

  • width (Integer)

    The width of the new canvas.

  • height (Integer)

    The height of the new canvas.

  • stream (#read, String)

    The stream to read the pixel data from.

Returns:



154
155
156
157
# File 'lib/chunky_png/canvas.rb', line 154

def self.from_rgba_stream(width, height, stream)
  string = stream.respond_to?(:read) ? stream.read(4 * width * height) : stream.to_s[0, 4 * width * height]
  self.new(width, height, string.unpack("N*"))
end

Instance Method Details

#[](x, y) ⇒ ChunkyPNG::Color

Returns a single pixel from this canvas.

Parameters:

  • x (Integer)

    The x-coordinate of the pixel (column)

  • y (Integer)

    The y-coordinate of the pixel (row)

Returns:



86
87
88
# File 'lib/chunky_png/canvas.rb', line 86

def [](x, y)
  @pixels[y * width + x]
end

#[]=(x, y, color) ⇒ Object

Replaces a single pixel in this canvas.

Parameters:

  • x (Integer)

    The x-coordinate of the pixel (column)

  • y (Integer)

    The y-coordinate of the pixel (row)

  • pixel (ChunkyPNG::Color)

    The new pixel for the provided coordinates.



78
79
80
# File 'lib/chunky_png/canvas.rb', line 78

def []=(x, y, color)
  @pixels[y * width + x] = color
end

#eql?(other) ⇒ true, false Also known as: ==

Equality check to compare this canvas with other matrices.

Parameters:

  • other

    The object to compare this Matrix to.

Returns:

  • (true, false)

    True if the size and pixel values of the other canvas are exactly the same as this canvas’s size and pixel values.



101
102
103
104
# File 'lib/chunky_png/canvas.rb', line 101

def eql?(other)
  other.kind_of?(self.class) && other.pixels == self.pixels &&
        other.width == self.width && other.height == self.height
end

#initialize_copy(other) ⇒ Object



63
64
65
66
# File 'lib/chunky_png/canvas.rb', line 63

def initialize_copy(other)
  @width, @height = other.width, other.height
  @pixels = other.pixels.dup
end

#paletteChunkyPNG::Palette

Returns the palette used for this canvas.

Returns:

  • (ChunkyPNG::Palette)

    A pallete which contains all the colors that are being used for this image.



93
94
95
# File 'lib/chunky_png/canvas.rb', line 93

def palette
  ChunkyPNG::Palette.from_canvas(self)
end

#sizeObject

Returns the size ([width, height]) for this canvas.

Returns:

  • Array An array with the width and height of this canvas as elements.



70
71
72
# File 'lib/chunky_png/canvas.rb', line 70

def size
  [@width, @height]
end

#to_imageObject

Creates an ChunkyPNG::Image object from this canvas



109
110
111
# File 'lib/chunky_png/canvas.rb', line 109

def to_image
  ChunkyPNG::Image.from_canvas(self)
end

#to_rgb_streamString

Creates an RGB-formatted pixelstream with the pixel data from this canvas.

Note that this format is fast but bloated, because no compression is used and the internal representation is almost left intact. However, to reconstruct the canvas, the width and height should be known.

Returns:

  • (String)

    The RGB-formatted pixel data.



181
182
183
184
# File 'lib/chunky_png/canvas.rb', line 181

def to_rgb_stream
  packer = 'NX' * (width * height)
  pixels.pack(packer)
end

#to_rgba_streamString

Creates an RGB-formatted pixelstream with the pixel data from this canvas.

Note that this format is fast but bloated, because no compression is used and the internal representation is left intact. However, to reconstruct the canvas, the width and height should be known.

Returns:

  • (String)

    The RGBA-formatted pixel data.



170
171
172
# File 'lib/chunky_png/canvas.rb', line 170

def to_rgba_stream
  pixels.pack('N*')
end