Create PDF Optional Content Groups (OCG) using PDF objects in C# and VB.NET

PDF Layers, most commonly known as Optional Content Groups (OCGs), are the sections of content in a PDF document that users can view or hide. This feature is useful for grouping PdfContentElements, such as images, notes, and other graphic elements. The most common use cases are layered artwork and the production of documents in multiple languages.

After grouping elements, OCGs let users control their visibility based on conditions such as whether the user is viewing the document on-screen, printing it, or through user interaction. It’s also important to highlight that these PDF layers can be jointly transformed and/or clipped without affecting the rest of the content.

When creating a PDF OCG in C# or VB.NET, we can represent it with the PdfContentGroup class.

Do you want to learn how to create layers in pdf? The example below can help you create any group you need. It also shows how transformation and clipping applied to an optional content group do not affect the content outside of it.

PDF optional content groups (ocg) created with GemBox.Pdf C#/VB.NET library
Screenshot of PDF optional content groups (PDF layers) created with GemBox.Pdf library
using GemBox.Pdf;
using GemBox.Pdf.Content;

class Program
{
    static void Main()
    {
        // If using Professional version, put your serial key below.
        ComponentInfo.SetLicense("FREE-LIMITED-KEY");

        using (var document = new PdfDocument())
        {
            var page = document.Pages.Add();

            // Add a rectangle with a green fill whose bottom-left corner is at location (100, 450) from the bottom-left corner of the page.
            var path = page.Content.Elements.AddPath();
            path.AddRectangle(100, 450, 200, 100);
            var format = path.Format;
            format.Fill.IsApplied = true;
            format.Fill.Color = PdfColors.Green;

            // Add an outer group whose bottom-left corner is at the same location as the page's bottom-left corner.
            var outerGroup = page.Content.Elements.AddGroup();
            // Add an inner group whose bottom-left corner is at location (100, 250) from the bottom-left corner of the outer group/page.
            var innerGroup = outerGroup.Elements.AddGroup();
            innerGroup.Transform = PdfMatrix.CreateTranslation(100, 250);

            // Add a rectangle that clips its content and the content of all elements that come after it in the same group.
            // The bottom-left corner of the clipping rectangle is at location (50, -150) from the bottom-left corner of the inner group.
            // The clipping rectangle is also stroked to show that it goes over the first and the last rectangle from the main content group, but it doesn't clip them because they are in the main content group.
            var clippingPath = innerGroup.Elements.AddPath();
            clippingPath.AddRectangle(50, -150, 100, 400);
            format = clippingPath.Format;
            format.Clip.IsApplied = true;
            format.Stroke.IsApplied = true;
            format.Stroke.Width = 2;
            format.Stroke.DashPattern = PdfLineDashPatterns.Dash;

            // Add a rectangle with a red fill that gets clipped by the previous rectangle, thus making it a square.
            // The bottom-left corner is at the same location as the inner group's bottom-left corner.
            var clippedPath = innerGroup.Elements.AddPath();
            clippedPath.AddRectangle(0, 0, 200, 100);
            format = clippedPath.Format;
            format.Fill.IsApplied = true;
            format.Fill.Color = PdfColors.Red;

            // Add the same rectangle as the first one and move it down by 400 points.
            path = page.Content.Elements.AddClone(path);
            path.Subpaths.Transform(PdfMatrix.CreateTranslation(0, -400));

            document.Save("ContentGroups.%OutputFileType%");
        }
    }
}
Imports GemBox.Pdf
Imports GemBox.Pdf.Content

Module Program

    Sub Main()

        ' If using Professional version, put your serial key below.
        ComponentInfo.SetLicense("FREE-LIMITED-KEY")

        Using document = New PdfDocument()

            Dim page = document.Pages.Add()

            ' Add a rectangle with a green fill whose bottom-left corner is at location (100, 450) from the bottom-left corner of the page.
            Dim path = page.Content.Elements.AddPath()
            path.AddRectangle(100, 450, 200, 100)
            Dim format = path.Format
            format.Fill.IsApplied = True
            format.Fill.Color = PdfColors.Green

            ' Add an outer group whose bottom-left corner is at the same location as the page's bottom-left corner.
            Dim outerGroup = page.Content.Elements.AddGroup()
            ' Add an inner group whose bottom-left corner is at location (100, 250) from the bottom-left corner of the outer group/page.
            Dim innerGroup = outerGroup.Elements.AddGroup()
            innerGroup.Transform = PdfMatrix.CreateTranslation(100, 250)

            ' Add a rectangle that clips its content and the content of all elements that come after it in the same group.
            ' The bottom-left corner of the clipping rectangle is at location (50, -150) from the bottom-left corner of the inner group.
            ' The clipping rectangle is also stroked to show that it goes over the first and the last rectangle from the main content group, but it doesn't clip them because they are in the main content group.
            Dim clippingPath = innerGroup.Elements.AddPath()
            clippingPath.AddRectangle(50, -150, 100, 400)
            format = clippingPath.Format
            format.Clip.IsApplied = True
            format.Stroke.IsApplied = True
            format.Stroke.Width = 2
            format.Stroke.DashPattern = PdfLineDashPatterns.Dash

            ' Add a rectangle with a red fill that gets clipped by the previous rectangle, thus making it a square.
            ' The bottom-left corner is at the same location as the inner group's bottom-left corner.
            Dim clippedPath = innerGroup.Elements.AddPath()
            clippedPath.AddRectangle(0, 0, 200, 100)
            format = clippedPath.Format
            format.Fill.IsApplied = True
            format.Fill.Color = PdfColors.Red

            ' Add the same rectangle as the first one and move it down by 400 points.
            path = page.Content.Elements.AddClone(path)
            path.Subpaths.Transform(PdfMatrix.CreateTranslation(0, -400))

            document.Save("ContentGroups.%OutputFileType%")
        End Using
    End Sub
End Module

Want more?

Next example GitHub

Check the next example or select an example from the menu. You can also download our examples from the GitHub.


Like it?

Download Buy

If you want to try the GemBox.Pdf yourself, you can download the free version. It delivers the same performance and set of features as the professional version, but with some operations limited. To remove the limitation, you need to purchase a license.