Meet us at PRINT 19. Chicago, IL. Oct. 3 - 5.
This documentation is for the old version. Go to the latest Graphics Mill docs

Adding Vignette

Vignette is a nice example of artistic effects which decorates the image and makes it more attractive. This topic describes how to create vignettes using Graphics Mill for .NET.

Vignettes can have different shape and width. Let's begin with vignette which you can see on the image below.

Image with vignette

It can be achieved by using Buttonize method of the TransformsProvider returned by the Bitmap (or an appropriate Buttonize transform class). Here is a code example which adds this vignette:

Visual Basic
bitmap.Transforms.Buttonize(50, Aurigma.GraphicsMill.Transforms.FadeType.Nonlinear, _
    Aurigma.GraphicsMill.Transforms.Direction.UpLeft, _
    Aurigma.GraphicsMill.RgbColor.Black, _
    Aurigma.GraphicsMill.RgbColor.Black)
C#
bitmap.Transforms.Buttonize(50, Aurigma.GraphicsMill.Transforms.FadeType.Nonlinear, 
    Aurigma.GraphicsMill.Transforms.Direction.UpLeft, 
    Aurigma.GraphicsMill.RgbColor.Black, 
    Aurigma.GraphicsMill.RgbColor.Black);

If you need to increase the width of the vignette (like on the image below), you may notice that Buttonize can work in a wrong way. In this case you can modify the code to move "thin" vignette into the center and fill border with the vignette color using Crop.

Image with vignette

Here is a modified code:

Visual Basic
Dim offset As Integer = 20

'Crop in
bitmap.Transforms.Crop(offset, offset, _
    bitmap.Width - 2 * offset, bitmap.Height - 2 * offset)

'Add vignette
bitmap.Transforms.Buttonize(50, Aurigma.GraphicsMill.Transforms.FadeType.Nonlinear, _
    Aurigma.GraphicsMill.Transforms.Direction.UpLeft, _
    Aurigma.GraphicsMill.RgbColor.Black, _
    Aurigma.GraphicsMill.RgbColor.Black)

'Crop out
bitmap.Transforms.Crop(-offset, -offset, _
    bitmap.Width + 2 * offset, bitmap.Height + 2 * offset, _
    Aurigma.GraphicsMill.RgbColor.Black)
C#
const int offset = 20;
 
//Crop in
bitmap.Transforms.Crop(offset, offset, 
    bitmap.Width - 2 * offset, bitmap.Height - 2 * offset);

//Add vignette
bitmap.Transforms.Buttonize(50, Aurigma.GraphicsMill.Transforms.FadeType.Nonlinear, 
    Aurigma.GraphicsMill.Transforms.Direction.UpLeft, 
    Aurigma.GraphicsMill.RgbColor.Black, 
    Aurigma.GraphicsMill.RgbColor.Black);

//Crop out
bitmap.Transforms.Crop(-offset, -offset, 
    bitmap.Width + 2 * offset, bitmap.Height + 2 * offset, 
    Aurigma.GraphicsMill.RgbColor.Black);

However Graphics Mill for .NET allows to draw more advanced vignettes. You can create not only rectangular vignettes, but vignettes of other shapes too, for example, an ellipse like on the image below.

Image with vignette

However, this cannot be done via Buttonize method, so we have to use another means. For elliptical vignette we can use the following technique:

  1. Create a new empty mask image. It must have the same size as the image which you want to decorate and pixel format should be 8-bit grayscale (or 16-bit if extended). The easiest way to do it is to use GetEmptyMask() method of the Bitmap method.
  2. Using GdiGraphics object draw a hollow ellipse thick enough to fill all the edges.
  3. Blur this mask.
  4. Replace the original image alpha channel with prepared mask and flatten this image.

The code example below demonstrates this approach.

Visual Basic
'Convert to format with alpha channel
If Not bitmap.HasAlpha Then
    bitmap.Channels.AddAlpha(1)
End If

Dim alpha As Aurigma.GraphicsMill.Bitmap = bitmap.GetEmptyMask()
Dim gdiGraphics As New Aurigma.GraphicsMill.Drawing.GdiGraphics(alpha)
gdiGraphics.FillEllipse(New Aurigma.GraphicsMill.Drawing.SolidBrush( _
    Aurigma.GraphicsMill.RgbColor.White), 20, 20, bitmap.Width - 40, _
    bitmap.Height - 40)

alpha.Transforms.Blur(40)

bitmap.Channels.Channel(Aurigma.GraphicsMill.ColorChannel.Alpha) = alpha

'Flatten alpha channel
bitmap.Channels.DiscardAlpha(Aurigma.GraphicsMill.RgbColor.Black)
C#
//Convert to format with alpha channel
if (!bitmap.HasAlpha)
{
    bitmap.Channels.AddAlpha(1);
}

Aurigma.GraphicsMill.Bitmap alpha = bitmap.GetEmptyMask();
Aurigma.GraphicsMill.Drawing.GdiGraphics gdiGraphics = 
    new Aurigma.GraphicsMill.Drawing.GdiGraphics(alpha);
gdiGraphics.FillEllipse(new Aurigma.GraphicsMill.Drawing.SolidBrush( 
    Aurigma.GraphicsMill.RgbColor.White), 20, 20, bitmap.Width - 40, bitmap.Height - 40);

alpha.Transforms.Blur(40);

bitmap.Channels[Aurigma.GraphicsMill.ColorChannel.Alpha] = alpha;

//Flatten alpha channel
bitmap.Channels.DiscardAlpha(Aurigma.GraphicsMill.RgbColor.Black);

