Manipulating Vector Images with Graphics Containers

Graphics Mill allows you to use containers for vector graphics. This topic describes how you can apply these containers.

Creating a GraphicsContainer

The GraphicsContainer class provides an easy way to manipulate vector graphics. It presents storage that can include vector images, bitmaps, texts, and other graphics containers. You can draw such containers on bitmaps or combine them with each other without rasterization.

To start working with vector graphics, you can either create a graphics container from scratch or get it from PSD, PDF, or SVG files. After that, you can draw on it via Graphics returned by the GraphicsContainer.GetGraphics() method. There are three ways to create a graphics container:

Create a GraphicsContainer from Scratch

The following example shows how you can create, draw, and rasterize such a container.

C#
var dpi = 72;

using (var container = new GraphicsContainer(300, 300, dpi, dpi))
using (var graphics = container.GetGraphics())
{
    graphics.DrawLine(new Pen(RgbColor.Red, 3), 100, 100, 150, 250);
    graphics.DrawEllipse(new Pen(RgbColor.Green, 10), new System.Drawing.Rectangle(50, 50, 250, 200));

    using (var bitmap = new Bitmap(400, 400, PixelFormat.Format32bppArgb))
    using (var bitmapGraphics = bitmap.GetAdvancedGraphics())
    {
        // Draw the container on the bitmap twice.
        bitmapGraphics.DrawContainer(container, 0, 0);
        bitmapGraphics.DrawContainer(container, 50, 50);

        bitmap.Save(@"Images\Output\out.png");
    }
}

When you draw a GraphicsContainer on a bitmap by the DrawContainer method, it is rasterized, and you can save it as a raster file.

Convert a PSD Layer

You can use another way to create a GraphicsContainer if you work with PSD files. In this case, the container can be created by the PsdFrameExtensions.ToGraphicsContainer(PsdFrame) static method. A PSD frame represents a layer of a PSD file in Graphics Mill. This method allows you to convert a frame to a new GraphicsContainer.

C#
using (var reader = new PsdReader(@"Images\BusinessCard.psd"))
// Get the first PSD layer, for example.
using (var frame = reader.Frames[0])
{
    if (frame.Type != FrameType.Unknown && frame.Type != FrameType.Group)
    {
        // Put the layer into the container.
        using (var container = PsdFrameExtensions.ToGraphicsContainer(frame))
        using (var bitmap = new Bitmap(frame.Width, frame.Height, PixelFormat.Format32bppArgb, RgbColor.White))
        using (var graphics = bitmap.GetAdvancedGraphics())
        {
            // Draw the container on the bitmap.
            graphics.DrawContainer(container, 0, 0);
            bitmap.Save(@"Images\Output\out.png");
        }
    }
}

Get Content of a PDF or SVG File

Also, PdfReader and SvgReader can create a graphics container for a frame that they have read. In the case of PDFs, these frames represent pages of multipage documents. Let us look at how you can retrieve vector graphics from a PDF file using the PdfReader class.

C#
using (var reader = new PdfReader(@"Images\in.pdf", dpi, dpi))
// Get the first page of the PDF file, for example:
using (var frame = reader.Frames[0])
using (var container = frame.GetContent())
using (var bitmap = new Bitmap(frame.Width, frame.Height, PixelFormat.Format32bppArgb, RgbColor.White))
using (var graphics = bitmap.GetAdvancedGraphics())
{
    // Draw the container on the bitmap.
    graphics.DrawContainer(container, 0, 0);
    bitmap.Save(@"Images\Output\out.jpg");
}

Here, the PdfFrame.GetContent() method returns the GraphicsContainer object that is placed into the container.

Transforming a Graphics Container

Graphics Mill applies transformations to raster and vector images. To transform the content of a graphics container, you can rasterize it through ImageGenerator first. The following example shows how you can read graphics from a PDF file, get vector objects through PdfFrame.GetContent(), and then place them into a graphics container via the Graphics.DrawContainer() method. The ImageGenerator class converts the graphics container into a bitmap that can be used for the transformation later. Here, you run a pipeline to resize the image.

