Class ChunkyPNG::Canvas
In: lib/chunky_png/canvas.rb
lib/chunky_png/canvas/png_encoding.rb
lib/chunky_png/canvas/operations.rb
lib/chunky_png/canvas/drawing.rb
lib/chunky_png/canvas/masking.rb
lib/chunky_png/canvas/resampling.rb
lib/chunky_png/canvas/data_url_importing.rb
lib/chunky_png/canvas/png_decoding.rb
lib/chunky_png/canvas/data_url_exporting.rb
lib/chunky_png/canvas/stream_importing.rb
lib/chunky_png/canvas/adam7_interlacing.rb
lib/chunky_png/canvas/stream_exporting.rb
Parent: Object

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 {ChunkyPNG::Datastream 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 {ChunkyPNG::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 {ChunkyPNG::Color} is provided to work more easily with these number as color values.

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

Methods

Included Modules

PNGEncoding StreamExporting DataUrlExporting Operations Drawing Resampling Masking

Classes and Modules

Module ChunkyPNG::Canvas::Adam7Interlacing
Module ChunkyPNG::Canvas::DataUrlExporting
Module ChunkyPNG::Canvas::DataUrlImporting
Module ChunkyPNG::Canvas::Drawing
Module ChunkyPNG::Canvas::Masking
Module ChunkyPNG::Canvas::Operations
Module ChunkyPNG::Canvas::PNGDecoding
Module ChunkyPNG::Canvas::PNGEncoding
Module ChunkyPNG::Canvas::Resampling
Module ChunkyPNG::Canvas::StreamExporting
Module ChunkyPNG::Canvas::StreamImporting

Attributes

height  [R]  @return [Integer] The number of rows in this canvas
pixels  [R]  @return [Array<ChunkyPNG::Color>] The list of pixels in this canvas.
    This array always should have +width * height+ elements.
width  [R]  @return [Integer] The number of columns in this canvas

Public Class methods

Creates a new canvas instance by duplicating another instance. @param [ChunkyPNG::Canvas] canvas The canvas to duplicate @return [ChunkyPNG::Canvas] The newly constructed canvas instance.

[Source]

     # File lib/chunky_png/canvas.rb, line 103
103:     def self.from_canvas(canvas)
104:       self.new(canvas.width, canvas.height, canvas.pixels.dup)
105:     end

Initializes a new Canvas instance.

@overload initialize(width, height, background_color)

  @param [Integer] width The width in pixels of this canvas
  @param [Integer] height The height in pixels of this canvas
  @param [Integer, ...] background_color The initial background color of this canvas.
     This can be a color value or any value that {ChunkyPNG::Color.parse} can handle.

@overload initialize(width, height, initial)

  @param [Integer] width The width in pixels of this canvas
  @param [Integer] height The height in pixels of this canvas
  @param [Array<Integer>] initial The initial pizel values. Must be an array with
    <tt>width * height</tt> elements.

[Source]

    # File lib/chunky_png/canvas.rb, line 79
79:     def initialize(width, height, initial = ChunkyPNG::Color::TRANSPARENT)
80: 
81:       @width, @height = width, height
82: 
83:       if initial.kind_of?(Array)
84:         raise ArgumentError, "The initial array should have #{width}x#{height} = #{width*height} elements!" unless initial.length == width * height
85:         @pixels = initial
86:       else
87:         @pixels = Array.new(width * height, ChunkyPNG::Color.parse(initial))
88:       end
89:     end

Public Instance methods

==(other)

Alias for eql?

Returns a single pixel‘s color value from this canvas. @param [Integer] x The x-coordinate of the pixel (column) @param [Integer] y The y-coordinate of the pixel (row) @return [Integer] The current color value at the provided coordinates. @raise [ChunkyPNG::OutOfBounds] when the coordinates are outside of the image‘s dimensions. @see get_pixel

[Source]

     # File lib/chunky_png/canvas.rb, line 168
168:     def [](x, y)
169:       assert_xy!(x, y)
170:       @pixels[y * width + x]
171:     end

Replaces a single pixel in this canvas. @param [Integer] x The x-coordinate of the pixel (column) @param [Integer] y The y-coordinate of the pixel (row) @param [Integer] color The new color for the provided coordinates. @return [Integer] The new color value for this pixel, i.e. color. @raise [ChunkyPNG::OutOfBounds] when the coordinates are outside of the image‘s dimensions. @see set_pixel

[Source]

     # File lib/chunky_png/canvas.rb, line 131
131:     def []=(x, y, color)
132:       assert_xy!(x, y)
133:       @pixels[y * width + x] = ChunkyPNG::Color.parse(color)
134:     end

Returns the area of this canvas in number of pixels. @return [Integer] The number of pixels in this canvas

[Source]

     # File lib/chunky_png/canvas.rb, line 120
120:     def area
121:       pixels.length
122:     end

Returns an extracted column as vector of pixels. @param [Integer] x The 0-based column index. @return [Array<Integer>] The vector of pixels in the requested column.

[Source]

     # File lib/chunky_png/canvas.rb, line 192
192:     def column(x)
193:       assert_x!(x)
194:       (0...height).inject([]) { |pixels, y| pixels << get_pixel(x, y) }
195:     end

Returns the dimension (width x height) for this canvas. @return [ChunkyPNG::Dimension] A dimension instance with the width and height set for this canvas.

[Source]

     # File lib/chunky_png/canvas.rb, line 114
114:     def dimension
115:       ChunkyPNG::Dimension.new(width, height)
116:     end

Equality check to compare this canvas with other matrices. @param other The object to compare this Matrix to. @return [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.

[Source]

     # File lib/chunky_png/canvas.rb, line 261
261:     def eql?(other)
262:       other.kind_of?(self.class) && other.pixels == self.pixels &&
263:             other.width == self.width && other.height == self.height
264:     end

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. @param (see #[]) @return [Integer] The current pixel at the provided coordinates.

[Source]

     # File lib/chunky_png/canvas.rb, line 177
177:     def get_pixel(x, y)
178:       @pixels[y * width + x]
179:     end
include?(*point_like)

Alias for include_point?

Checks whether the given coordinates are in the range of the canvas @param [ChunkyPNG::Point, Array, Hash, String] point_like The point to check. @return [true, false] True if the x and y coordinates of the point are

   within the limits of this canvas.

@see ChunkyPNG.Point

[Source]

     # File lib/chunky_png/canvas.rb, line 222
222:     def include_point?(*point_like)
223:       dimension.include?(ChunkyPNG::Point(*point_like))
224:     end

Checks whether the given x-coordinate is in the range of the canvas @param [Integer] x The y-coordinate of the pixel (column) @return [true, false] True if the x-coordinate is in the range of this canvas.

[Source]

     # File lib/chunky_png/canvas.rb, line 246
246:     def include_x?(x)
247:       x >= 0 && x < width
248:     end

Checks whether the given x- and y-coordinate are in the range of the canvas @param [Integer] x The x-coordinate of the pixel (column) @param [Integer] y The y-coordinate of the pixel (row) @return [true, false] True if the x- and y-coordinate is in the range of this canvas.

[Source]

     # File lib/chunky_png/canvas.rb, line 232
232:     def include_xy?(x, y)
233:       y >= 0 && y < height && x >= 0 && x < width
234:     end

Checks whether the given y-coordinate is in the range of the canvas @param [Integer] y The y-coordinate of the pixel (row) @return [true, false] True if the y-coordinate is in the range of this canvas.

[Source]

     # File lib/chunky_png/canvas.rb, line 239
239:     def include_y?(y)
240:       y >= 0 && y < height
241:     end

Initializes a new Canvas instances when being cloned. @param [ChunkyPNG::Canvas] other The canvas to duplicate @return [void] @private

[Source]

    # File lib/chunky_png/canvas.rb, line 95
95:     def initialize_copy(other)
96:       @width, @height = other.width, other.height
97:       @pixels = other.pixels.dup
98:     end

Alternative implementation of the inspect method. @return [String] A nicely formatted string representation of this canvas. @private

[Source]

     # File lib/chunky_png/canvas.rb, line 281
281:     def inspect
282:       inspected = "<#{self.class.name} #{width}x#{height} ["
283:       for y in 0...height
284:         inspected << "\n\t[" << row(y).map { |p| ChunkyPNG::Color.to_hex(p) }.join(' ') << ']'
285:       end
286:       inspected << "\n]>"
287:     end

Returns the palette used for this canvas. @return [ChunkyPNG::Palette] A palette which contains all the colors that are

   being used for this image.

[Source]

     # File lib/chunky_png/canvas.rb, line 253
253:     def palette
254:       ChunkyPNG::Palette.from_canvas(self)
255:     end

Replaces a column of pixels on this canvas. @param [Integer] x The 0-based column index. @param [Array<Integer>] vector The vector of pixels to replace the column with. @return [void]

[Source]

     # File lib/chunky_png/canvas.rb, line 210
210:     def replace_column!(x, vector)
211:       assert_x!(x) && assert_height!(vector.length)
212:       for y in 0...height do
213:         set_pixel(x, y, vector[y])
214:       end
215:     end

Replaces a row of pixels on this canvas. @param [Integer] y The 0-based row index. @param [Array<Integer>] vector The vector of pixels to replace the row with. @return [void]

[Source]

     # File lib/chunky_png/canvas.rb, line 201
201:     def replace_row!(y, vector)
202:       assert_y!(y) && assert_width!(vector.length)
203:       pixels[y * width, width] = vector
204:     end

Returns an extracted row as vector of pixels @param [Integer] y The 0-based row index @return [Array<Integer>] The vector of pixels in the requested row

[Source]

     # File lib/chunky_png/canvas.rb, line 184
184:     def row(y)
185:       assert_y!(y)
186:       pixels.slice(y * width, width)
187:     end

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.

@param [Integer] x The x-coordinate of the pixel (column) @param [Integer] y The y-coordinate of the pixel (row) @param [Integer] pixel The new color for the provided coordinates. @return [Integer] The new color value for this pixel, i.e. color.

[Source]

     # File lib/chunky_png/canvas.rb, line 145
145:     def set_pixel(x, y, color)
146:       @pixels[y * width + x] = color
147:     end

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

@param [Integer] x The x-coordinate of the pixel (column) @param [Integer] y The y-coordinate of the pixel (row) @param [Integer] pixel The new color value for the provided coordinates. @return [Integer] The new color value for this pixel, i.e. color, or

   <tt>nil</tt> if the coordinates are out of bounds.

[Source]

     # File lib/chunky_png/canvas.rb, line 157
157:     def set_pixel_if_within_bounds(x, y, color)
158:       return unless include_xy?(x, y)
159:       @pixels[y * width + x] = color
160:     end

Creates an ChunkyPNG::Image object from this canvas. @return [ChunkyPNG::Image] This canvas wrapped in an Image instance.

[Source]

     # File lib/chunky_png/canvas.rb, line 274
274:     def to_image
275:       ChunkyPNG::Image.from_canvas(self)
276:     end

Protected Instance methods

Throws an exception if the vector_length does not match this canvas’ height.

[Source]

     # File lib/chunky_png/canvas.rb, line 317
317:     def assert_height!(vector_length)
318:       raise ChunkyPNG::ExpectationFailed, "The length of the vector (#{vector_length}) does not match the canvas height (#{height})!" if height != vector_length
319:       return true
320:     end

Throws an exception if the matrix width and height does not match this canvas’ dimensions.

[Source]

     # File lib/chunky_png/canvas.rb, line 329
329:     def assert_size!(matrix_width, matrix_height)
330:       raise ChunkyPNG::ExpectationFailed, "The width of the matrix does not match the canvas width!"   if width  != matrix_width
331:       raise ChunkyPNG::ExpectationFailed, "The height of the matrix does not match the canvas height!" if height != matrix_height
332:       return true
333:     end

Throws an exception if the vector_length does not match this canvas’ width.

[Source]

     # File lib/chunky_png/canvas.rb, line 323
323:     def assert_width!(vector_length)
324:       raise ChunkyPNG::ExpectationFailed, "The length of the vector (#{vector_length}) does not match the canvas width (#{width})!" if width != vector_length
325:       return true
326:     end

Throws an exception if the x-coordinate is out of bounds.

[Source]

     # File lib/chunky_png/canvas.rb, line 299
299:     def assert_x!(x)
300:       raise ChunkyPNG::OutOfBounds, "Column index #{x} out of bounds!" unless include_x?(x)
301:       return true
302:     end

Throws an exception if the x- or y-coordinate is out of bounds.

[Source]

     # File lib/chunky_png/canvas.rb, line 311
311:     def assert_xy!(x, y)
312:       raise ChunkyPNG::OutOfBounds, "Coordinates (#{x},#{y}) out of bounds!" unless include_xy?(x, y)
313:       return true
314:     end

Throws an exception if the y-coordinate is out of bounds.

[Source]

     # File lib/chunky_png/canvas.rb, line 305
305:     def assert_y!(y)
306:       raise ChunkyPNG::OutOfBounds, "Row index #{y} out of bounds!" unless include_y?(y)
307:       return true
308:     end

Replaces the image, given a new width, new height, and a new pixel array.

[Source]

     # File lib/chunky_png/canvas.rb, line 292
292:     def replace_canvas!(new_width, new_height, new_pixels)
293:       raise ArgumentError, "The provided pixel array should have #{new_width * new_height} items" unless new_pixels.length == new_width * new_height
294:       @width, @height, @pixels = new_width, new_height, new_pixels
295:       return self
296:     end

[Validate]