RMagick Web 2.0 Graphics
Alpha Compositing - Part 2

Tommy Maloney's Web 2.0 Design Kit is a tutorial about making Web 2.0 design effects using Photoshop. I ran across the tutorial just by luck and immediately recognized it as just the thing I needed for Part 2 of my Alpha Compositing tutorial. (If you haven't read it yet, part 1 is here.)

This tutorial reproduces the effects described in Part 1 of the Web 2.0 Design Kit using RMagick instead of Photoshop. Before beginning, you ought to go over to the Design Kit page (if it's still available) so you can see the image created during the tutorial. The RMagick version of the image is a bit different and looks like the image below.

This tutorial will show you how to create each part of this image using RMagick. In addition to composite, we'll use annotate from the Draw class to draw the text, the GradientFill class to make gradient backgrounds, and blur_image to make shadows. We'll also use the append, rotate, and negate methods.

The glass effect

The first effect is the reflective, or "glass" effect. Before we start, let's get some housekeeping out of the way. Define a couple of constants for the dimensions of the gradients and an ImageList object to hold the images:

require 'RMagick'
include Magick

WIDTH = 650

stripes = ImageList.new

Start by making the blue-gray stripes in the background. This image is made by appending two gray-scale gradient images, one above the other, into a single image. Then you add color to the result using the colorize composite operation.

Make the gradients by creating two instances of the GradientFill class. The GradientFill.new method expects 6 arguments. The first four arguments define a line or a point. The last two arguments are two colors. The gradient is created by starting with the first color at the line or point and gradually changing to the second color as the gradient moves away from the line or point.

Create a gradient that starts with color #dddddd at a line across the top of the image and ranges to #888888 at the bottom. Then create a new image using the gradient as the 3rd, or "fill" argument to Image.new. Stow the new image in the imagelist.

top_grad = GradientFill.new(0, 0, WIDTH, 0, "#dddddd", "#888888")
stripes << Image.new(WIDTH, HEIGHT, top_grad)

Repeat with darker shades of gray.

bottom_grad = GradientFill.new(0, 0, WIDTH, 0, "#757575", "#555555")
stripes << Image.new(WIDTH, HEIGHT, bottom_grad)

Let's look at the images. This is the top image:

This is the bottom:

Now use append to stack the two images and produce a single image. The append method takes one argument, either true or false. If true, append stacks the images vertically. If false, append joins the images horizontally.

combined_grad = stripes.append(true)

Here's what the combined images look like:

The colorize composite operation

So far so good. Now add some color. To do this use the composite method to combine the grays from these gradients with a color. Remember from Part 1 that alpha compositing uses a source image and a destination image. In this case, the destination image will be the combined gradient image you just made. Now you need to make the source image. This is the image that will supply the color.

Make a source image the same size at the combined gradient image. Give it a solid blue background.

color = Image.new(combined_grad.columns, combined_grad.rows) do
         self.background_color = "#87a5ff"

That image looks like this:

In Part 1 I explained that the src-over composite operation replaces pixels in the destination image with pixels from the source image. This time you don't want to replace the gray pixels with blue pixels. Instead you want to blend the blue from the source image with the grays of the destination image. To do this it helps to think about the colors in the images in terms of their hue, saturation, and lightness.

We are accustomed to thinking of colors by their red, green, and blue components, that is, in the RGB scheme. Every color can also be described by its hue, saturation, and lightness components as well. In the HSL scheme, the hue is the position of the color on the color wheel. Lightness (also called "luminance") describes how much light the color has in it. Black has 0% lightness, white has 100%. Saturation is a measurement of the intensity of the color from vivid to washed-out.

RMagick supports a full range of composite operations to combine the HSL components of the pixels in two images. The operation needed here is called colorize. The colorize operation combines the saturation and hue of the source image with the lightness of the target image.

Remember, in RMagick the destination image is the image to which the composite method is sent. The source image is the first argument to composite. The second argument positions the source image relative to the destination. Since both images are the same size it hardly matters which one you choose. Here I chose CenterGravity for readability. The third argument specifies the desired composite operation.

background = combined_grad.composite(color, CenterGravity, ColorizeCompositeOp)

The colorized gradient looks like this:

Next, annotate the image with the word "RMAGICK" and its "reflection."

>> Page 2: Add reflecting text >>