Read and write PDF page boxes

PDF Read Write Advanced

This sample shows how to define print production page boundaries (MediaBox, CropBox, BleedBox, TrimBox, and ArtBox) when writing a 300 DPI PDF, and how to read them back afterwards. It builds a bleed-aware business card layout with PdfWriter and PdfPage, converting real-world sizes to pixels with UnitConverter, then reopens the file with PdfReader to show that CropBox, BleedBox, TrimBox, and ArtBox always come back in points regardless of the page's DPI.

Сode Snippet

public static void Run()
{
    const string pdfPath = "PageBoxes.pdf";
    const float dpi = 300; // A common print resolution.

    // A typical print production layout: the sheet includes bleed, TrimBox is the finished
    // card size, and ArtBox is a safety margin the design shouldn't cross. PdfWriter treats
    // all these box values as pixels at the page's own DPI, so real-world sizes are converted
    // through UnitConverter rather than hardcoded as pixel counts.
    var bleed = UnitConverter.ConvertUnitsToPixels(dpi, 0.125f, Unit.Inch);       // 1/8" bleed
    var safeMargin = UnitConverter.ConvertUnitsToPixels(dpi, 0.1875f, Unit.Inch); // 3/16" safety margin
    var trimWidth = UnitConverter.ConvertUnitsToPixels(dpi, 3.5f, Unit.Inch);     // Business card width
    var trimHeight = UnitConverter.ConvertUnitsToPixels(dpi, 2f, Unit.Inch);      // Business card height
    var hairlineWidth = UnitConverter.ConvertUnitsToPixels(dpi, 0.5f, Unit.Point); // 0.5pt trim guide

    var sheetBox = new System.Drawing.RectangleF(0, 0, trimWidth + (2 * bleed), trimHeight + (2 * bleed));
    var trimBox = new System.Drawing.RectangleF(bleed, bleed, trimWidth, trimHeight);
    var artBox = new System.Drawing.RectangleF(
        trimBox.Left + safeMargin,
        trimBox.Top + safeMargin,
        trimBox.Width - (2 * safeMargin),
        trimBox.Height - (2 * safeMargin));

    using (var writer = new PdfWriter(pdfPath))
    {
        // MediaBox comes from the page size passed here; CropBox and BleedBox share it because
        // the whole sheet, bleed included, is meant to be printed and cut down to TrimBox.
        var page = new PdfPage(sheetBox.Width, sheetBox.Height, dpi, dpi)
        {
            CropBox = sheetBox,
            BleedBox = sheetBox,
            TrimBox = trimBox,
            ArtBox = artBox,
        };

        writer.AddPage(page);

        using (var gr = writer.GetGraphics())
        {
            // Background runs to the edge of the bleed area so no white sliver appears after trimming.
            gr.FillRectangle(new SolidBrush(RgbColor.MidnightBlue), sheetBox.X, sheetBox.Y, sheetBox.Width, sheetBox.Height);

            // A hairline at the trim box shows where the sheet will actually be cut.
            gr.DrawRectangle(new Pen(RgbColor.White, hairlineWidth), trimBox.X, trimBox.Y, trimBox.Width, trimBox.Height);

            // Keep the company name inside the art box, clear of the trim line.
            var font = gr.CreateFont("Arial", 14f);
            var name = new PlainText("Northwind Creative LLC", font, new SolidBrush(RgbColor.White), artBox.Left, artBox.Top + 20f, TextAlignment.Left);
            gr.DrawText(name);
        }
    }

    // Read the same file back. Unlike PdfWriter, PdfReader always reports CropBox, BleedBox,
    // TrimBox, and ArtBox in points regardless of the page's DPI; MediaBox alone is left in the
    // PDF's own bottom-left-origin coordinate system rather than GraphicsMill's.
    using (var reader = new PdfReader(pdfPath))
    {
        var page = reader.Frames[0];

        Console.WriteLine("MediaBox (points): {0}", page.MediaBox);
        Console.WriteLine("CropBox  (points): {0}", page.CropBox);
        Console.WriteLine("BleedBox (points): {0}", page.BleedBox);
        Console.WriteLine("TrimBox  (points): {0}", page.TrimBox);
        Console.WriteLine("ArtBox   (points): {0}", page.ArtBox);
        Console.WriteLine();

        // Converting every box back to inches makes it easy to compare against the physical
        // sizes (3.5x2" trim, 1/8" bleed, 3/16" safe margin) the page was designed with.
        PrintBoxSizeInInches("MediaBox", page.MediaBox, reader.DpiX);
        PrintBoxSizeInInches("CropBox", page.CropBox, reader.DpiX);
        PrintBoxSizeInInches("BleedBox", page.BleedBox, reader.DpiX);
        PrintBoxSizeInInches("TrimBox", page.TrimBox, reader.DpiX);
        PrintBoxSizeInInches("ArtBox", page.ArtBox, reader.DpiX);
    }
}

private static void PrintBoxSizeInInches(string boxName, System.Drawing.RectangleF boxInPoints, float resolution)
{
    var widthInch = UnitConverter.ConvertUnitsToUnits(resolution, boxInPoints.Width, Unit.Point, Unit.Inch);
    var heightInch = UnitConverter.ConvertUnitsToUnits(resolution, boxInPoints.Height, Unit.Point, Unit.Inch);

    Console.WriteLine("{0} size in inches: {1} x {2}", boxName, widthInch, heightInch);
}

Output

PageBoxes.pdf

Download

PageBoxes.png

PageBoxes.txt

MediaBox (points): {X=0,Y=0,Width=269.76,Height=161.76}
CropBox  (points): {X=0,Y=0,Width=269.76,Height=161.76}
BleedBox (points): {X=0,Y=0,Width=269.76,Height=161.76}
TrimBox  (points): {X=8.88,Y=8.87999,Width=252,Height=144}
ArtBox   (points): {X=22.32,Y=22.32001,Width=225.12,Height=117.12}

MediaBox size in inches: 3.746667 x 2.246667
CropBox size in inches: 3.746667 x 2.246667
BleedBox size in inches: 3.746667 x 2.246667
TrimBox size in inches: 3.5 x 2
ArtBox size in inches: 3.126667 x 1.626667

For AI-assisted development: Download Graphics Mill Code Samples XML Catalog