Note, this approach opens wide horizons for creativity. For example, it allows you to create vignettes of other shapes (for example, hearts, diamonds, stars, clouds or any other). Using GdiGraphics you can draw curves of any shape you can invent.

You can also use another technique which works somewhat slower, but gives additional control:

  1. Create an empty bitmap of the same size as the target bitmap (an overlaying bitmap).
  2. Create an empty grayscale bitmap. It will be a mask for the alpha channel of the overlaying bitmap. At this mask, areas filled with black will be transparent, with white—opaque, and with gray—semitransparent.
  3. Draw a necessary vignette pattern at the mask and apply necessary effects.
  4. Replace the alpha channel of the overlaying bitmap with the mask.
  5. Combine overlaying image with the original one. You can use not only alpha blending, but also other combine modes. For example, using the Screen combine mode you can make the pixels under the vignette have the same tint as the vignette color, preserving highlights and shadows of the original image.

That is how an image with such a vignette might look:

Image with vignette

The code example below shows this approach.

Visual Basic
Dim bitmap As New Aurigma.GraphicsMill.Bitmap("D:\girl.jpg")

'Create an ovelaying bitmap
Dim overlay As New Aurigma.GraphicsMill.Bitmap( _
    Aurigma.GraphicsMill.RgbColor.Pink, bitmap.Width, bitmap.Height, _
    Aurigma.GraphicsMill.PixelFormat.Format32bppArgb)

'Create an empty mask. It will be opaque as it is filled with white
Dim mask As New Aurigma.GraphicsMill.Bitmap( _
    Aurigma.GraphicsMill.RgbColor.White, bitmap.Width, bitmap.Height, _
    Aurigma.GraphicsMill.PixelFormat.Format8bppGrayScale)

Dim points As System.Drawing.Point() = { _
    New System.Drawing.Point(20, 10), _
    New System.Drawing.Point(overlay.Width - 20, 10), _
    New System.Drawing.Point(overlay.Width - 10, 20), _
    New System.Drawing.Point(overlay.Width - 10, overlay.Height - 20), _
    New System.Drawing.Point(overlay.Width - 20, overlay.Height - 10), _
    New System.Drawing.Point(20, overlay.Height - 10), _
    New System.Drawing.Point(10, overlay.Height - 20), _
    New System.Drawing.Point(10, 20), _
    New System.Drawing.Point(20, 10) }
Dim graphics As Aurigma.GraphicsMill.Drawing.GdiGraphics = mask.GetGdiGraphics()

'Draw a polygon
graphics.FillPolygon(New Aurigma.GraphicsMill.Drawing.SolidBrush( _
    Aurigma.GraphicsMill.RgbColor.Black), points)

'Add a blur effect
mask.Transforms.Blur(7.0F, Aurigma.GraphicsMill.Transforms.BlurType.Gaussian)

'Replace the alpha channel of the overlay with the mask
overlay.Channels.Channel(overlay.Channels.AlphaChannelIndex) = mask

'Put the ovelaying bitmap over the source image
overlay.Draw(bitmap, 0, 0, overlay.Width, overlay.Height, _
    Aurigma.GraphicsMill.Transforms.CombineMode.Screen, 1.0F, _
    Aurigma.GraphicsMill.Transforms.InterpolationMode.HighQuality)
C#
Aurigma.GraphicsMill.Bitmap bitmap = new Aurigma.GraphicsMill.Bitmap(
    @"D:\girl.jpg");

//Create an ovelaying bitmap
Aurigma.GraphicsMill.Bitmap overlay = new
    Aurigma.GraphicsMill.Bitmap(Aurigma.GraphicsMill.RgbColor.Pink,
    bitmap.Width, bitmap.Height,
    Aurigma.GraphicsMill.PixelFormat.Format32bppArgb);

//Create an empty mask. It will be opaque as it is filled with white
Aurigma.GraphicsMill.Bitmap mask = new
    Aurigma.GraphicsMill.Bitmap(Aurigma.GraphicsMill.RgbColor.White,
    bitmap.Width, bitmap.Height,
    Aurigma.GraphicsMill.PixelFormat.Format8bppGrayScale);

System.Drawing.Point [] points = 
{
    new System.Drawing.Point(20, 10),
    new System.Drawing.Point(overlay.Width-20, 10),
    new System.Drawing.Point(overlay.Width-10, 20),
    new System.Drawing.Point(overlay.Width-10, overlay.Height-20),
    new System.Drawing.Point(overlay.Width-20, overlay.Height-10),
    new System.Drawing.Point(20, overlay.Height-10),
    new System.Drawing.Point(10, overlay.Height-20),
    new System.Drawing.Point(10, 20),
    new System.Drawing.Point(20, 10)
};
Aurigma.GraphicsMill.Drawing.GdiGraphics graphics =
    mask.GetGdiGraphics();

//Draw a polygon
graphics.FillPolygon(new Aurigma.GraphicsMill.Drawing.SolidBrush(
    Aurigma.GraphicsMill.RgbColor.Black), points);

//Add a blur effect
mask.Transforms.Blur(7.0f, Aurigma.GraphicsMill.Transforms.BlurType.Gaussian);

//Replace the alpha channel of the overlay with the mask
overlay.Channels[overlay.Channels.AlphaChannelIndex] = mask;

//Put the ovelaying bitmap over the source image
overlay.Draw(bitmap, 0, 0, overlay.Width, overlay.Height,
    Aurigma.GraphicsMill.Transforms.CombineMode.Screen, 1.0f,
    Aurigma.GraphicsMill.Transforms.InterpolationMode.HighQuality);