class ImageVise::EllipseStencil
Applies an elliptic stencil around the entire image. The stencil will fit inside the image boundaries, with about 1 pixel cushion on each side to provide smooth anti-aliased edges. If the input image to be provessed is square, the ellipse will turn into a neat circle.
This adds an alpha channel to the image being processed (and premultiplies the RGB channels by it). This will force the RenderEngine to return the processed image as a PNG in all cases, instead of keeping it in the original format.
The corresponding Pipeline method is `ellipse_stencil`.
Constants
- C_black
- C_white
Public Instance Methods
apply!(magick_image)
click to toggle source
# File lib/image_vise/operators/ellipse_stencil.rb, line 15 def apply!(magick_image) width, height = magick_image.columns, magick_image.rows # This is a bit involved. We need to do a manual composite. Here is what it entails. # # Given a premultiplied RGB image B, and a grayscale mask A, we need to do the following # operation: # # BrBgBb / Ba * (Ba * A) # # Since ImageMagick works with unpremultiplied alphas, it is doable - but special care # must be taken not to overmult or overdivide. # # To begin,generate a black and white image for the stencil mask = Magick::Image.new(width, height) draw_circle(mask, width, height) # At this stage the mask contains a B/W image of the circle, black outside, white inside. # Retain the alpha of the original in a separate image only_alpha = magick_image.copy only_alpha.alpha(Magick::ExtractAlphaChannel) mask.composite!(only_alpha, Magick::CenterGravity, Magick::MultiplyCompositeOp) # With this composite op, enabling alpha on the destination image is # not required - it will be enabled automatically. # The CopyOpacityCompositeOp implies that we copy the grayscale version # of the RGB channels as the alpha channel, so for some weird reason we need # to disable the alpha on our mask image mask.alpha(Magick::DeactivateAlphaChannel) # And perform the operation (set gray(RGB) of mask as the A of magick_image) magick_image.composite!(mask, Magick::CenterGravity, Magick::CopyOpacityCompositeOp) ensure [mask, only_alpha].each do |maybe_image| ImageVise.destroy(maybe_image) end end
draw_circle(into_image, width, height)
click to toggle source
# File lib/image_vise/operators/ellipse_stencil.rb, line 52 def draw_circle(into_image, width, height) center_x = (width / 2.0) center_y = (height / 2.0) # Make sure all the edges are anti-aliased radius_width = center_x - 1.5 radius_height = center_y - 1.5 gc = Magick::Draw.new gc.fill C_black gc.rectangle(0, 0, width, height) gc.fill C_white gc.ellipse(center_x, center_y, radius_width, radius_height, deg_start=0, deg_end=360) gc.draw(into_image) ensure ImageVise.destroy(gc) end