Class: ChunkyPNG::Canvas

Inherits:
Object
  • Object
show all
Extended by:
Adam7Interlacing, PNGDecoding, StreamImporting
Includes:
Drawing, Masking, Operations, PNGEncoding, Resampling, StreamExporting
Defined in:
lib/chunky_png/canvas.rb,
lib/chunky_png/canvas/drawing.rb,
lib/chunky_png/canvas/masking.rb,
lib/chunky_png/canvas/operations.rb,
lib/chunky_png/canvas/resampling.rb,
lib/chunky_png/canvas/png_decoding.rb,
lib/chunky_png/canvas/png_encoding.rb,
lib/chunky_png/canvas/stream_exporting.rb,
lib/chunky_png/canvas/stream_importing.rb,
lib/chunky_png/canvas/adam7_interlacing.rb

Overview

The ChunkyPNG::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, Masking, Operations, PNGDecoding, PNGEncoding, Resampling, StreamExporting, StreamImporting

Instance Attribute Summary collapse

Attributes included from PNGDecoding

#decoding_palette

Attributes included from PNGEncoding

#encoding_palette

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 StreamImporting

from_abgr_stream, from_bgr_stream, from_rgb_stream, from_rgba_stream

Methods included from Masking

#change_mask_color!, #change_theme_color!, #extract_mask

Methods included from Resampling

#resample_nearest_neighbor, #resample_nearest_neighbor!

Methods included from Drawing

#bezier_curve, #circle, #compose_pixel, #compose_pixel_unsafe, #line_xiaolin_wu, #polygon, #rect

Methods included from Operations

#compose, #compose!, #crop, #crop!, #flip_horizontally, #flip_horizontally!, #flip_vertically, #flip_vertically!, #replace, #replace!, #rotate_180, #rotate_180!, #rotate_left, #rotate_left!, #rotate_right, #rotate_right!

Methods included from StreamExporting

#to_abgr_stream, #to_rgb_stream, #to_rgba_stream

Methods included from PNGEncoding

#save, #to_blob, #to_datastream, #write

Constructor Details

#initialize(width, height, background_color) ⇒ Canvas #initialize(width, height, initial) ⇒ Canvas

Initializes a new Canvas instance.

Overloads:

  • #initialize(width, height, background_color) ⇒ Canvas

    Parameters:

    • width (Integer)

      The width in pixels of this canvas

    • height (Integer)

      The height in pixels of this canvas

    • background_color (Integer, ...)

      The initial background color of this canvas. This can be a color value or any value that ChunkyPNG::Color.parse can handle.

  • #initialize(width, height, initial) ⇒ Canvas

    Parameters:

    • width (Integer)

      The width in pixels of this canvas

    • height (Integer)

      The height in pixels of this canvas

    • initial (Array<Integer>)

      The initial pizel values. Must be an array with width * height elements.



74
75
76
77
78
79
80
81
82
83
84
# File 'lib/chunky_png/canvas.rb', line 74

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

  @width, @height = width, height

  if initial.kind_of?(Array)
    raise ArgumentError, "The initial array should have #{width}x#{height} = #{width*height} elements!" unless initial.length == width * height
    @pixels = initial
  else
    @pixels = Array.new(width * height, ChunkyPNG::Color.parse(initial))
  end
end

Instance Attribute Details

#heightInteger (readonly)

Returns The number of rows in this canvas.

Returns:

  • (Integer)

    The number of rows in this canvas



50
51
52
# File 'lib/chunky_png/canvas.rb', line 50

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.



54
55
56
# File 'lib/chunky_png/canvas.rb', line 54

def pixels
  @pixels
end

#widthInteger (readonly)

Returns The number of columns in this canvas.

Returns:

  • (Integer)

    The number of columns in this canvas



47
48
49
# File 'lib/chunky_png/canvas.rb', line 47

def width
  @width
end

Class Method Details

.from_canvas(canvas) ⇒ ChunkyPNG::Canvas

Creates a new canvas instance by duplicating another instance.

Parameters:

Returns:



98
99
100
# File 'lib/chunky_png/canvas.rb', line 98

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

Instance Method Details

#[](x, y) ⇒ Integer

Returns a single pixel’s color value from this canvas.

Parameters:

  • x (Integer)

    The x-coordinate of the pixel (column)

  • y (Integer)

    The y-coordinate of the pixel (row)

Returns:

  • (Integer)

    The current color value at the provided coordinates.

Raises:

See Also:



163
164
165
166
# File 'lib/chunky_png/canvas.rb', line 163

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

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

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)

  • color (Integer)

    The new color for the provided coordinates.

Returns:

  • (Integer)

    The new color value for this pixel, i.e. color.

Raises:

See Also:



126
127
128
129
# File 'lib/chunky_png/canvas.rb', line 126

def []=(x, y, color)
  assert_xy!(x, y)
  @pixels[y * width + x] = ChunkyPNG::Color.parse(color)
end

#areaInteger

Returns the area of this canvas in number of pixels.

Returns:

  • (Integer)

    The number of pixels in this canvas



115
116
117
# File 'lib/chunky_png/canvas.rb', line 115

def area
  pixels.length
end

#column(x) ⇒ Array<Integer>

Returns an extracted column as vector of pixels.

Parameters:

  • x (Integer)

    The 0-based column index.

Returns:

  • (Array<Integer>)

    The vector of pixels in the requested column.



187
188
189
190
# File 'lib/chunky_png/canvas.rb', line 187

def column(x)
  assert_x!(x)
  (0...height).inject([]) { |pixels, y| pixels << get_pixel(x, y) }
