---
title: "Graphics: Drawing Images and Geometric Shapes"
canonical: https://www.graphicsmill.com/docs/gm/graphics.htm
product: "Graphics Mill"
---

# Graphics: Drawing Images and Geometric Shapes
 
The article below is devoted to the basic aspects of using the drawing engine in Graphics Mill. Reading this article will help you become familiar with:
 
- The concept of **Graphics**, how to draw on bitmaps, and how to create PDF and EPS files.
- How to use pens and brushes for drawing geometric shapes.
- How to utilize drawing operations within the engine. Drawing images, curves, and shapes.
- What the clipping path is and how to apply it while drawing.

## Graphics. Drawing on Bitmaps. Creating PDF and EPS.
  
The [Aurigma.GraphicsMill.Drawing](https://www.graphicsmill.com/docs/gm/N_Aurigma_GraphicsMill_Drawing.htm.md) namespace represents the drawing API in Graphics Mill. It includes classes allowing the creation of images of any complexity. All drawing operations are represented by the [Drawing.Graphics](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_Drawing_Graphics.htm.md) class that can be created from the following types of objects:
 
- [Bitmap](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_Bitmap.htm.md). **Aurigma.GraphicsMill.Drawing** allows drawing on images with any pixel format supported by Graphics Mill, except for indexed formats. Even extended formats (16 bits per channel), CMYK, and formats with alpha channels are handled correctly. The following snippet illustrates how to get **Graphics** from **Bitmap**:
 
```csharp
    using (var bitmap = new Bitmap(640, 480, PixelFormat.Format24bppRgb, RgbColor.White))
    {
        var graphics = bitmap.GetGraphics();
    }
    ```
- [PdfWriter](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_Codecs_PdfWriter.htm.md) allows for creating multi-page PDF documents and filling each page with content using the drawing API (to learn more about how to work with PDF, read the [Working with PDF](https://www.graphicsmill.com/docs/gm/working-with-pdf.htm.md) topic). Here is the code creating **Graphics** from **PdfWriter**.
 
```csharp
    using (var pdfWriter = new PdfWriter("in.pdf"))
    {
        pdfWriter.AddPage(500, 500);
        var graphics = pdfWriter.GetGraphics();
    }
    ```
- [EpsWriter](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_Codecs_EpsWriter.htm.md) is a class for creating EPS files (to learn more about how to work with EPS, read the [Working with EPS](https://www.graphicsmill.com/docs/gm/working-with-eps.htm.md) topic). The following snippet shows how to get **Graphics** from **EpsWriter**:
 
```csharp
    using (var epsWriter = new EpsWriter("in.eps", 640, 480))
    {
        var graphics = epsWriter.GetGraphics();
    }
    ```
 
## Pens and Brushes
  
[Pen](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_Drawing_Pen.htm.md) and [Brush](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_Drawing_Brush.htm.md) are two centerpiece objects needed for drawing graphics shapes. Pens are used for drawing lines, outlining shapes, or delineating other geometric objects. Whereas brushes are used for filling areas, such as filled shapes and text.
 
### Line Color and Width
 
**Pen** allows you to specify an outline color via the [Pen.Color](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_Drawing_Pen_Color.htm.md) property and the outline width via the [Pen.Width](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_Drawing_Pen_Width.htm.md) property. The default value of **Width** is `1.0`, whereas **Color** should always be passed to a constructor when initializing a **Pen** instance.
 
The following snippet draws two lines:
 ![Using Pens.](https://www.graphicsmill.com/docs/gm/Graphics8.png) 
```csharp
using (var bitmap = new Bitmap(100, 60, PixelFormat.Format24bppRgb, RgbColor.White))
using (var graphics = bitmap.GetGraphics())
{
    var redPen = new Pen(RgbColor.Red, 8);
    graphics.DrawLine(redPen, 10, 5, 90, 55);

    var bluePen = new Pen(RgbColor.Blue, 8);
    graphics.DrawLine(bluePen, 10, 55, 90, 5);

    bitmap.Save(@"Images\Output\out.png");
}
```
 
### Dash Lines
 
By default, you draw solid lines. To draw dotted or dashed lines, specify the [Pen.DashPattern](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_Drawing_Pen_DashPattern.htm.md) property. This property is an array, and its elements are a sequence of painted and unpainted units. So, you are free to draw lines of any dash style.
 
For example, the following snippet draws dashed, dotted, and dash-dot lines:
 ![Pens with dashes and dots.](https://www.graphicsmill.com/docs/gm/Graphics9.png) 
```csharp
using (var bitmap = new Bitmap(160, 80, PixelFormat.Format24bppRgb, RgbColor.White))
using (var graphics = bitmap.GetGraphics())
{
    // A dashed line
    var pen = new Pen(RgbColor.Red, 2);
    pen.DashPattern = new float[] { 8, 2 };
    graphics.DrawLine(pen, 20, 20, 140, 20);

    // A dotted line
    pen.Color = RgbColor.DarkOrange;
    pen.DashPattern = new float[] { 2 };
    graphics.DrawLine(pen, 20, 40, 140, 40);

    // A dash-dot line
    pen.Color = RgbColor.Green;
    pen.DashPattern = new float[] { 10, 2, 2, 2 };
    graphics.DrawLine(pen, 20, 60, 140, 60);

    bitmap.Save(@"Images\Output\out.png");
}
```
 
You can shift the dash pattern sequence via the [Pen.DashOffset](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_Drawing_Pen_DashOffset.htm.md) property.
 
### Solid Brushes
 
[SolidBrush](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_Drawing_SolidBrush.htm.md) has the [SolidBrush.Color](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_Drawing_SolidBrush_Color.htm.md) property that specifies the color of the filled area.
 
The following snippet illustrates how to create a yellow rectangle having a green outline:
 
```csharp
using (var bitmap = new Bitmap(160, 120, PixelFormat.Format24bppRgb, RgbColor.White))
using (var graphics = bitmap.GetGraphics())
{
    graphics.DrawRectangle(new Pen(RgbColor.Green, 0.5f), 20, 20, 120, 80);
    graphics.FillRectangle(new SolidBrush(RgbColor.Yellow), 20, 20, 120, 80);
    bitmap.Save(@"Images\Output\out.png");
}
```
 
After launching this snippet, you will see the following result:
 ![Using Solid Brushes.](https://www.graphicsmill.com/docs/gm/Graphics1.png) 
### Gradient Brushes
 
To draw gradients, use the [LinearGradientBrush](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_Drawing_LinearGradientBrush.htm.md) class. You need to specify the [ColorStops](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_Drawing_GradientBrush_ColorStops.htm.md) array that defines the colors of the filled area. Set two or more color stops with a color and its position within the filled area. The position is a relative value. To define a gradient direction, set [StartPoint](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_Drawing_LinearGradientBrush_StartPoint.htm.md) and [EndPoint](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_Drawing_LinearGradientBrush_EndPoint.htm.md).
 
The following snippet illustrates how to create a gradient between blue, yellow, and red:
 ![Using Gradient Brushes.](https://www.graphicsmill.com/docs/gm/Graphics10.png) 
```csharp
using (var bitmap = new Bitmap(300, 70, PixelFormat.Format24bppRgb, RgbColor.White))
using (var graphics = bitmap.GetGraphics())
{
    var brush = new LinearGradientBrush();

    // Define the first color.
    var colorStop1 = new ColorStop();
    colorStop1.Color = RgbColor.Blue;
    colorStop1.Position = 0;

    // Define the second color.
    var colorStop2 = new ColorStop();
    colorStop2.Color = RgbColor.Yellow;
    colorStop2.Position = 0.75f;

    // Define the third color.
    var colorStop3 = new ColorStop();
    colorStop3.Color = RgbColor.Red;
    colorStop3.Position = 1;

    brush.ColorStops = new ColorStop[] { colorStop1, colorStop2, colorStop3 };

    // Define a direction of the gradient.
    brush.StartPoint = new System.Drawing.PointF(0, 0);
    brush.EndPoint = new System.Drawing.PointF(300, 0);

    graphics.FillRectangle(brush, 0, 0, 300, 70);

    bitmap.Save(@"Images\Output\out.png");

}
```
 
## Drawing Graphic Elements
  
**Graphics** allows the drawing of the following elements:
 
- Images
- Lines and Curves
- Graphics Shapes
- [Text](https://www.graphicsmill.com/docs/gm/advanced-drawing-text.htm.md)

### Drawing Images
 
For drawing images, **Graphics** provides the [DrawImage(Bitmap, RectangleF)](https://www.graphicsmill.com/docs/gm/M_Aurigma_GraphicsMill_Drawing_Graphics_DrawImage_2_2fdc9815.htm.md) method. This method draws an image from **Bitmap** in the specified rectangle, for example:
 
```csharp
using (var bitmap = new Bitmap(225, 336, PixelFormat.Format24bppRgb, RgbColor.White))
using (var image = new Bitmap(@"Images\in.png"))
using (var graphics = bitmap.GetGraphics())
{
    graphics.DrawImage(image, new System.Drawing.RectangleF(30, 30, 175, 286));
    bitmap.Save(@"Images\Output\out.png");
}
```
 
To make the source image fit the specified rectangle, Graphics Mill resizes the image, preserving its aspect ratio. If you need to preserve the original image's size, you should specify the location of the image:
 
```csharp
using (var bitmap = new Bitmap(225, 336, PixelFormat.Format24bppRgb, RgbColor.White))
using (var image = new Bitmap(@"Images\in.png"))
using (var graphics = bitmap.GetGraphics())
{
    graphics.DrawImage(image, 0, 0);
    bitmap.Save(@"Images\Output\out.png");
}
```
 
You can also draw an image from [Pipeline](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_Pipeline.htm.md) using the overloaded [DrawImage(Pipeline, RectangleF)](https://www.graphicsmill.com/docs/gm/M_Aurigma_GraphicsMill_Drawing_Graphics_DrawImage_2_e4e5b0be.htm.md) method. This is useful when you need to transform your image before drawing, for instance, to rotate, resize, or crop it. The following snippet shows how to resize an image and then draw it in the PDF format:
 
```csharp
using (var pdf = new PdfWriter(@"Images\Output\out.pdf"))
using (var image = new Bitmap(@"Images\in.png"))
using (var resize = new Resize(200, 150))
using (var graphics = pdf.GetGraphics())
{
    pdf.AddPage(200, 150);
    graphics.DrawImage(new Pipeline(image + resize), 0, 0);
    pdf.Close();
}
```
 
This snippet resizes the image without preserving its aspect ratio. You can choose whether or not to save an image's ratio using the [Resize.ResizeMode](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_Transforms_Resize_ResizeMode.htm.md) property. You can also handle the quality of a resized image via the [Resize.InterpolationMode](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_Transforms_Resize_InterpolationMode.htm.md) property. For example, the following snippet demonstrates how to resize an image with high quality and preserve its aspect ratio:
 
```csharp
using (var bitmap = new Bitmap(200, 150, PixelFormat.Format24bppRgb, RgbColor.White))
using (var image = new Bitmap(@"Images\in.png"))
using (var resize = new Resize(200, 150, ResizeInterpolationMode.High, ResizeMode.Fit))
using (var graphics = bitmap.GetGraphics())
{
    graphics.DrawImage(new Pipeline(image + resize), 0, 0);
    bitmap.Save(@"Images\Output\out.png");
}
```
 
### Drawing Lines and Curves
 
**Graphics** supports drawing the following line objects: lines, polylines, and Bezier curves. For all these types, you need to specify the outline color and width using a **Pen** instance. Let us discuss how to draw each line type.
 
#### Lines
 
To create a line, use the [DrawLine(Pen, PointF, PointF)](https://www.graphicsmill.com/docs/gm/M_Aurigma_GraphicsMill_Drawing_Graphics_DrawLine_3_32eccb21.htm.md) method as the following snippet illustrates:
 
```csharp
using (var bitmap = new Bitmap(160, 120, PixelFormat.Format24bppRgb, RgbColor.White))
using (var graphics = bitmap.GetGraphics())
{
    graphics.DrawLine(new Pen(RgbColor.Red), 10, 10, 150, 110);
    bitmap.Save(@"Images\Output\out.png");
}
```
 
After launching this snippet you will see the following line:
 ![Drawing Lines.](https://www.graphicsmill.com/docs/gm/Graphics2.png) 
#### Polylines
 
To create a polyline, use the [DrawLines(Pen, PointF\[\])](https://www.graphicsmill.com/docs/gm/M_Aurigma_GraphicsMill_Drawing_Graphics_DrawLines_2_a58b81e0.htm.md) method that draws a set of line segments specified by a [PointF](https://learn.microsoft.com/en-us/dotnet/api/system.drawing.pointf?view=netframework-4.8) array. Remember, the ending point of a line is the starting point of the next line. The following snippet demonstrates how to draw a pentagon:
 
```csharp
using (var bitmap = new Bitmap(170, 160, PixelFormat.Format24bppRgb, RgbColor.White))
using (var graphics = bitmap.GetGraphics())
{
    System.Drawing.PointF[] points = {
        new System.Drawing.PointF(5,  65),
        new System.Drawing.PointF(85, 5),
        new System.Drawing.PointF(165, 65),
        new System.Drawing.PointF(135, 153),
        new System.Drawing.PointF(35,  153),
        new System.Drawing.PointF(5, 65)};
    graphics.DrawLines(new Pen(RgbColor.Green), points);
    bitmap.Save(@"Images\Output\out.png");
}
```
 
The polyline delineated pentagon looks as follows:
 ![Drawing Polylines.](https://www.graphicsmill.com/docs/gm/Graphics3.png) 
#### Bezier Curves
 
To create a Bezier curve, use the [DrawBezier(Pen, PointF, PointF, PointF, PointF)](https://www.graphicsmill.com/docs/gm/M_Aurigma_GraphicsMill_Drawing_Graphics_DrawBezier_5_8a3de9c1.htm.md) method. A cubic Bezier curve is set by four points: a starting point, two control points specifying the curve direction, and an ending point (read the [Working with Paths](https://www.graphicsmill.com/docs/gm/working-with-path.htm.md) article discussing a cubic Bezier curve in detail). The following snippet illustrates how to draw a curve:
 
```csharp
using (var bitmap = new Bitmap(160, 120, PixelFormat.Format24bppRgb, RgbColor.White))
using (var graphics = bitmap.GetGraphics()) 
{
    graphics.DrawBezier(new Pen(RgbColor.Black), 10, 60, 40, 20, 70, 60, 100, 20); 
    bitmap.Save(@"Images\Output\out.png");
}
```
 
You can create a sequence of Bezier curves using the [DrawBeziers(Pen, PointF\[\])](https://www.graphicsmill.com/docs/gm/M_Aurigma_GraphicsMill_Drawing_Graphics_DrawBeziers_2_a58b81e0.htm.md) method. The ending point of one spline will be the starting point of the next one. Therefore, for splines, except for the first one in the array, you need to specify three points instead of four. The following snippet shows how to create a sequence of two splines:
 
```csharp
using (var bitmap = new Bitmap(200, 80, PixelFormat.Format24bppRgb, RgbColor.White))
using (var graphics = bitmap.GetGraphics())
{
    System.Drawing.PointF[] points = {
        new System.Drawing.PointF(10,  60),
        new System.Drawing.PointF(40, 20),
        new System.Drawing.PointF(70,  60),
        new System.Drawing.PointF(100, 20),
        new System.Drawing.PointF(130, 60),
        new System.Drawing.PointF(160, 20),
        new System.Drawing.PointF(190, 60)};
    graphics.DrawBeziers(new Pen(RgbColor.Black), points);
    bitmap.Save(@"Images\Output\out.png");
}
```
 
Please note that transition between two splines in a sequence is not smoothed, as you can see in the image below:
 ![Drawing Curves.](https://www.graphicsmill.com/docs/gm/Graphics4.png) 
### Drawing Graphics Shapes
 
**Graphics** supports drawing the following shapes: rectangles, ellipses, polygons, and paths. For all of them, you need to specify their outline color and width using a **Pen** instance. Now we will discuss how to draw these elements.
 
#### Rectangles
 
To draw a rectangle, use the [DrawRectangle(Pen, RectangleF)](https://www.graphicsmill.com/docs/gm/M_Aurigma_GraphicsMill_Drawing_Graphics_DrawRectangle_2_169e24a7.htm.md) method, passing the top left corner of the rectangle and its width and height as parameters:
 
```csharp
using (var bitmap = new Bitmap(80, 80, PixelFormat.Format24bppRgb, RgbColor.White))
using (var graphics = bitmap.GetGraphics())
{
    graphics.DrawRectangle(new Pen(RgbColor.Blue), new System.Drawing.Rectangle(10, 10, 60, 60));
    bitmap.Save(@"Images\Output\out.png");
}
```
 
You can draw several rectangles at a time using the [DrawRectangles(Pen, RectangleF\[\])](https://www.graphicsmill.com/docs/gm/M_Aurigma_GraphicsMill_Drawing_Graphics_DrawRectangles_2_8b12e7a5.htm.md) method, which accepts an array of [RectangleF](https://learn.microsoft.com/en-us/dotnet/api/system.drawing.rectanglef?view=netframework-4.8).
 
#### Ellipses
 
To draw an ellipse, you need to specify a rectangle bounding the ellipse as a parameter of the [DrawEllipse(Pen, RectangleF)](https://www.graphicsmill.com/docs/gm/M_Aurigma_GraphicsMill_Drawing_Graphics_DrawEllipse_2_169e24a7.htm.md) method:
 
```csharp
using (var bitmap = new Bitmap(80, 80, PixelFormat.Format24bppRgb, RgbColor.White))
using (var graphics = bitmap.GetGraphics())
{
    graphics.DrawEllipse(new Pen(RgbColor.Blue), new System.Drawing.RectangleF(10, 10, 60, 60));
    bitmap.Save(@"Images\Output\out.png");
}
```
 
You can also draw several ellipses at a time using the [DrawEllipses(Pen, RectangleF\[\])](https://www.graphicsmill.com/docs/gm/M_Aurigma_GraphicsMill_Drawing_Graphics_DrawEllipses_2_8b12e7a5.htm.md) method, which accepts an array of **RectangleF**.
 
#### Polygons
 
To draw a polygon, use the [DrawPolygon(Pen, PointF\[\])](https://www.graphicsmill.com/docs/gm/M_Aurigma_GraphicsMill_Drawing_Graphics_DrawPolygon_2_a58b81e0.htm.md) method, which accepts an array of vertices as the argument:
 
```csharp
using (var bitmap = new Bitmap(170, 160, PixelFormat.Format24bppRgb, RgbColor.White))
using (var graphics = bitmap.GetGraphics())
{
    System.Drawing.PointF[] points = {
        new System.Drawing.PointF(5,  55),
        new System.Drawing.PointF(85, 5),
        new System.Drawing.PointF(165, 55),
        new System.Drawing.PointF(135, 153),
        new System.Drawing.PointF(35,  153)};
    graphics.DrawPolygon(new Pen(RgbColor.Blue), points);
    bitmap.Save(@"Images\Output\out.png");
}
```
 
#### Paths
 
To draw a path on a **Graphics** object, use the [Graphics.DrawPath(Pen, Path)](https://www.graphicsmill.com/docs/gm/M_Aurigma_GraphicsMill_Drawing_Graphics_DrawPath_2_77634c23.htm.md) method as shown below. If you do not know how to work with paths in Graphics Mill, read the [Working with Paths](https://www.graphicsmill.com/docs/gm/working-with-path.htm.md) article.
 
```csharp
using (var bitmap = new Bitmap(170, 160, PixelFormat.Format24bppRgb, RgbColor.White))
using (var graphics = bitmap.GetGraphics())
using (var path = new Path())
{
    path.DrawRectangle(new System.Drawing.RectangleF(75, 75, 75, 35));
    graphics.DrawPath(new Pen(RgbColor.Green), path);
    bitmap.Save(@"Images\Output\out.png");
}
```
 
### Filling Figures
 
All figures discussed in the previous paragraph are drawn as outline shapes. Here, we will demonstrate methods of the **Graphics** class that draws filled elements:
 
- The [FillRectangle(Brush, RectangleF)](https://www.graphicsmill.com/docs/gm/M_Aurigma_GraphicsMill_Drawing_Graphics_FillRectangle_2_9763ccb2.htm.md) method fills a rectangle.
- The [FillEllipse(Brush, RectangleF)](https://www.graphicsmill.com/docs/gm/M_Aurigma_GraphicsMill_Drawing_Graphics_FillEllipse_2_9763ccb2.htm.md) method fills an ellipse.
- The [FillPolygon(Brush, PointF\[\])](https://www.graphicsmill.com/docs/gm/M_Aurigma_GraphicsMill_Drawing_Graphics_FillPolygon_2_928ed375.htm.md) method fills a polygon.
- The [FillBezier(Brush, PointF, PointF, PointF, PointF)](https://www.graphicsmill.com/docs/gm/M_Aurigma_GraphicsMill_Drawing_Graphics_FillBezier_5_9c69d196.htm.md) method fills a Bezier curve.
- The [FillPath(Brush, Path)](https://www.graphicsmill.com/docs/gm/M_Aurigma_GraphicsMill_Drawing_Graphics_FillPath_2_3cee1596.htm.md) method fills a path.

All these methods accept a **Brush** class instance as a parameter specifying a figure color.
 
The following snippet demonstrates how to draw a filled ellipse and its bounded rectangle:
 
```csharp
using (var bitmap = new Bitmap(160, 120, PixelFormat.Format24bppRgb, RgbColor.White))
using (var graphics = bitmap.GetGraphics())
{
    graphics.FillEllipse(new SolidBrush(RgbColor.Green), new System.Drawing.RectangleF(20, 20, 120, 80));
    graphics.DrawRectangle(new Pen(RgbColor.YellowGreen), new System.Drawing.RectangleF(20, 20, 120, 80));
    bitmap.Save(@"Images\Output\out.png");
}
```
 
Here is the result of this snippet:
 ![Filled Shape.](https://www.graphicsmill.com/docs/gm/Graphics5.png)
 
## Clipping Path
  
The clipping path is a technique for cutting out a part of an image that is outside of a given vector path (to learn more about paths, read the [Working with Paths](https://www.graphicsmill.com/docs/gm/working-with-path.htm.md) article). For example, using a clipping path you can select an area of the image and put it over a new background. **Graphics** instances can have one or more clipping paths set in the [Graphics.ClippingPaths](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_Drawing_Graphics_ClippingPaths.htm.md) property. While drawing with the **Graphics** object, the drawing region is defined by the path specified in this property. Everything drawn outside the given paths will not have any effect on the resulting image.
 
Assume that you have two images:
 ![Star.](https://www.graphicsmill.com/docs/gm/Graphics6.png) 
Let us say the first image contains a clipping path delineating the star (e.g. in Adobe Resources). We need to downsize the star and put it on the Christmas tree as follows:
 ![Star on Tree.](https://www.graphicsmill.com/docs/gm/Graphics7.png) 
Here is the algorithm that performs the task:
 
1. Open the image with the star using [ImageReader](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_Codecs_ImageReader.htm.md).
2. Extract the clipping path from the loaded image and copy it to an [Drawing.Path](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_Drawing_Path.htm.md) instance.
3. Resize the path. It should have the same size as the star on the Christmas tree.
4. Move the resized path to the appropriate position.
5. Add the path to the **Graphics.ClippingPaths** collection of **Graphics** created for the Christmas tree image.
6. Resize the image of the star and use the [Graphics.DrawImage(Pipeline, Single, Single)](https://www.graphicsmill.com/docs/gm/M_Aurigma_GraphicsMill_Drawing_Graphics_DrawImage_3_81ae131e.htm.md) method to draw it on the Christmas tree.

According to the algorithm, we need to resize and translate the path. The **Drawing.Path** class provides the [ApplyTransform(Matrix)](https://www.graphicsmill.com/docs/gm/M_Aurigma_GraphicsMill_Drawing_Path_ApplyTransform_1_5bff9483.htm.md) method for manipulating the path. This method accepts a [Matrix](https://learn.microsoft.com/en-us/dotnet/api/system.drawing.drawing2d.matrix?view=netframework-4.8) instance as an argument. In turn, **Matrix** provides methods such as **Translate**, **Scale**, **Rotate**, etc., which perform transformations. Make sure that you apply the same transformations on the original "star" image as on the clipping path extracted from it. Otherwise, the path and the clipping path will not match. Here is the code based on the algorithm:
 
```csharp
using (var reader = ImageReader.Create(@"Images\star.psd"))
using (var bitmap = new Bitmap(@"Images\conifer.png"))
using (var resize = new Resize(reader.Width / 4, reader.Height / 4))
using (var graphics = bitmap.GetGraphics())
{
    var path = Path.Create(reader.ClippingPaths[0].CreateGraphicsPath(reader.Width, reader.Height));
    var m = new System.Drawing.Drawing2D.Matrix();
    m.Translate(85, 60);
    m.Scale(0.25f, 0.25f);
    path.ApplyTransform(m);

    graphics.ClippingPaths.Add(path);
    graphics.DrawImage(new Pipeline(reader.Frames[0] + resize), 43, 39);
    
    bitmap.Save(@"Images\Output\out.png");
}
```
 
## Soft Masks
  
A soft mask is a technique for applying variable opacity to elements drawn on a **Graphics** object. Unlike a fixed alpha channel tied to pixel data, a soft mask is a general concept that works at the **Graphics** level - it defines a grayscale mask that controls the opacity of any content drawn through it.
 
Soft masks are particularly useful for:
 
- Creating smooth edges and anti-aliased selections
- Blending content with gradual transitions
- Creating vignettes and fade effects
- Applying localized adjustments with smooth boundaries

From the perspective of a raster image, a soft mask does not bring additional improvements over the existing alpha channel. Instead, it provides a unified way to handle opacity control for abstract **Graphics** contexts, such as drawing on PDF or EPS surfaces, where pixel-level alpha channels are not directly applicable.
 
### Applying a Soft Mask
 
To apply a soft mask, set the **SoftMask** property of a **Graphics** object. It affects everything you draw through this object. You can also set the [Item.SoftMask](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_Drawing_Item_SoftMask.htm.md) property of a single item, for example, of an image or a shape in a container. In this case, the mask affects only this item.
 
The mask itself is the content of a [GraphicsContainer](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_Drawing_GraphicsContainer.htm.md) object. Draw the mask on the container, and then assign the container to the property. The container is converted to a [SoftMask](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_Drawing_SoftMask.htm.md) object with default settings. The default method is **Luminosity**, and there is no backdrop.
 
In the following example, the mask is a white ellipse on an empty container. The red rectangle is visible only inside the ellipse.
 
```csharp
using (var maskContainer = new GraphicsContainer(300, 200, 72, 72))
using (var bitmap = new Bitmap(300, 200, PixelFormat.Format24bppRgb, RgbColor.White))
using (var graphics = bitmap.GetGraphics())
{
    // Define the mask. White content is opaque, and empty (black) area is transparent.
    using (var maskGraphics = maskContainer.GetGraphics())
    {
        var ellipse = new Path();
        ellipse.DrawEllipse(50, 30, 200, 140);
        maskGraphics.FillPath(new SolidBrush(RgbColor.White), ellipse);
    }

    // A GraphicsContainer is converted to a SoftMask with the Luminosity method.
    graphics.SoftMask = maskContainer;

    // The rectangle is visible only inside the ellipse.
    graphics.FillRectangle(new SolidBrush(RgbColor.Red), 0, 0, 300, 200);

    bitmap.Save(@"Images\Output\SoftMaskLuminosity.png");
}
```
 ![A red rectangle drawn through a soft mask with an ellipse.](https://www.graphicsmill.com/docs/gm/SoftMaskLuminosity.png) 
### Mask Method
 
The [SoftMask.Method](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_Drawing_SoftMask_Method.htm.md) property defines how the mask content is converted to opacity. It takes a value of the [SoftMaskMethod](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_Drawing_SoftMaskMethod.htm.md) enumeration:
 
- **Luminosity** - the brightness of the mask content sets the opacity. White is opaque, and black is transparent. This is the default method.
- **Alpha** - the alpha channel of the mask content sets the opacity. The color of the content is ignored.

To change the method, create the **SoftMask** object yourself. The following example uses the **Alpha** method. The mask content is black, but the result is the same as in the previous example, because only the alpha channel matters.
 
```csharp
using (var maskContainer = new GraphicsContainer(300, 200, 72, 72))
using (var bitmap = new Bitmap(300, 200, PixelFormat.Format24bppRgb, RgbColor.White))
using (var graphics = bitmap.GetGraphics())
{
    // Define the mask. Only the alpha channel of this content matters, so the color is not important.
    using (var maskGraphics = maskContainer.GetGraphics())
    {
        var ellipse = new Path();
        ellipse.DrawEllipse(50, 30, 200, 140);
        maskGraphics.FillPath(new SolidBrush(RgbColor.Black), ellipse);
    }

    var softMask = new SoftMask(maskContainer)
    {
        Method = SoftMaskMethod.Alpha
    };

    graphics.SoftMask = softMask;
    graphics.FillRectangle(new SolidBrush(RgbColor.Red), 0, 0, 300, 200);

    bitmap.Save(@"Images\Output\SoftMaskAlpha.png");
}
```
 
### Backdrop
 
By default, the area without mask content is black, so it is transparent for the **Luminosity** method. The [SoftMask.Backdrop](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_Drawing_SoftMask_Backdrop.htm.md) property changes this. It sets the luminosity of the area without mask content, from 0 (black) to 1 (white). The value `null` means the default black backdrop. The backdrop is used only with the **Luminosity** method.
 
In the following example, the mask is a black ellipse and the backdrop is white. The area outside the ellipse is opaque, so the rectangle is visible everywhere except inside the ellipse.
 
```csharp
using (var maskContainer = new GraphicsContainer(300, 200, 72, 72))
using (var bitmap = new Bitmap(300, 200, PixelFormat.Format24bppRgb, RgbColor.White))
using (var graphics = bitmap.GetGraphics())
{
    // Define the mask. Black content is transparent.
    using (var maskGraphics = maskContainer.GetGraphics())
    {
        var ellipse = new Path();
        ellipse.DrawEllipse(50, 30, 200, 140);
        maskGraphics.FillPath(new SolidBrush(RgbColor.Black), ellipse);
    }

    // The white backdrop makes the area outside the mask content opaque.
    var softMask = new SoftMask(maskContainer)
    {
        Backdrop = 1.0
    };

    graphics.SoftMask = softMask;

    // The rectangle is visible everywhere except inside the ellipse.
    graphics.FillRectangle(new SolidBrush(RgbColor.Red), 0, 0, 300, 200);

    bitmap.Save(@"Images\Output\SoftMaskBackdrop.png");
}
```
 ![A red rectangle drawn through a soft mask with a white backdrop. The ellipse is transparent.](https://www.graphicsmill.com/docs/gm/SoftMaskBackdrop.png) 
### Soft Masks in PDF and SVG
 
When you write to PDF, the soft mask is saved as a native PDF soft mask object. It is not rasterized. The mask method and the backdrop are saved too.
 
When you read a PDF file as a graphics container, soft masks are restored with their method and backdrop. If it is possible, the mask content stays vector.
 
SVG output supports the **Alpha** method. SVG has no backdrop. For a **Luminosity** mask with a backdrop, an opaque rectangle of the backdrop color is drawn under the mask content.
 
## See Also
  
### Reference
 
- [Aurigma.GraphicsMill.Drawing Namespace](https://www.graphicsmill.com/docs/gm/N_Aurigma_GraphicsMill_Drawing.htm.md)
- [Drawing.Graphics Class](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_Drawing_Graphics.htm.md)
- [Bitmap Class](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_Bitmap.htm.md)
- [PdfWriter Class](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_Codecs_PdfWriter.htm.md)
- [EpsWriter Class](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_Codecs_EpsWriter.htm.md)
- [Pen Class](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_Drawing_Pen.htm.md)
- [SolidBrush Class](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_Drawing_SolidBrush.htm.md)
- [Path Class](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_Drawing_Path.htm.md)

### Manual
 
- [Working with PDF](https://www.graphicsmill.com/docs/gm/working-with-pdf.htm.md)
- [Adobe Image Resource Blocks](https://www.graphicsmill.com/docs/gm/adobe-image-resource-blocks.htm.md)
- [Working with Paths](https://www.graphicsmill.com/docs/gm/working-with-path.htm.md)
- [Working with the Text Class](https://www.graphicsmill.com/docs/gm/working-with-text-class.htm.md)
- [Drawing Simple Text Objects](https://www.graphicsmill.com/docs/gm/advanced-drawing-text.htm.md)

### Other
 
- [Matrix Class](https://learn.microsoft.com/en-us/dotnet/api/system.drawing.drawing2d.matrix?view=netframework-4.8)
