- About Graphics Mill
- What's New?
- Breaking Changes in Graphics Mill 12
- Breaking Changes in Graphics Mill 11
- Features
- Supported File Formats
- System Requirements
- Getting Started
- Your First Application with Graphics Mill
- Understanding Image Processing Approaches in Graphics Mill
- Evaluating Graphics Mill
- Registering Production License Keys
- Upgrading from Graphics Mill 5
- Installation and Redistribution Notices
- Graphics Mill Configuration
- Using Graphics Mill with Microsoft Azure
- Using Graphics Mill in .NET projects
- Working with Image Formats
- Transforming Images (Resize, Rotate, Crop)
- Working with Metadata
- Color Management and Color Reduction
- Drawing Text and Graphics
- Color Keying (Green Screen Removal)
- Channels and Pixel Data
- Color and Tone Correction
- Working with Photoshop (PSD) Files
- Image Filters
- Processing Large Images
- Basics of Image Processing
- Troubleshooting
- Class Library Reference
- Licensing
- End User License Agreement
- Copyright Notices
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
- Transforming Images
- Converting Colors
- 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.
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 topic for a detailed description of the differences between a bitmap and pipeline.
Working with Bitmaps
The Bitmap 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 class:
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. This class doesn't affect image data or attributes, it just converts spatial parameters to different units.
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 and DpiY. |
| Bitmap.IsCmyk, Bitmap.IsGrayScale, Bitmap.IsRgb, Bitmap.IsIndexed, Bitmap.IsExtended | Removed. Use PixelFormat.IsCmyk, PixelFormat.IsGrayscale, PixelFormat.IsRgb, PixelFormat.IsIndexed, PixelFormat.IsExtended instead. |
| Bitmap.BitsPerPixel | Removed. Use PixelFormat.Size instead. |
Loading and Saving Images
Using the Bitmap Class
To load an image using the Bitmap class, use constructors. Note, the Bitmap.Load and Bitmap.LoadThumbnail methods have been eliminated. To save the Bitmap, use the Save methods. To pass output parameters (compression type, quality, etc.) use an appropriate WriterSettings class descendant. For example, use the JpegSettings for saving JPEG files, PngSettings - for PNG, etc.
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 section for details.
To read multipage image files (GIF, TIFF, etc.) frame by frame, use the ImageReader.Frames property. To retrieve a bitmap from a frame, use the Frame.GetBitmap() method.
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:
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, Iptc, AdobeResources, and Xmp properties of the ImageReader class.
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.
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 and TiffSettings classes. You should create an instance of the corresponding class, initialize its properties with references to metadata, and pass it to the Save method.
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 namespace.
| FormatReader/FormatWriter | Renamed to ImageReader/ImageWriter. |
| XXXEncoderOptions | Renamed to XXXSettings. |
| AdvancedPsdXXX and PsdXXX | Merged and moved to Aurigma.GraphicsMill.Codecs.Psd namespace. |
| AviXXX , DSXXX , Jpeg2kXXX , PcxXXX , QTXXX , SwfXXX , WbmpXXX , WMXXX | Removed. |
See the Working with Image Formats and Working with Metadata 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 and Bitmap.ColorAdjustment properties:
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 namespace:
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. |
| RotateAndFlip | Split into Rotate and Flip. |
| InterpolationMode | Split into InterpolationMode and ResizeInterpolationMode. |
| Curves, Glow, PageCurl, SwapChannels, Swirl, Waddle, WaterDrop, Wave | Removed. |
See the Transforming Images (Resize, Rotate, Crop) 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 property:
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 class:
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 and ColorManagementProvider.DestinationProfile.
To set a source color profile in the case of in-place conversion, use the Bitmap.ColorProfile property. For out-of-place conversion, you can set a default source profile (ColorConverter.DefaultSourceProfile), which will be used only if the image has no embedded color profile.
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 to XXXIndexed value. In this case, an appropriate color palette will be automatically created:
- Black and white palette for the Format1bppIndexed pixel format.
- Adaptive palette for the Format4bppIndexed and Format8bppIndexed pixel formats.
To specify dithering parameters, use the Dithering and DitheringIntensity properties.
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 property.
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 and ColorManagementProvider.TargetDeviceProfile. |
| CustomPalette | Renamed to ColorConverter.Palette and ColorManagementProvider.Palette. |
| PaletteAlphaTheshold | Renamed to ColorConverter.TransparentIndexThreshold and ColorManagementProvider.TransparentIndexThreshold. |
| BackgroundEnabled, BuildAdaptivePaletteWithAlpha, PaletteAlphaThesholdUsed, PaletteEntryCount, PaletteType | Removed. |
| ColorQuantizationAlgorithm, QuantizationTo8bBitsUsed, QuantizationTo8bOffset, QuantizationTo8bScale | Removed. |
See the Color Management and Color Reduction section for details.
Drawing on Images
To draw geometric primitives, vector text, or raster data on an image surface, use the Graphics class:
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(). |
| Bitmap.Draw | Renamed to Bitmap.DrawOn. |
See the Drawing Text and Graphics section for details.