Chapter 5: Image and Graphics Objects

Contents

5.1 PdfImage Object

AspPDF.NET is capable of placing arbitrary images on a PDF document. It supports images in BMP, GIF, JPEG, PNG and TIFF formats. To display an image on a canvas, the method PdfCanvas.DrawImage should be used. This method expects two arguments, an instance of the PdfImage object and a parameter object (or parameter string).

A PdfImage object is created via PdfDocument's OpenImage method which takes an image path as an argument. PdfImage can also be created via the OpenImageBinary method which opens an image from memory. Once an instance of PdfImage is created, it can be displayed multiple times across a PDF document.

The following code segment displays the image painting.jpg three times on a page with various scaling factors:

void Page_Load(Object Source, EventArgs E)
{
PdfManager objPdf = new PdfManager();

// Create empty document
PdfDocument objDoc = objPdf.CreateDocument();

// Add a new page
PdfPage objPage = objDoc.Pages.Add();

// Open image
PdfImage objImage = objDoc.OpenImage( Server.MapPath( "painting.jpg") );

// Create empty param object
PdfParam objParam = objPdf.CreateParam();

for( int i = 1; i <=3; i++ )
{
  objParam["x"] = (objPage.Width - objImage.Width / i) / 2.0f;
  objParam["y"] = objPage.Height - objImage.Height * i / 2.0f - 200;
  objParam["ScaleX"] = 1.0f / i;
  objParam["ScaleY"] = 1.0f / i;
  objPage.Canvas.DrawImage( objImage, objParam );
}

// Save document, the Save method returns generated file name
string strFilename = objDoc.Save( Server.MapPath("image.pdf"), false );
lblResult.Text = "Success! Download your PDF file <A TARGET=_new HREF=" + strFilename + ">here</A>";
}
Sub Page_Load(Source As Object, E As EventArgs)

Dim objPdf As PdfManager = New PdfManager()

' Create empty document
Dim objDoc As PdfDocument = objPdf.CreateDocument()

' Add a new page
Dim objPage As PdfPage = objDoc.Pages.Add()

' Open image
Dim objImage As PdfImage = objDoc.OpenImage( Server.MapPath( "painting.jpg") )

' Create empty param object
Dim objParam As PdfParam = objPdf.CreateParam()

For i As integer = 1 To 3
  objParam("x") = (objPage.Width - objImage.Width / i) / 2.0f
  objParam("y") = objPage.Height - objImage.Height * i / 2.0f - 200
  objParam("ScaleX") = 1.0f / i
  objParam("ScaleY") = 1.0f / i
  objPage.Canvas.DrawImage( objImage, objParam )
Next

' Save document, the Save method returns generated file name
Dim strFilename As String = objDoc.Save( Server.MapPath("image.pdf"), false )
lblResult.Text = "Success! Download your PDF file <A TARGET=_new HREF=" + strFilename + ">here</A>"
End Sub

Here, we pass four arguments to the DrawImage method: X, Y, ScaleX and ScaleY. X and Y are required: they specify the coordinates of the lower-left corner of the image being displayed.

ScaleX and ScaleY are optional: they specify scaling factors along the X and Y coordinates. Both arguments are 1 by default, which means the image size on the page (in user coordinates) will be equal to its pixel size, provided that the image resolution is the standard 72 dots per inch (dpi). For example, if a 72dpi image is 360 x 216 pixels and the ScaleX/ScaleY arguments are not specified, the image will occupy 360 x 216 units of space, or 5" x 3". A 300dpi image with the same pixel size will only occupy 1.2" x .72".

You can optionally specify a rotation Angle (in degrees) by which the image will be rotated counter-clockwise around its lower-left corner.

Click on the links below to run this code sample:

The overloaded OpenImage(byte[]) method opens an image from a memory array as opposed to disk. This method can be used if the image being opened is stored in a database table as a blob:

PdfImage objImage = objDoc.OpenImage( rs["image_blob"] );

5.2.1 Image-to-PDF Conversion

The PdfImage properties ResolutionX and ResolutionY enable conversion of GIF, JPEG, BMP, PNG and TIFF images to one-page PDF documents with the size and resolution of the original image fully preserved. These properties return the dot-per-inch (DPI) resolutions of an image along the X and Y coordinates. For GIF, PNG and BMP images, these values are always 72 dpi, the resolution of JPEG and TIFF images may vary and usually ranges from 72 to 600 dpi.

The following code fragment converts an arbitrary image into a one-page PDF document with the page size calculated based on the size and resolution of the image being converted:

...
// Open image from file
PdfImage objImage = objDoc.OpenImage(Server.MapPath( "atlanticocean.tif" ) );

// Add empty page. Page size is based on resolution and size of image
float fWidth = objImage.Width * 72.0f / objImage.ResolutionX;
float fHeight = objImage.Height * 72.0f / objImage.ResolutionY;
PdfPage objPage = objDoc.Pages.Add( fWidth, fHeight );