end

#dimensionChunkyPNG::Dimension

Returns the dimension (width x height) for this canvas.

Returns:



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

def dimension
  ChunkyPNG::Dimension.new(width, height)
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.



256
257
258
259
# File 'lib/chunky_png/canvas.rb', line 256

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

#get_pixel(x, y) ⇒ Integer

Returns a single pixel from this canvas, without checking bounds. The return value for this method is undefined if the coordinates are out of bounds.

Parameters:

  • x (Integer)

    The x-coordinate of the pixel (column)

  • y (Integer)

    The y-coordinate of the pixel (row)

Returns:

  • (Integer)

    The current pixel at the provided coordinates.



172
173
174
# File 'lib/chunky_png/canvas.rb', line 172

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

#include_point?(*point_like) ⇒ true, false Also known as: include?

Checks whether the given coordinates are in the range of the canvas

Parameters:

Returns:

  • (true, false)

    True if the x and y coordinates of the point are

    within the limits of this canvas.

See Also:



217
218
219
# File 'lib/chunky_png/canvas.rb', line 217

def include_point?(*point_like)
  dimension.include?(ChunkyPNG::Point(*point_like))
end

#include_x?(x) ⇒ true, false

Checks whether the given x-coordinate is in the range of the canvas

Parameters:

  • x (Integer)

    The y-coordinate of the pixel (column)

Returns:

  • (true, false)

    True if the x-coordinate is in the range of this canvas.



241
242
243
# File 'lib/chunky_png/canvas.rb', line 241

def include_x?(x)
  x >= 0 && x < width
end

#include_xy?(x, y) ⇒ true, false

Checks whether the given x- and y-coordinate are in the range of the canvas

Parameters:

  • x (Integer)

    The x-coordinate of the pixel (column)

  • y (Integer)

    The y-coordinate of the pixel (row)

Returns:

  • (true, false)

    True if the x- and y-coordinate is in the range of this canvas.



227
228
229
# File 'lib/chunky_png/canvas.rb', line 227

def include_xy?(x, y)
  y >= 0 && y < height && x >= 0 && x < width
end

#include_y?(y) ⇒ true, false

Checks whether the given y-coordinate is in the range of the canvas

Parameters:

  • y (Integer)

    The y-coordinate of the pixel (row)

Returns:

  • (true, false)

    True if the y-coordinate is in the range of this canvas.



234
235
236
# File 'lib/chunky_png/canvas.rb', line 234

def include_y?(y)
  y >= 0 && y < height
end

#paletteChunkyPNG::Palette

Returns the palette used for this canvas.

Returns:

  • (ChunkyPNG::Palette)

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



248
249
250
# File 'lib/chunky_png/canvas.rb', line 248

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

#replace_column!(x, vector)

This method returns an undefined value.

Replaces a column of pixels on this canvas.

Parameters:

  • x (Integer)

    The 0-based column index.

  • vector (Array<Integer>)

    The vector of pixels to replace the column with.



205
206
207
208
209
210
# File 'lib/chunky_png/canvas.rb', line 205

def replace_column!(x, vector)
  assert_x!(x) && assert_height!(vector.length)
  for y in 0...height do
    set_pixel(x, y, vector[y])
  end
end

#replace_row!(y, vector)

This method returns an undefined value.

Replaces a row of pixels on this canvas.

Parameters:

  • y (Integer)

    The 0-based row index.

  • vector (Array<Integer>)

    The vector of pixels to replace the row with.



196
197
198
199
# File 'lib/chunky_png/canvas.rb', line 196

def replace_row!(y, vector)
  assert_y!(y) && assert_width!(vector.length)
  pixels[y * width, width] = vector
end

#row(y) ⇒ Array<Integer>

Returns an extracted row as vector of pixels

Parameters:

  • y (Integer)

    The 0-based row index

Returns:

  • (Array<Integer>)

    The vector of pixels in the requested row



179
180
181
182
# File 'lib/chunky_png/canvas.rb', line 179

def row(y)
  assert_y!(y)
  pixels.slice(y * width, width)
end

#set_pixel(x, y, color) ⇒ Integer

Replaces a single pixel in this canvas, without bounds checking.

This method return value and effects are undefined for coordinates out of bounds of the canvas.

Parameters:

  • x (Integer)

    The x-coordinate of the pixel (column)

  • y (Integer)

    The y-coordinate of the pixel (row)

  • pixel (Integer)

    The new color for the provided coordinates.

Returns:

  • (Integer)

    The new color value for this pixel, i.e. color.



140
141
142
# File 'lib/chunky_png/canvas.rb', line 140

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

#set_pixel_if_within_bounds(x, y, color) ⇒ Integer

Replaces a single pixel in this canvas, with bounds checking. It will do noting if the provided coordinates are out of bounds.

Parameters:

  • x (Integer)

    The x-coordinate of the pixel (column)

  • y (Integer)

    The y-coordinate of the pixel (row)

  • pixel (Integer)

    The new color value for the provided coordinates.

Returns:

  • (Integer)

    The new color value for this pixel, i.e. color, or nil if the coordinates are out of bounds.



152
153
154
155
# File 'lib/chunky_png/canvas.rb', line 152

def set_pixel_if_within_bounds(x, y, color)
  return unless include_xy?(x, y)
  @pixels[y * width + x] = color
end

#to_imageChunkyPNG::Image

Creates an ChunkyPNG::Image object from this canvas.

Returns:



269
270
271
# File 'lib/chunky_png/canvas.rb', line 269

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