module ChunkyPNG::Canvas::Operations

def border(size, color = ChunkyPNG::Color::BLACK)

Other tags:
    See: #border! -

Returns:
  • (ChunkyPNG::Canvas) - Returns a bordered version of the image.

Parameters:
  • color (Integer) -- The color of the border.
  • size (Integer) -- The size of the border.
def border(size, color = ChunkyPNG::Color::BLACK)
  dup.border!(size, color)
end

def border!(size, color = ChunkyPNG::Color::BLACK)

Other tags:
    See: #border -

Returns:
  • (ChunkyPNG::Canvas) - Returns itself with the border added.

Parameters:
  • color (Integer) -- The color of the border.
  • size (Integer) -- The size of the border.
def border!(size, color = ChunkyPNG::Color::BLACK)
  new_width  = width  + size * 2
  new_height = height + size * 2
  bg = Canvas.new(new_width, new_height, color).replace(self, size, size)
  replace_canvas!(new_width, new_height, bg.pixels)
end

def check_size_constraints!(other, offset_x, offset_y)

Raises:
  • (ChunkyPNG::OutOfBounds) - when the other image doesn't fit.

Parameters:
  • offset_y (Integer) -- The y offset on which the other image will be
  • offset_x (Integer) -- The x offset on which the other image will be
  • other (ChunkyPNG::Canvas) -- The other canvas
def check_size_constraints!(other, offset_x, offset_y)
  if width  < other.width  + offset_x
    raise ChunkyPNG::OutOfBounds, 'Background image width is too small!'
  end
  if height < other.height + offset_y
    raise ChunkyPNG::OutOfBounds, 'Background image height is too small!'
  end
end

def compose(other, offset_x = 0, offset_y = 0)

Other tags:
    See: #replace -

Other tags:
    Note: - API changed since 1.0 - This method now no longer is in place,

Raises:
  • (ChunkyPNG::OutOfBounds) - when the other canvas doesn't fit on

Returns:
  • (ChunkyPNG::Canvas) - Returns the new canvas, composed of the

Parameters:
  • () --
def compose(other, offset_x = 0, offset_y = 0)
  dup.compose!(other, offset_x, offset_y)
end

def compose!(other, offset_x = 0, offset_y = 0)

Other tags:
    See: #compose -
    See: #replace! -

Raises:
  • (ChunkyPNG::OutOfBounds) - when the other canvas doesn't fit on

Returns:
  • (ChunkyPNG::Canvas) - Returns itself, but with the other canvas

Parameters:
  • offset_y (Integer) -- The y-offset to apply the new foreground on.
  • offset_x (Integer) -- The x-offset to apply the new foreground on.
  • other (ChunkyPNG::Canvas) -- The foreground canvas to compose on
def compose!(other, offset_x = 0, offset_y = 0)
  check_size_constraints!(other, offset_x, offset_y)
  for y in 0...other.height do
    for x in 0...other.width do
      set_pixel(x + offset_x,
                y + offset_y,
                ChunkyPNG::Color.compose(other.get_pixel(x, y),
                                         get_pixel(x + offset_x,
                                                   y + offset_y)))
    end
  end
  self
end

def crop(x, y, crop_width, crop_height)

Raises:
  • (ChunkyPNG::OutOfBounds) - when the crop dimensions plus the given

Returns:
  • (ChunkyPNG::Canvas) - Returns the newly created cropped image.

Parameters:
  • crop_height (Integer) -- The height of the image to be cropped.
  • crop_width (Integer) -- The width of the image to be cropped.
  • y (Integer) -- The y-coordinate of the top left corner of the image
  • x (Integer) -- The x-coordinate of the top left corner of the image
def crop(x, y, crop_width, crop_height)
  dup.crop!(x, y, crop_width, crop_height)
end

def crop!(x, y, crop_width, crop_height)

Raises:
  • (ChunkyPNG::OutOfBounds) - when the crop dimensions plus the given

Returns:
  • (ChunkyPNG::Canvas) - Returns itself, but cropped.

Parameters:
  • crop_height (Integer) -- The height of the image to be cropped.
  • crop_width (Integer) -- The width of the image to be cropped.
  • y (Integer) -- The y-coordinate of the top left corner of the image
  • x (Integer) -- The x-coordinate of the top left corner of the image
def crop!(x, y, crop_width, crop_height)
  if crop_width + x > width
    raise ChunkyPNG::OutOfBounds, 'Original image width is too small!'
  end
  if crop_height + y > height
    raise ChunkyPNG::OutOfBounds, 'Original image height is too small!'
  end
  if crop_width == width && x == 0
    # We only need to crop off the top and/or bottom, so we can take a
    # shortcut.
    replace_canvas!(crop_width, crop_height,
                    pixels.slice(y * width, width * crop_height))
  else
    new_pixels = []
    for cy in 0...crop_height do
      new_pixels.concat pixels.slice((cy + y) * width + x, crop_width)
    end
    replace_canvas!(crop_width, crop_height, new_pixels)
  end
end

def flip_horizontally

Other tags:
    See: #flip_horizontally! -

Returns:
  • (ChunkyPNG::Canvas) - The flipped image
def flip_horizontally
  dup.flip_horizontally!
end

