Module: ChunkyPNG::Canvas::Operations
- Included in:
- ChunkyPNG::Canvas
- Defined in:
- lib/chunky_png/canvas/operations.rb
Overview
The ChunkyPNG::Canvas::Operations module defines methods to perform operations on a ChunkyPNG::Canvas. The module is included into the Canvas class so all these methods are available on every canvas.
Note that some of these operations modify the canvas, while some operations return a new canvas and leave the original intact.
Instance Method Summary collapse
-
#change_mask_color!(new_color) ⇒ Object
Changes the color of a mask image.
-
#change_theme_color!(old_theme_color, new_theme_color, bg_color = ChunkyPNG::Color::WHITE, tolerance = 5) ⇒ ChunkyPNG::Canvas
Creates a new image, based on the current image but with a new theme color.
-
#compose(other, offset_x = 0, offset_y = 0) ⇒ ChunkyPNG::Canvas
Composes another image onto this image using alpha blending.
-
#crop(x, y, crop_width, crop_height) ⇒ ChunkyPNG::Canvas
Crops an image, given the coordinates and size of the image that needs to be cut out.
-
#extract_mask(mask_color, bg_color = ChunkyPNG::Color::WHITE, tolerance = 5) ⇒ Array<ChunkyPNG::Canvas, ChunkyPNG::Canvas>
Creates a base image and a mask image from an original image that has a particular theme color.
-
#flip_horizontally ⇒ ChunkyPNG::Canvas
Flips the image horizontally.
-
#flip_vertically ⇒ ChunkyPNG::Canvas
Flips the image horizontally.
-
#replace(other, offset_x = 0, offset_y = 0) ⇒ ChunkyPNG::Canvas
Replaces pixels on this image by pixels from another pixels, on a given offset.
-
#rotate_180 ⇒ ChunkyPNG::Canvas
Rotates the image 180 degrees.
-
#rotate_left ⇒ ChunkyPNG::Canvas
Rotates the image 90 degrees counter-clockwise.
-
#rotate_right ⇒ ChunkyPNG::Canvas
Rotates the image 90 degrees clockwise.
Instance Method Details
#change_mask_color!(new_color) ⇒ Object
Changes the color of a mask image.
This method works on acanavs extracte out of another image using the #extract_mask method. It can then be applied on the extracted base image. See #change_theme_color! to perform these operations in one go.
152 153 154 155 156 |
# File 'lib/chunky_png/canvas/operations.rb', line 152 def change_mask_color!(new_color) raise ChunkyPNG::ExpectationFailed, "This is not a mask image!" if palette.opaque_palette.size != 1 pixels.map! { |pixel| (new_color & 0xffffff00) | ChunkyPNG::Color.a(pixel) } self end |
#change_theme_color!(old_theme_color, new_theme_color, bg_color = ChunkyPNG::Color::WHITE, tolerance = 5) ⇒ ChunkyPNG::Canvas
Creates a new image, based on the current image but with a new theme color.
This method will replace one color in an image with another image. This is done by first extracting the pixels with a color close to the original theme color as a mask image, changing the color of this mask image and then apply it on the original image.
Mask extraction works best when the theme colored pixels are clearly distinguishable from a background color (preferably white). You can set a tolerance level to influence the extraction process.
98 99 100 101 102 |
# File 'lib/chunky_png/canvas/operations.rb', line 98 def change_theme_color!(old_theme_color, new_theme_color, bg_color = ChunkyPNG::Color::WHITE, tolerance = 5) base, mask = extract_mask(old_theme_color, bg_color, tolerance) mask.change_mask_color!(new_theme_color) self.replace(base.compose(mask)) end |
#compose(other, offset_x = 0, offset_y = 0) ⇒ ChunkyPNG::Canvas
Composes another image onto this image using alpha blending.
If you simply want to replace pixels or when the other image does not have transparency, it is faster to use #replace.
27 28 29 30 31 32 33 34 35 36 |
# File 'lib/chunky_png/canvas/operations.rb', line 27 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 |
#crop(x, y, crop_width, crop_height) ⇒ ChunkyPNG::Canvas
Crops an image, given the coordinates and size of the image that needs to be cut out. This will leave the original image intact and return a new, cropped image with pixels copied from the original image.
67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/chunky_png/canvas/operations.rb', line 67 def crop(x, y, crop_width, crop_height) raise ChunkyPNG::OutOfBounds, "Image width is too small!" if crop_width + x > width raise ChunkyPNG::OutOfBounds, "Image width is too small!" if crop_height + y > height new_pixels = [] for cy in 0...crop_height do new_pixels += pixels.slice((cy + y) * width + x, crop_width) end ChunkyPNG::Canvas.new(crop_width, crop_height, new_pixels) end |
#extract_mask(mask_color, bg_color = ChunkyPNG::Color::WHITE, tolerance = 5) ⇒ Array<ChunkyPNG::Canvas, ChunkyPNG::Canvas>
Creates a base image and a mask image from an original image that has a particular theme color. This can be used to easily change a theme color in an image.
It will extract all the pixels that look like the theme color (with a tolerance level) and put these in a mask image. All the other pixels will be stored in a base image. Both images will be of the exact same size as the original image. The original image will be left untouched.
The color of the mask image can be changed with #change_mask_color!. This new mask image can then be composed upon the base image to create an image with a new theme color. A call to #change_theme_color! will perform this in one go.
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/chunky_png/canvas/operations.rb', line 124 def extract_mask(mask_color, bg_color = ChunkyPNG::Color::WHITE, tolerance = 5) base_pixels = [] mask_pixels = [] pixels.each do |pixel| if ChunkyPNG::Color.alpha_decomposable?(pixel, mask_color, bg_color, tolerance) mask_pixels << ChunkyPNG::Color.decompose_color(pixel, mask_color, bg_color, tolerance) base_pixels << bg_color else mask_pixels << (mask_color & 0xffffff00) base_pixels << pixel end end [ self.class.new(width, height, base_pixels), self.class.new(width, height, mask_pixels) ] end |
#flip_horizontally ⇒ ChunkyPNG::Canvas
Flips the image horizontally.
This will flip the image on its horizontal axis, e.g. pixels on the top will now be pixels on the bottom. Chaining this method twice will return the original canvas. This method will leave the original object intact and return a new canvas.
165 166 167 168 169 170 171 |
# File 'lib/chunky_png/canvas/operations.rb', line 165 def flip_horizontally self.class.new(width, height).tap do |flipped| for y in 0...height do flipped.replace_row!(height - (y + 1), row(y)) end end end |
#flip_vertically ⇒ ChunkyPNG::Canvas
Flips the image horizontally.
This will flip the image on its vertical axis, e.g. pixels on the left will now be pixels on the right. Chaining this method twice will return the original canvas. This method will leave the original object intact and return a new canvas.
180 181 182 183 184 185 186 |
# File 'lib/chunky_png/canvas/operations.rb', line 180 def flip_vertically self.class.new(width, height).tap do |flipped| for x in 0...width do flipped.replace_column!(width - (x + 1), column(x)) end end end |
#replace(other, offset_x = 0, offset_y = 0) ⇒ ChunkyPNG::Canvas
Replaces pixels on this image by pixels from another pixels, on a given offset.
This will completely replace the pixels of the background image. If you want to blend them with semi-transparent pixels from the foreground image, see #compose.
47 48 49 50 51 52 53 54 |
# File 'lib/chunky_png/canvas/operations.rb', line 47 def replace(other, offset_x = 0, offset_y = 0) check_size_constraints!(other, offset_x, offset_y) for y in 0...other.height do pixels[(y + offset_y) * width + offset_x, other.width] = other.pixels[y * other.width, other.width] end self end |
#rotate_180 ⇒ ChunkyPNG::Canvas
Rotates the image 180 degrees. This method will leave the original object intact and return a new canvas.
216 217 218 219 220 221 222 |
# File 'lib/chunky_png/canvas/operations.rb', line 216 def rotate_180 self.class.new(width, height).tap do |flipped| for y in 0...height do flipped.replace_row!(height - (y + 1), row(y).reverse) end end end |
#rotate_left ⇒ ChunkyPNG::Canvas
Rotates the image 90 degrees counter-clockwise. This method will leave the original object intact and return a new canvas.
204 205 206 207 208 209 210 |
# File 'lib/chunky_png/canvas/operations.rb', line 204 def rotate_left self.class.new(height, width).tap do |rotated| for i in 0...width do rotated.replace_row!(width - (i + 1), column(i)) end end end |
#rotate_right ⇒ ChunkyPNG::Canvas
Rotates the image 90 degrees clockwise. This method will leave the original object intact and return a new canvas.
192 193 194 195 196 197 198 |
# File 'lib/chunky_png/canvas/operations.rb', line 192 def rotate_right self.class.new(height, width).tap do |rotated| for i in 0...width do rotated.replace_row!(i, column(i).reverse) end end end |