// Draw image
objPage.Canvas.DrawImage( objImage, "x=0, y=0" );
...
...
' Open image from file
Dim objImage As PdfImage = objDoc.OpenImage(Server.MapPath( "atlanticocean.tif" ) )

' Add empty page. Page size is based on resolution and size of image
Dim fWidth As Single = objImage.Width * 72.0f / objImage.ResolutionX
Dim fHeight As Single = objImage.Height * 72.0f / objImage.ResolutionY
Dim objPage As PdfPage = objDoc.Pages.Add( fWidth, fHeight )

' Draw image
objPage.Canvas.DrawImage( objImage, "x=0, y=0" )
...

5.2 Masking and Transparency

Usually, an image completely covers an area it occupies. All portions of the image, whether black, white, gray or color, completely obscure any marks that may previously have existed in the same place on the page.

However, it is possible to crop, or "mask out" the background of an image and then place the masked image on a different background, allowing the existing background to show through the masked areas. Two masking methods are available: explicit masking using a separate image, and color key masking.

5.2.1 Explicit Masking

This method requires a separate monochrome image which serves as an image mask. Such an image can be created using the Microsoft Paint application (included in all versions of Windows). Copy an image you need masked into Paint, change its attribute to Black and White, then save it as a monochrome bitmap. White areas of the bitmap will mask out the corresponding pixels of the image being masked.

An image is masked as follows:

1. The monochrome mask image is opened with OpenImage, then its IsMask property is set to True.

2. The image to be masked is opened with OpenImage also, then its SetImageMask method is called and the image object obtained in Step 1 is passed as an argument.

The following code sample takes the image exclam.gif and its monochrome bitmap mask exclam.bmp, and places the image on top of a drawing to demonstrate that the existing background is showing through the masked areas.

...
// Open image to become the mask. This has to be a monochrome bitmap
PdfImage objImageMask = objDoc.OpenImage( Server.MapPath( "exclam.bmp") );
objImageMask.IsMask = true; // Mark this image object as a mask

// Open image to be masked
PdfImage objImage = objDoc.OpenImage( Server.MapPath( "exclam.gif") );
objImage.SetImageMask( objImageMask );

// Draw masked image
objPage.Canvas.DrawImage( objImage, "x=10, y=550" );
...
...
' Open image to become the mask. This has to be a monochrome bitmap
Dim objImageMask As PdfImage = objDoc.OpenImage( Server.MapPath( "exclam.bmp") )
objImageMask.IsMask = True ' Mark this image object as a mask

' Open image to be masked
Dim objImage As PdfImage = objDoc.OpenImage( Server.MapPath( "exclam.gif") )
objImage.SetImageMask( objImageMask )

' Draw masked image
objPage.Canvas.DrawImage( objImage, "x=10, y=550" )
...

Click on the links below to run this code sample:

5.2.2 Color Key Masking

An alternative way to mask an image is by specifying a range of colors to mask. All samples (a PDF term roughly equivalent to "pixels") of the image with color components falling within the specified range are masked (not painted).

A color range is an array of 2 x N integers where N is the number of color components per sample. N is 3 for RGB images, 4 for CMYK images, and 1 for monochrome bitmaps.

Each integer in the array must be between 0 and 2 BitsPerComponent - 1. The BitsPerComponent value may be 1, 2, 4, or 8 depending on the image. Use PdfImage properties ComponentsPerSample and BitsPerComponent to know exactly what these values are for your image.

To specify a color key mask, the PdfImage provides the method SetColorMask which takes a parameter object (or parameter string) as an argument. The parameters in the parameter object must be named Min1, Max1, Min2, Max2, ..., MinN, MaxN.

For example, the image exclam.gif used in the previous section is a GIF, so its ComponentsPerSample is 3 and BitsPerComponent is 8. To set a mask, we need to specify three ranges, or 6 integers each between 0 and 255. Therefore, to mask the white and light gray areas of this image, we may use the following code:

objImage.SetColorMask( "Min1=250;Max1=255; Min2=250;Max2=255; Min3=250;Max3=255" );

Here, we specify three ranges for each of the R, G, and B color components. The ranges are between 250 and 255 which corresponds to white and very light gray.

5.2.3 GIF & PNG Transparency Support

AspPDF.NET provides full transparency support for GIF and PNG images. The transparent areas of GIF and PNG images are automatically masked. PNG alpha channels are also supported.

5.2.4 TIFF Transparency Support

As of Version 3.4.0.33278, AspPDF.NET supports alpha information contained in TIFF images the same way as with PNG images.

5.3 PdfGraphics Object

Sometimes, a composite graphics object comprised of drawings, text and images, such as a company's logo and slogan on a background, needs to be displayed in multiple places and on multiple pages within a PDF document, possibly with various scaling factors.

PDF specifications describe such self-contained, complex entities under the name Form XObjects but to avoid confusion with interactive forms described in Chapter 11, AspPDF.NET refers to them as graphics objects.