def flip_horizontally!

Other tags:
    See: #flip_horizontally -

Returns:
  • (ChunkyPNG::Canvas) - Itself, but flipped
def flip_horizontally!
  for y in 0..((height - 1) >> 1) do
    other_y   = height - (y + 1)
    other_row = row(other_y)
    replace_row!(other_y, row(y))
    replace_row!(y, other_row)
  end
  self
end

def flip_vertically

Other tags:
    See: #flip_vertically! -

Returns:
  • (ChunkyPNG::Canvas) - The flipped image
def flip_vertically
  dup.flip_vertically!
end

def flip_vertically!

Other tags:
    See: #flip_vertically -

Returns:
  • (ChunkyPNG::Canvas) - Itself, but flipped
def flip_vertically!
  for y in 0...height do
    replace_row!(y, row(y).reverse)
  end
  self
end

def grayscale

Other tags:
    See: {ChunkyPNG::Color#to_grayscale} -
    See: {#grayscale!} -

Returns:
  • (ChunkyPNG::Canvas) - A copy of the canvas, converted to
def grayscale
  dup.grayscale!
end

def grayscale!

Other tags:
    See: {ChunkyPNG::Color#to_grayscale} -
    See: {#grayscale} -

Returns:
  • (ChunkyPNG::Canvas) - Returns itself, converted to grayscale.
def grayscale!
  pixels.map! { |pixel| ChunkyPNG::Color.to_grayscale(pixel) }
  self
end

def replace(other, offset_x = 0, offset_y = 0)

Other tags:
    See: #compose -

Other tags:
    Note: - API changed since 1.0 - This method now no longer is in place,

Raises:
  • (ChunkyPNG::OutOfBounds) - when the other canvas doesn't fit on

Returns:
  • (ChunkyPNG::Canvas) - Returns a new, combined canvas.

Parameters:
  • () --
def replace(other, offset_x = 0, offset_y = 0)
  dup.replace!(other, offset_x, offset_y)
end

def replace!(other, offset_x = 0, offset_y = 0)

Other tags:
    See: #replace -
    See: #compose! -

Raises:
  • (ChunkyPNG::OutOfBounds) - when the other canvas doesn't fit on

Returns:
  • (ChunkyPNG::Canvas) - Returns itself, but with the other canvas

Parameters:
  • offset_y (Integer) -- The y-offset to apply the new foreground on.
  • offset_x (Integer) -- The x-offset to apply the new foreground on.
  • other (ChunkyPNG::Canvas) -- The foreground canvas to get the
def replace!(other, offset_x = 0, offset_y = 0)
  check_size_constraints!(other, offset_x, offset_y)
  for y in 0...other.height do
    for d in 0...other.width
      pixels[(y + offset_y) * width + offset_x + d] = other.pixels[y * other.width + d]
    end
  end
  self
end

def rotate_180

Other tags:
    See: #rotate_180! -

Returns:
  • (ChunkyPNG::Canvas) - The rotated image.
def rotate_180
  dup.rotate_180!
end

def rotate_180!

Other tags:
    See: #rotate_180 -

Returns:
  • (ChunkyPNG::Canvas) - Itself, but rotated 180 degrees.
def rotate_180!
  pixels.reverse!
  self
end

def rotate_left

Other tags:
    See: #rotate_left! - for the in-place version.

Returns:
  • (ChunkyPNG::Canvas) - A rotated copy of itself.
def rotate_left
  dup.rotate_left!
end

def rotate_left!

Returns:
  • (ChunkyPNG::Canvas) - Itself, but rotated.
def rotate_left!
  new_pixels = []
  (width - 1).downto(0) { |i| new_pixels += column(i) }
  replace_canvas!(height, width, new_pixels)
end

def rotate_right

Other tags:
    See: #rotate_right! - for the in place version.

Returns:
  • (ChunkyPNG::Canvas) - A clockwise-rotated copy.
def rotate_right
  dup.rotate_right!
end

def rotate_right!

Other tags:
    See: #rotate_right - for a version that leaves the current canvas intact

Returns:
  • (ChunkyPNG::Canvas) - Itself, but rotated clockwise.
def rotate_right!
  new_pixels = []
  0.upto(width - 1) { |i| new_pixels += column(i).reverse }
  replace_canvas!(height, width, new_pixels)
end

def trim(border = pixels.first)

Other tags:
    See: #trim! -

Returns:
  • (ChunkyPNG::Canvas) - The trimmed image.

Parameters:
  • border (Integer) -- The color to attempt to trim.
def trim(border = pixels.first)
  dup.trim!
end

def trim!(border = pixels.first)

Other tags:
    See: #trim -

Returns:
  • (ChunkyPNG::Canvas) - Returns itself, but with the border

Parameters:
  • border (Integer) -- The color to attempt to trim.
def trim!(border = pixels.first)
  x1 = [*0...width].index   { |c| column(c).uniq != [border] }
  x2 = [*0...width].rindex  { |c| column(c).uniq != [border] }
  y1 = [*0...height].index  { |r|    row(r).uniq != [border] }
  y2 = [*0...height].rindex { |r|    row(r).uniq != [border] }
  crop! x1, y1, x2 - x1 + 1, y2 - y1 + 1
end