C#
var dpi = 150f;
using (var reader = new PdfReader(@"Images\in.pdf", dpi, dpi))
// Get the first page of the PDF file, for example:
using (var frame = reader.Frames[0])
using (var frameContent = frame.GetContent())
using (var container = new GraphicsContainer(frame.Width, frame.Height, frame.DpiX, frame.DpiY))
using (var graphics = container.GetGraphics())
{
    // Draw vector graphics in the container.
    graphics.DrawContainer(frameContent, 0, 0);

    // Rasterize the container.
    using (var image = new ImageGenerator(container, PixelFormat.Format24bppRgb, RgbColor.Transparent))
    using (var resize = new Resize(100, 0))
    using (var writer = ImageWriter.Create(@"Images\Output\out.png"))
    {
       Pipeline.Run(image + resize + writer);
    }
}

The following example shows transformations of vector images without rasterization. It illustrates how you can downsize the image twice as much as it originally was and then rotate it using the coordinate transformation.

C#
using (var reader = new PdfReader(@"Images\in.pdf", dpi, dpi))
using (var frame = reader.Frames[0])
using (var container = frame.GetContent())
using (var writer = new PdfWriter(@"Images\Output\out.pdf"))
{
    var resizeK = 0.5f;

    writer.AddPage((int)(frame.Height * resizeK), (int)(frame.Width * resizeK),
        dpi, dpi, RgbColor.White, null);

    using (var graphics = writer.GetGraphics())
    {
        graphics.Transform.Scale(resizeK, resizeK);
        graphics.Transform.Rotate(90f);
        graphics.Transform.Translate(0, -frame.Height);

        graphics.DrawContainer(container, 0, 0);
    }
}

Working with Files

Graphics Mill supports three file formats of vector graphics. These are PDF, SVG, and EPS. You can read from PDF and SVG using the PdfReader and SvgReader classes. Also, you can write to PDF, SVG, and EPS using the PdfWriter, SvgWriter, and EpsWriter classes, correspondingly.

The previous examples in this topic show how you can apply PdfReader and PdfWriter.

Saving vector graphics into an SVG file is completely the same as saving into EPS. So, let us illustrate how you can do it using SvgWriter. In the following example, you convert a PDF to an SVG file and draw some watermark text on it.

C#
var dpi = 72;
using (var reader = new PdfReader(@"Images\in.pdf", dpi, dpi))
using (var container = reader.Frames[0].GetContent())
using (var writer = new SvgWriter(@"Images\Output\out.svg", 400, 400, dpi, dpi))
using (var graphics = writer.GetGraphics())
{
    graphics.DrawContainer(container, 0, 0);
    graphics.DrawText(new PlainText("Graphics Mill", FontRegistry.Installed.CreateFont("Arial", 12, dpi, dpi), 50, 50));
}

Now, open the out.svg file in an editor, in Inkscape for example, and verify that the file contains path elements for text objects and graphical primitives, and an image element for raster images.

The saved SVG file in Inkscape.

Color Management

Graphics containers may include elements in different color spaces. For example, there may be a bitmap image in the CMIK color space and graphical primitives in RGB. So, which color space should be used to rasterize the container?

Graphics Mill provides the GraphicsContainer.GetPreferredPixelFormat() and GraphicsContainer.GetPreferredColorProfile() methods to resolve this problem. The first one gets the most preferred PixelFormat for elements in the container, and the second method returns ColorProfile for given pixel format. The following example shows how you can apply these methods.

C#
using (var reader = new PdfReader(@"Images\in.pdf", dpi, dpi))
using (var frame = reader.Frames[0])
using (var content = frame.GetContent())
using (var bitmap = new Bitmap(frame.Width, frame.Height, content.GetPreferredPixelFormat()
    , RgbColor.White))
{
    bitmap.ColorProfile = content.GetPreferredColorProfile(bitmap.PixelFormat.ColorSpace);

    using (var graphics = bitmap.GetAdvancedGraphics())
    {
        graphics.DrawContainer(content, 0f, 0f);
    }

    bitmap.Save(@"Images\Output\out.tif");
}

See Also

Reference

Manual