---
title: "Upgrading from Graphics Mill 5"
canonical: https://www.graphicsmill.com/docs/gm/upgrading-from-graphics-mill-5.htm
product: "Graphics Mill"
---

# Upgrading from Graphics Mill 5
 
Major API changes have occurred in Graphics Mill 6. The later versions are backward compatible. This topic highlights the changes and illustrates how to migrate an application to a new version of the product.
 
- Working with Bitmaps
- Loading and Saving Images
    - Using the Bitmap Class
    - Using Image Readers and Writers
    - Reading and Writing Metadata
    - Codecs API Changes
- Transforming Images
- Converting Colors
    - Image Quantization
    - Color Conversion API Changes
- Drawing on Images

In addition to a traditional image processing approach, Graphics Mill 6 introduced a memory-friendly approach called *pipelines*. They allow for reading and writing image files and processing them without the necessity of loading a whole bitmap into memory. Pipelines are preferable for large images and complex imaging tasks.
 
```csharp
using (var reader = new JpegReader(@"Images\in.jpg"))
using (var resize = new Resize(2048, 0, ResizeInterpolationMode.High))
using (var writer = new JpegWriter(@"Images\Output\out.jpg"))
{
    Pipeline.Run(reader + resize + writer);
}
```
 
See the [Understanding Image Processing Approaches in Graphics Mill](https://www.graphicsmill.com/docs/gm/understanding-image-processing-approaches-in-graphics-mill.htm.md) topic for a detailed description of the differences between a bitmap and pipeline.
 
## Working with Bitmaps
  
The [Bitmap](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_Bitmap.htm.md) class has been significantly simplified in the new version of Graphics Mill. It no longer supports the undo/redo functionality and it implements no events.
 
All properties for retrieving information about an image's pixel format are moved to the [PixelFormat](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_PixelFormat.htm.md) class:
 
```csharp
using (var bitmap = new Bitmap(@"Images\in.jpg"))
{
    Console.WriteLine("Bitmap: " + bitmap.Width + "x" + bitmap.Height);
    Console.WriteLine("  Has Aplha: " + bitmap.HasAlpha);
    Console.WriteLine("  PixelFormat: " + bitmap.PixelFormat.ToString());
    Console.WriteLine("  CMYK: " + bitmap.PixelFormat.IsCmyk);
}
```
 
The built-in units conversion (available through the **Bitmap.Units** property) has been removed, too. Therefore, the image size and coordinates are now always measured in pixels, and the resolution in DPI. However, if you need to convert pixels to device-independent units or vice versa, you can use a utility class [UnitConverter](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_UnitConverter.htm.md). This class doesn't affect image data or attributes, it just converts spatial parameters to different units.
 
```csharp
using (var bitmap = new Bitmap(@"Images\in.jpg"))
{
    float width = UnitConverter.ConvertPixelsToUnits(bitmap.DpiX, bitmap.Width, Unit.Inch);
    float height = UnitConverter.ConvertPixelsToUnits(bitmap.DpiY, bitmap.Height, Unit.Inch);

    Console.WriteLine(width + "x" + height);
}
```
 
The following table contains the most noticeable API changes in the **Bitmap** class.
 
|  **Bitmap.HorizontalResolution**, **Bitmap.VerticalResolution** |  Renamed to [DpiX](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_Bitmap_DpiX.htm.md) and [DpiY](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_Bitmap_DpiY.htm.md). |
| --- | --- |
 |  **Bitmap.IsCmyk**, **Bitmap.IsGrayScale**, **Bitmap.IsRgb**, **Bitmap.IsIndexed**, **Bitmap.IsExtended** |  Removed. Use [PixelFormat.IsCmyk](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_PixelFormat_IsCmyk.htm.md), [PixelFormat.IsGrayscale](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_PixelFormat_IsGrayscale.htm.md), [PixelFormat.IsRgb](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_PixelFormat_IsRgb.htm.md), [PixelFormat.IsIndexed](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_PixelFormat_IsIndexed.htm.md), [PixelFormat.IsExtended](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_PixelFormat_IsExtended.htm.md) instead. |
 |  **Bitmap.BitsPerPixel** |  Removed. Use [PixelFormat.Size](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_PixelFormat_Size.htm.md) instead. |
 
## Loading and Saving Images
  
### Using the Bitmap Class
 
To load an image using the **Bitmap** class, use [constructors](https://www.graphicsmill.com/docs/gm/O_T_Aurigma_GraphicsMill_Bitmap_ctor.htm.md). Note, the **Bitmap.Load** and **Bitmap.LoadThumbnail** methods have been eliminated. To save the **Bitmap**, use the [Save](https://www.graphicsmill.com/docs/gm/O_T_Aurigma_GraphicsMill_Bitmap_Save.htm.md) methods. To pass output parameters (compression type, quality, etc.) use an appropriate [WriterSettings](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_Codecs_WriterSettings.htm.md) class descendant. For example, use the [JpegSettings](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_Codecs_JpegSettings.htm.md) for saving JPEG files, [PngSettings](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_Codecs_PngSettings.htm.md) - for PNG, etc.
 
```csharp
using (var bitmap = new Bitmap(@"Images\in.jpg"))
{
    bitmap.Save(@"Images\Output\out.jpg", new JpegSettings(70));
}
```
 
### Using Image Readers and Writers
 
Image readers and writers offer memory-friendly image processing, multiframe image support, and access to metadata. In the new Graphics Mill version, they are used within the pipeline image processing approach; see the [Processing Large Images](https://www.graphicsmill.com/docs/gm/processing-large-images.htm.md) section for details.
 
To read multipage image files (GIF, TIFF, etc.) frame by frame, use the [ImageReader.Frames](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_Codecs_ImageReader_Frames.htm.md) property. To retrieve a bitmap from a frame, use the [Frame.GetBitmap()](https://www.graphicsmill.com/docs/gm/M_Aurigma_GraphicsMill_Codecs_Frame_GetBitmap.htm.md) method.
 
```csharp
using (var reader = new GifReader(@"Images\slideshow.gif"))
{
    for (int i = 0; i < reader.Frames.Count; i++)
    {
        reader.Frames[i].GetBitmap().Save(@"Images\Output\GIF_frame_" + i.ToString() + ".png");
    }
}
```
 
To construct a multipage image from separate bitmaps, use the following code:
 
```csharp
using (var writer = new GifWriter(@"Images\Output\slideshow.gif"))
{
    writer.FrameOptions.Delay = 100;

    for (int i = 0; i < 4; i++)
    {
        using (var bitmap = new Bitmap(@"Images\GIF_frame_" + i.ToString() + ".png"))
        {
            Pipeline.Run(bitmap + writer);
        }
    }
}
```
 
### Reading and Writing Metadata
 
To read metadata from images, use the [Exif](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_Codecs_ImageReader_Exif.htm.md), [Iptc](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_Codecs_ImageReader_Iptc.htm.md), [AdobeResources](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_Codecs_ImageReader_AdobeResources.htm.md), and [Xmp](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_Codecs_ImageReader_Xmp.htm.md) properties of the [ImageReader](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_Codecs_ImageReader.htm.md) class.
 
```csharp
using (var jpegReader = new JpegReader(@"Images\in.jpg"))
{
    var exif = jpegReader.Exif;
    if (exif != null)
    {
        Console.WriteLine("EXIF");
        foreach (object key in exif.Keys)
        {
            Console.WriteLine("{0}: {1}, {2}", exif.GetKeyDescription(key), exif[key], exif.GetItemString(key));
        }
    }

    var iptc = jpegReader.Iptc;
    if (iptc != null)
    {
        Console.WriteLine("IPTC");
        foreach (long key in iptc.Keys)
        {
            Console.WriteLine("{0}: {1}, {2}", iptc.GetKeyDescription(key), iptc[key], iptc.GetItemString(key));
        }
    }
}
```
 
To write metadata to image files, you can use both image writers and the **Bitmap.Save** method. Image writers supporting metadata expose **Exif**, **Iptc**, **AdobeResources**, and **Xmp** properties.
 
```csharp
using (var jpegReader = new JpegReader(@"Images\in.jpg"))
using (var jpegWriter = new JpegWriter(@"Images\out.jpg"))
{
    var exif = new ExifDictionary();
    exif[ExifDictionary.Software] = "Aurigma Graphics Mill";
    jpegWriter.Exif = exif;

    var iptc = new IptcDictionary();
    iptc[IptcDictionary.Keyword] = "mountain";
    iptc[IptcDictionary.City] = "Olympia";
    jpegWriter.Iptc = iptc;

    Pipeline.Run(jpegReader + jpegWriter);
}
```
 
To write metadata to image files via the **Bitmap.Save** method, use the self-named properties of the [JpegSettings](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_Codecs_JpegSettings.htm.md) and [TiffSettings](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_Codecs_TiffSettings.htm.md) classes. You should create an instance of the corresponding class, initialize its properties with references to metadata, and pass it to the **Save** method.
 
```csharp
using (var bitmap = new Bitmap(@"Images\in.jpg"))
{
    var settings = new JpegSettings(70);

    var exif = new ExifDictionary();
    exif[ExifDictionary.Software] = "Aurigma Graphics Mill";
    settings.Exif = exif;

    var iptc = new IptcDictionary();
    iptc[IptcDictionary.Keyword] = "mountain";
    iptc[IptcDictionary.City] = "Olympia";
    settings.Iptc = iptc;

    bitmap.Save(@"Images\out.jpg", settings);
}
```
 
### Codecs API Changes
 
The following table contains the most noticeable API changes in the [Aurigma.GraphicsMill.Codecs](https://www.graphicsmill.com/docs/gm/N_Aurigma_GraphicsMill_Codecs.htm.md) namespace.
 
|  **FormatReader**/**FormatWriter** |  Renamed to **ImageReader**/[ImageWriter](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_Codecs_ImageWriter.htm.md). |
| --- | --- |
 |  ***XXX*EncoderOptions** |  Renamed to [*XXX*Settings](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_Codecs_WriterSettings.htm.md). |
 |  **AdvancedPsd*XXX***  and **Psd*XXX*** |  Merged and moved to [Aurigma.GraphicsMill.Codecs.Psd](https://www.graphicsmill.com/docs/gm/N_Aurigma_GraphicsMill_Codecs_Psd.htm.md) namespace. |
 |  **Avi*XXX*** , **DS*XXX*** , **Jpeg2k*XXX*** , **Pcx*XXX*** , **QT*XXX*** , **Swf*XXX*** , **Wbmp*XXX*** , **WM*XXX*** |  Removed. |
 
See the [Working with Image Formats](https://www.graphicsmill.com/docs/gm/loading-and-saving-images.htm.md) and [Working with Metadata](https://www.graphicsmill.com/docs/gm/working-with-metadata.htm.md) nodes for details.
 
## Transforming Images
  
Image transformation operations in Graphics Mill can be performed in two ways: in-place and out-of-place. The main difference is that in-place operations change the source bitmap, while out-of-place operations create a new one. To apply an in-place transformation, use the [Bitmap.Transforms](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_Bitmap_Transforms.htm.md) and [Bitmap.ColorAdjustment](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_Bitmap_ColorAdjustment.htm.md) properties:
 
```csharp
using (var bitmap = new Bitmap(@"Images\in.jpg"))
{
    bitmap.Transforms.Crop(50, 60, 50, 100);
    bitmap.Save(@"Images\Output\out.jpg");
}
```
 
To apply an out-of-place transformation, use classes from the [Aurigma.GraphicsMill.Transforms](https://www.graphicsmill.com/docs/gm/N_Aurigma_GraphicsMill_Transforms.htm.md) namespace:
 
```csharp
using (var bitmap = new Bitmap(@"Images\in.jpg"))
{
    var cropRectangle = new System.Drawing.Rectangle(50, 60, 50, 100);

    using (var crop = new Crop(cropRectangle))
    {
        using (var result = crop.Apply(bitmap))
        {
            result.Save(@"Images\Output\out.jpg");
        }
    }
}
```
 
The following table lists API changes in the **Aurigma.GraphicsMill.Transforms** namespace.
 
|  **ApplyLut** |  Renamed to [LutTransform](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_Transforms_LutTransform.htm.md). |
| --- | --- |
 |  **RotateAndFlip** |  Split into [Rotate](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_Transforms_Rotate.htm.md) and [Flip](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_Transforms_Flip.htm.md). |
 |  **InterpolationMode** |  Split into [InterpolationMode](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_Transforms_InterpolationMode.htm.md) and [ResizeInterpolationMode](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_Transforms_ResizeInterpolationMode.htm.md). |
 |  **Curves**, **Glow**, **PageCurl**, **SwapChannels**, **Swirl**, **Waddle**, **WaterDrop**, **Wave** |  Removed. |
 
See the [Transforming Images (Resize, Rotate, Crop)](https://www.graphicsmill.com/docs/gm/transformations-on-images.htm.md) node for details.
 
## Converting Colors
  
Color conversion, as one of image transformations, can be performed both in-place (changing a source image) and out-of-place (creating a new image). To apply an in-place color conversion, use the [Bitmap.ColorManagement](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_Bitmap_ColorManagement.htm.md) property:
 
```csharp
using (var bitmap = new Bitmap(@"Images\cmyk.jpg"))
{
    bitmap.ColorManagement.ColorManagementEngine = ColorManagementEngine.LittleCms;
    bitmap.ColorManagement.DestinationProfile = ColorProfile.FromSrgb();
    bitmap.ColorManagement.Convert(ColorSpace.Rgb, bitmap.HasAlpha, bitmap.PixelFormat.IsExtended);
    bitmap.Save(@"Images\Output\out.jpg");
}
```
 
To apply an out-of-place conversion, use the [ColorConverter](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_Transforms_ColorConverter.htm.md) class:
 
```csharp
using (var bitmap = new Bitmap(@"Images\cmyk.jpg"))
using (var cc = new ColorConverter(PixelFormat.Format24bppRgb))
{
    using (var result = cc.Apply(bitmap))
    {
        result.Save(@"Images\Output\out.jpg");
    }
}
```
 
Note that properties for specifying destination profiles (**CmykColorProfile**, **RgbColorProfile**, and **GrayScaleColorProfile**) have been replaced by [ColorConverter.DestinationProfile](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_Transforms_ColorConverter_DestinationProfile.htm.md) and [ColorManagementProvider.DestinationProfile](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_ColorManagementProvider_DestinationProfile.htm.md).
 
To set a source color profile in the case of in-place conversion, use the [Bitmap.ColorProfile](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_Bitmap_ColorProfile.htm.md) property. For out-of-place conversion, you can set a default source profile ([ColorConverter.DefaultSourceProfile](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_Transforms_ColorConverter_DefaultSourceProfile.htm.md)), which will be used only if the image has no embedded color profile.
 
```csharp
using (var bitmap = new Bitmap(@"Images\cmyk.jpg"))
using (var cc = new ColorConverter(PixelFormat.Format24bppRgb))
{
    cc.DefaultSourceProfile = ColorProfile.FromSrgb();
    using (var result = cc.Apply(bitmap))
    {
        result.Save(@"Images\Output\out.jpg");
    }
}
```
 
### Image Quantization
 
To convert a bitmap to an indexed pixel format, set the [DestinationPixelFormat](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_Transforms_ColorConverter_DestinationPixelFormat.htm.md) to  ***XXX*Indexed** value. In this case, an appropriate color palette will be automatically created:

- Black and white palette for the [Format1bppIndexed](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_PixelFormat_Format1bppIndexed.htm.md) pixel format.
- Adaptive palette for the [Format4bppIndexed](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_PixelFormat_Format4bppIndexed.htm.md) and [Format8bppIndexed](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_PixelFormat_Format8bppIndexed.htm.md) pixel formats.

 Adaptive palettes are more suitable for quantization of real life images because they are created directly from the original image by picking the most frequent colors. Therefore, using the adaptive palette and dithering produces an indexed image which can nearly match the original. 
To specify dithering parameters, use the [Dithering](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_ColorManagementProvider_Dithering.htm.md) and [DitheringIntensity](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_ColorManagementProvider_DitheringIntensity.htm.md) properties.
 
```csharp
using (var bitmap = new Bitmap(@"Images\in.jpg"))
{
    bitmap.ColorManagement.Dithering = DitheringType.FloydSteinberg;
    bitmap.ColorManagement.DitheringIntensity = 1;

    bitmap.ColorManagement.Convert(PixelFormat.Format8bppIndexed);
    bitmap.Save(@"Images\Output\out.png");
}
```
 
If you need to use another predefined or custom color palette, then you should specify it via the [Palette](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_ColorManagementProvider_Palette.htm.md) property.
 
```csharp
using (var bitmap = new Bitmap(@"Images\in.jpg"))
{
    bitmap.ColorManagement.Palette = new ColorPalette(ColorPaletteType.Windows);
    bitmap.ColorManagement.Convert(PixelFormat.Format8bppIndexed);
    bitmap.Save(@"Images\Output\out.png");
}
```
 
### Color Conversion API Changes
 
The table below shows changes in the color conversion API.
 
|  **PixelFormatConverter** |  Renamed to **ColorConverter**. |
| --- | --- |
 |  **CmykColorProfile**, **RgbColorProfile**, and **GrayScaleColorProfile** |  Renamed to **ColorConverter.DestinationProfile** and **ColorManagementProvider.DestinationProfile**. |
 |  **TargetColorProfile** |  Renamed to [ColorConverter.TargetDeviceProfile](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_Transforms_ColorConverter_TargetDeviceProfile.htm.md) and [ColorManagementProvider.TargetDeviceProfile](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_ColorManagementProvider_TargetDeviceProfile.htm.md). |
 |  **CustomPalette** |  Renamed to [ColorConverter.Palette](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_Transforms_ColorConverter_Palette.htm.md) and **ColorManagementProvider.Palette**. |
 |  **PaletteAlphaTheshold** |  Renamed to [ColorConverter.TransparentIndexThreshold](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_Transforms_ColorConverter_TransparentIndexThreshold.htm.md) and [ColorManagementProvider.TransparentIndexThreshold](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_ColorManagementProvider_TransparentIndexThreshold.htm.md). |
 |  **BackgroundEnabled**, **BuildAdaptivePaletteWithAlpha**, **PaletteAlphaThesholdUsed**, **PaletteEntryCount**, **PaletteType** |  Removed. |
 |  **ColorQuantizationAlgorithm**, **QuantizationTo8bBitsUsed**, **QuantizationTo8bOffset**, **QuantizationTo8bScale** |  Removed. |
 
See the [Color Management and Color Reduction](https://www.graphicsmill.com/docs/gm/color-conversion-and-color-reduction.htm.md) section for details.
 
## Drawing on Images
  
To draw geometric primitives, vector text, or raster data on an image surface, use the [Graphics](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_Drawing_Graphics.htm.md) class:
 
```csharp
using (var bitmap = new Bitmap(@"Images\in.jpg"))
using (var watermark = new Bitmap(@"Images\watermark.png"))
{
    //Watermark image.
    using (var graphics = bitmap.GetGraphics())
    {
        //Draw the semitransparent watermark.
        graphics.DrawImage(watermark, 10, bitmap.Height - watermark.Height - 40, 0.8f);
        //Save the resulting image.
        bitmap.Save(@"Images\Output\out.jpg");
    }
}
```
 
The table below lists the most significant API changes related to drawing functionality.
 
|  **GdiGraphics** |  Renamed to **Graphics**. |
| --- | --- |
 |  **Bitmap.GetGdiGraphics** |  Renamed to [Bitmap.GetGraphics()](https://www.graphicsmill.com/docs/gm/M_Aurigma_GraphicsMill_Bitmap_GetGraphics.htm.md). |
 |  **Bitmap.Draw** |  Renamed to [Bitmap.DrawOn](https://www.graphicsmill.com/docs/gm/O_T_Aurigma_GraphicsMill_Bitmap_DrawOn.htm.md). |
 
See the [Drawing Text and Graphics](https://www.graphicsmill.com/docs/gm/advanced-drawing.htm.md) section for details.
 
## See Also
  
### Manual
 
- [Working with Image Formats](https://www.graphicsmill.com/docs/gm/loading-and-saving-images.htm.md)
- [Transforming Images (Resize, Rotate, Crop)](https://www.graphicsmill.com/docs/gm/transformations-on-images.htm.md)
- [Color Management and Color Reduction](https://www.graphicsmill.com/docs/gm/color-conversion-and-color-reduction.htm.md)
- [Drawing Text and Graphics](https://www.graphicsmill.com/docs/gm/advanced-drawing.htm.md)
- [Processing Large Images](https://www.graphicsmill.com/docs/gm/processing-large-images.htm.md)