5.3.1 PdfGraphics Object Overview

AspPDF.NET provides support for graphics entities via the PdfGraphics object creatable via PdfDocument's CreateGraphics method. A graphics object has a fixed size specified at creation time, but it can be scaled and rotated when displayed via the Cavas.DrawGraphics method, the same way as an image.

PdfGraphics has an associated PdfCanvas object accessible via the Canvas property much the same way as PdfPage. Therefore, a graphics object may contain drawings, images, text and other graphics objects.

PdfGraphics objects may be used stand-alone to help display repetitive graphics entities. They can also be used to define the appearance of annotations and form fields described in later chapters.

The code sample below creates an instance of PdfGraphics, draws a mathematically defined shape on it, and also draws a string of text. After that, the graphics is drawn on the page multiple times with rotation around the center of the page.

...
// Create a new Graphics object
PdfGraphics objGraphics = objDoc.CreateGraphics( "Left=0, Bottom = 0; Right=100; Top=100" );

// Create a drawing
objGraphics.Canvas.DrawRect( 1, 1, 99, 99 );
objGraphics.Canvas.MoveTo( 50, 90 );
for( int i = 0; i <= 628; i++ )
{
  objGraphics.Canvas.LineTo( (float)(40 * Math.Sin(i / 25.0) + 50),
    (float)(40 * Math.Cos(i / 20.0) + 50) );
}
objGraphics.Canvas.Fill();

objGraphics.Canvas.DrawText( "AspPDF.NET Rules!", "x=10, y=12; size=8", objDoc.Fonts["Courier"] );

// Create empty Param object
PdfParam objParam = objPdf.CreateParam();

// Display graphics with rotation
for(int angle = 0; angle <= 330; angle +=30 )
{
  objParam["x"] = (float)(306 + 150.0 * Math.Cos( angle / 360.0 * 6.28 ) );
  objParam["y"] = (float)(396 + 150.0 * Math.Sin( angle / 360.0 * 6.28 ) );
  objParam["Angle"] = angle;

  objPage.Canvas.DrawGraphics( objGraphics, objParam );
}
...
...
' Create a new Graphics object
Dim objGraphics As PdfGraphics = objDoc.CreateGraphics( "Left=0, Bottom = 0; Right=100; Top=100" )

' Create a drawing
objGraphics.Canvas.DrawRect( 1, 1, 99, 99 )
objGraphics.Canvas.MoveTo( 50, 90 )
For i As Integer = 0 To 628
  objGraphics.Canvas.LineTo( 40 * Math.Sin(i / 25.0) + 50, 40 * Math.Cos(i / 20.0) + 50 )
Next

objGraphics.Canvas.Fill()

objGraphics.Canvas.DrawText( "AspPDF.NET Rules!", "x=10, y=12; size=8", objDoc.Fonts("Courier") )

' Create empty Param object
Dim objParam As PdfParam = objPdf.CreateParam()

' Display graphics with rotation
For angle As Integer = 0 To 330 Step 30

  objParam("x") = 306 + 150.0 * Math.Cos( angle / 360.0 * 6.28 )
  objParam("y") = 396 + 150.0 * Math.Sin( angle / 360.0 * 6.28 )
  objParam("Angle") = angle

  objPage.Canvas.DrawGraphics( objGraphics, objParam )
Next
...

Click on the links below to run this code sample:

5.3.2 Tiling Patterns

Update: As of Version 3.5, there is a more versatile way to create patterns, via the PdfDocument.CreatePattern method. This functionality is described in Section 16.5 - Patterns and Shadings.

A tiling pattern consists of a small graphical figure called a pattern cell. Filling an area with the pattern replicates the cell vertically and horizontally within this area.

AspPDF.NET supports tiling patterns via the method PdfCanvas.FillWithPattern which expects an instance of the PdfGraphics object representing the pattern cell to be used. The 2nd optional argument, EvenOdd, is the same as in the PdfCanvas.Fill method. To designate an instance of the PdfGraphics object as a pattern cell, the CreateGraphics method must be called with the parameter Pattern=true.

The following code snippet fills a circular area with a pattern consisting of a single small image:

PdfImage objImage = objDoc.OpenImage(@"c:\path\airplane_icon.gif");
PdfGraphics objGraph = pbjDoc.CreateGraphics("left=0; bottom=0; right=42;top=45; pattern=true;");
objGraph.Canvas.DrawImage( objImage, "x=0, y=0" );

// Create path, fill it with the pattern
objPage.Canvas.AddEllipse( 300, 200, 100, 100 );
objPage.Canvas.FillWithPattern( objGraph );
...

5.3.3 Creating Graphics from Pages

As of Version 2.3, a PdfGraphics object can be created from the page of another existing document and then drawn on this document one or more times with shifting, scaling and rotation applied, if necessary. This functionality is provided via the method PdfDocument.CreateGraphicsFromPage and described in detail in Section 9.6 - Drawing Other Documents' Pages.