Module: Compass::Magick::Functions::Operations
- Included in:
- Compass::Magick::Functions
- Defined in:
- lib/magick/functions/operations.rb
Overview
Methods for operating on a Canvas, e.g., crop, compose, etc.
Instance Method Summary collapse
-
#magick_compose(overlay, x = nil, y = nil) ⇒ Command
Composes one Canvas on top of another.
-
#magick_crop(x1 = nil, y1 = nil, x2 = nil, y2 = nil) ⇒ Command
Crops the Canvas to the given region.
-
#magick_drop_shadow(angle = nil, distance = nil, size = nil, color = nil) ⇒ Command
Apply drop shadow on the Canvas.
-
#magick_effect(name, *args) ⇒ Effect
Apply an effect on the Canvas.
-
#magick_mask(mask, x = nil, y = nil) ⇒ Command
Applies the mask on the Canvas.
Instance Method Details
#magick_compose(overlay, x = nil, y = nil) ⇒ Command
Composes one Canvas on top of another.
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/magick/functions/operations.rb', line 15 def magick_compose(, x = nil, y = nil) Compass::Magick::Utils.assert_type 'overlay', , ChunkyPNG::Canvas Compass::Magick::Utils.assert_type 'x', x, Sass::Script::Number Compass::Magick::Utils.assert_type 'y', y, Sass::Script::Number Command.new do |canvas| canvas_x = Compass::Magick::Utils.value_of(x, canvas.width - .width, 0).to_i canvas_y = Compass::Magick::Utils.value_of(y, canvas.height - .height, 0).to_i raise ChunkyPNG::OutOfBounds, 'Canvas image width is too small to compose overlay' if canvas.width < .width + canvas_x raise ChunkyPNG::OutOfBounds, 'Canvas image height is too small to compose overlay' if canvas.height < .height + canvas_y for y in 0....height do for x in 0....width do = .get_pixel(x, y) canvas_pixel = canvas.get_pixel(x + canvas_x, y + canvas_y) canvas.set_pixel(x + canvas_x, y + canvas_y, ChunkyPNG::Color.compose_precise(, canvas_pixel)) end end end end |
#magick_crop(x1 = nil, y1 = nil, x2 = nil, y2 = nil) ⇒ Command
Crops the Canvas to the given region.
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/magick/functions/operations.rb', line 41 def magick_crop(x1 = nil, y1 = nil, x2 = nil, y2 = nil) Compass::Magick::Utils.assert_type 'x1', x1, Sass::Script::Number Compass::Magick::Utils.assert_type 'y1', y1, Sass::Script::Number Compass::Magick::Utils.assert_type 'x2', x2, Sass::Script::Number Compass::Magick::Utils.assert_type 'y2', y2, Sass::Script::Number Command.new do |canvas| canvas_x1 = Compass::Magick::Utils.value_of(x1, canvas.width, 0) canvas_y1 = Compass::Magick::Utils.value_of(y1, canvas.height, 0) canvas_x2 = Compass::Magick::Utils.value_of(x2, canvas.width, canvas.width) canvas_y2 = Compass::Magick::Utils.value_of(y2, canvas.height, canvas.height) canvas_x1, canvas_x2 = canvas_x2, canvas_x1 if canvas_x1 > canvas_x2 canvas_y1, canvas_y2 = canvas_y2, canvas_y1 if canvas_y1 > canvas_y2 width = canvas_x2 - canvas_x1 height = canvas_y2 - canvas_y1 canvas.crop(canvas_x1, canvas_y1, width, height) end end |
#magick_drop_shadow(angle = nil, distance = nil, size = nil, color = nil) ⇒ Command
Apply drop shadow on the Canvas.
The alpha channel is used to construct a mask of the original image which is then used as a base for the horizontal/vertical shadow pass.
Copyright © 2005 by Romain Guy www.curious-creature.org/2005/07/06/non-rectangular-shadow/
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
# File 'lib/magick/functions/operations.rb', line 120 def magick_drop_shadow(angle = nil, distance = nil, size = nil, color = nil) Compass::Magick::Utils.assert_type 'angle', angle, Sass::Script::Number Compass::Magick::Utils.assert_type 'distance', distance, Sass::Script::Number Compass::Magick::Utils.assert_type 'size', size, Sass::Script::Number Compass::Magick::Utils.assert_type 'color', color, Sass::Script::Color Command.new do |canvas| shadow_angle = Compass::Magick::Utils.value_of(angle, 360, 0) shadow_distance = Compass::Magick::Utils.value_of(distance, [canvas.width, canvas.height].min, 5) shadow_size = Compass::Magick::Utils.value_of(size, [canvas.width, canvas.height].min, 5) shadow_color = Compass::Magick::Utils.to_chunky_color(color.nil? ? Sass::Script::Color.new([0, 0, 0, 1]) : color) shadow_canvas = ChunkyPNG::Canvas.new(canvas.width + shadow_size * 2, canvas.height + shadow_size * 2).replace(canvas, shadow_size, shadow_size) shadow_pixels = shadow_canvas.pixels shadow_red = ChunkyPNG::Color.r(shadow_color) shadow_green = ChunkyPNG::Color.g(shadow_color) shadow_blue = ChunkyPNG::Color.b(shadow_color) shadow_alpha = ChunkyPNG::Color.a(shadow_color) angle_radians = shadow_angle * Math::PI / 180 distance_x = (Math.cos(angle_radians) * shadow_distance).to_i distance_y = (Math.sin(angle_radians) * shadow_distance).to_i left = (shadow_size - 1) >> 1 right = shadow_size - left x_start = left x_finish = shadow_canvas.width - right y_start = left y_finish = shadow_canvas.height - right a_history = Array.new(shadow_size) history_index = 0 sum_divider = (shadow_alpha / 255.0) / shadow_size buffer_offset = 0 last_pixel_offset = right * shadow_canvas.width for y in (0...shadow_canvas.height) a_sum = 0 history_index = 0 for x in (0...shadow_size) a = ChunkyPNG::Color.a(shadow_pixels[buffer_offset]) a_history[x] = a a_sum = a_sum + a buffer_offset = buffer_offset + 1 end buffer_offset = buffer_offset - right for x in (x_start...x_finish) a = a_sum * sum_divider shadow_pixels[buffer_offset] = ChunkyPNG::Color.rgba(shadow_red, shadow_green, shadow_blue, (shadow_alpha * (a / 255.0)).to_i) a_sum = a_sum - a_history[history_index] a = ChunkyPNG::Color.a(shadow_pixels[buffer_offset + right]) a_history[history_index] = a a_sum = a_sum + a history_index = history_index + 1 history_index = history_index - shadow_size if history_index >= shadow_size buffer_offset = buffer_offset + 1 end buffer_offset = y * shadow_canvas.width end buffer_offset = 0 for x in (0...shadow_canvas.width) a_sum = 0 history_index = 0 for y in (0...shadow_size) a = ChunkyPNG::Color.a(shadow_pixels[buffer_offset]) a_history[y] = a a_sum = a_sum + a buffer_offset = buffer_offset + shadow_canvas.width end buffer_offset = buffer_offset - last_pixel_offset for y in (y_start...y_finish) a = a_sum * sum_divider shadow_pixels[buffer_offset] = ChunkyPNG::Color.rgba(shadow_red, shadow_green, shadow_blue, (shadow_alpha * (a / 255.0)).to_i) a_sum = a_sum - a_history[history_index] a = ChunkyPNG::Color.a(shadow_pixels[buffer_offset + last_pixel_offset]) a_history[history_index] = a a_sum = a_sum + a history_index = history_index + 1 history_index = history_index - shadow_size if history_index >= shadow_size buffer_offset = buffer_offset + shadow_canvas.width end buffer_offset = x end for y in 0...canvas.height do for x in 0...canvas.width do shadow_x = x + shadow_size + distance_x shadow_y = y + shadow_size + distance_y canvas.set_pixel(x, y, ChunkyPNG::Color.compose_precise( canvas.get_pixel(x, y), shadow_pixels[shadow_y * shadow_canvas.width + shadow_x] )) end end end end |
#magick_effect(name, *args) ⇒ Effect
Apply an effect on the Canvas.
100 101 102 103 |
# File 'lib/magick/functions/operations.rb', line 100 def magick_effect(name, *args) Compass::Magick::Utils.assert_type 'name', name, Sass::Script::String Compass::Magick::Functions::Operations::Effects.send(name.value, *args) end |
#magick_mask(mask, x = nil, y = nil) ⇒ Command
Applies the mask on the Canvas.
Composes the alpha channel from the mask
image with the one from the canvas and return the original canvas with the alpha-channel modified. Any opaque pixels from the mask
are converted to grayscale using BT709 luminosity factors, i.e. black is fully transparent and white is fully opaque.
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/magick/functions/operations.rb', line 70 def magick_mask(mask, x = nil, y = nil) Compass::Magick::Utils.assert_type 'mask', mask, ChunkyPNG::Canvas Compass::Magick::Utils.assert_type 'x', x, Sass::Script::Number Compass::Magick::Utils.assert_type 'y', y, Sass::Script::Number Command.new do |canvas| canvas_x = Compass::Magick::Utils.value_of(x, canvas.width - 1, 0) canvas_y = Compass::Magick::Utils.value_of(y, canvas.height - 1, 0) raise ChunkyPNG::OutOfBounds, 'Canvas image width is too small to fit mask' if canvas.width < mask.width + canvas_x raise ChunkyPNG::OutOfBounds, 'Canvas image height is too small to fit mask' if canvas.height < mask.height + canvas_y for y in 0...mask.height do for x in 0...mask.width do canvas_pixel = canvas.get_pixel(x + canvas_x, y + canvas_y) mask_pixel = mask.get_pixel(x, y) mask_alpha = (ChunkyPNG::Color.r(mask_pixel) * 0.2125 + ChunkyPNG::Color.g(mask_pixel) * 0.7154 + ChunkyPNG::Color.b(mask_pixel) * 0.0721) * (ChunkyPNG::Color.a(mask_pixel) / 255.0) canvas.set_pixel(x + canvas_x, y + canvas_y, ChunkyPNG::Color.rgba( ChunkyPNG::Color.r(canvas_pixel), ChunkyPNG::Color.g(canvas_pixel), ChunkyPNG::Color.b(canvas_pixel), (ChunkyPNG::Color.a(canvas_pixel) * (mask_alpha / 255.0)).to_i )) end end end end |