iTextSharp Tutorial SourceForge.net Logo iTextSharp, a Free C#-PDF library

[Home] [Previous] [TOC] [Next] [PDF]

Part I: Simple iText

Chapter 6: Images

The Image object
If you study the API, you will notice that there are several constructors you can use to create an image. However in this tutorial, we will only look at the most simple solution, i.e. by asking the Image object an instance of an Image identified by an URL or a filename:
public static Image getInstance(Uri url)
public static Image getInstance(string filename)

Image is an abstract class, so the getInstance method will detect the type of the given image (GIF, Jpeg, PNG,...) and return an object of type Gif, Jpeg, Png,... Some images will be rejected, please consult the FAQ if you have questions about rejected images.

Getting an instance of an image using an URL
This is the most simple way to add an Image. In example 1, we add a WMF (a Windows Meta File 33kByte), a GIF (a picture of SF-writer Kurt Vonnegut 26 kByte), a Jpeg (a picture of children 7 kByte) and a PNG (a picture of Alfred Hitchcock 16 kByte) to the document, using 3 URLs referring to my site:
Image wmf = Image.getInstance(new URL("../examples/harbour.wmf"));
Image gif = Image.getInstance(new URL("../examples/vonnegut.gif"));
Image jpeg = Image.getInstance(new URL("../examples/myKids.jpg"));
Image png = Image.getInstance(new URL("../examples/hitchcock.png"));

The resulting PDF file is 74 kByte: it contains the image data of the 4 images.

Remark:
Lots of PDF libraries decompress images and change them into a Bitmap-like format before adding them to the PDF-file. There are several reasons why I avoided such an approach:
  • This results in huge PDF files. The size of the resulting file is tens of times larger than the sum of the different images.
  • There is a legal problem: the LZW-algorithm is patented, so I was not allowed to use this algorithm to decompress GIF-files.
I found it much easier to copy the bits of the image file into the PDF file instead of decompressing/compressing the image data (thus avoiding all practical, technical and legal problems).

Getting an instance of an image using a filename
We can change example 1 into example 2 by simply changing the way images are instanciated:
Image gif = Image.getInstance("vonnegut.gif");
Image jpeg = Image.getInstance("myKids.jpg");
Image png = Image.getInstance("hitchcock.png");

The resulting PDF file is identical to the one in example 1, but the images are accessed locally.
This is another example , the resulting PDF.


Positioning the Image
alignment
An image can be aligned, using the method
Alignment = Image.RIGHT
Alignment = Image.MIDDLE
Alignment = Image.LEFT
See example 4 and the resulting PDF: we added the picture of Vonnegut to the right, the picture of my children in the middle and hitchcock to the left.

Images and text
But there's more, you can also specify that text has to be wrapped around the image (see example 5 and the resulting PDF):
Alignment = Image.RIGHT | Image.TEXTWRAP
Alignment = Image.MIDDLE
Alignment = Image.LEFT | Image.UNDERLYING
The text is wrapped on the left side of the Vonnegut-picture, isn't wrapped around the picture of my children and is written over the Hitchcock-image.
Remark: these functionalities still have a lot of bugs.

Absolute positions
When generating PDF-files, you can use the method
public void setAbsolutePosition(int absoluteX, int absoluteY)
to place an image at an absolute position on a page. In example 6 we add two pictures at different coordinates. In the resulting PDF, you can see that the given coordinates are used to position the lowerleft corner of the image. We took the width and height of the image as x- and y-coordinate for the first image and two times these values for the second.


Scaling and Rotating the Image
Scaling
There are several possibilities to scale an image:
public void scaleAbsolute(int newWidth, int newHeight)
public void scalePercent(int percent)
public void scalePercent(int percentX, int percentY)
public void scaleToFit(int fitWidth, int fitHeight)
The picture of the children is 194x202 pixels. If I wanted to make this picture smaller I could scale it using scaleAbsolute(97, 101), but using scalePercent(50) would have the same effect.
I could also reduce it like this: scaleAbsolute(194, 101), this would be the same as doing this: scalePercent(100, 50). All these examples are bundled in example 7, which results in this PDF-document.

Impact on the resolution
If an image is placed without any scaling the the resolution will be 72. If an image is placed with a scaling of 50% the the resolution will be 144. With lower scalings the resolution will increase because the pixels are the same but the size will be smaller. To put a picture with 300dpi use a scaling of 72/300=24%. For instance: if you have a 5X5 inch image that you scan at 300 dpi, the resultant image is 1500X1500 pixels (5X300 = 1500). When you place this image in the pdf with a scaling of 24% (72/300 = 0.24), the image in the pdf will be 5X5 inch with 1500X1500 pixel at 300 dpi. The image will always be 1500X1500 pixel whatever the size.

Rotating
With the following method, you can rotate images:
public void setRotation(double r)
This method is demonstrated in example 8 (see result).


Raw Image data
Uptil now all examples used images that were stored on your harddisk or that were retrieved from some webserver, but it is also possible to get an instance of an image using an array of bytes containing the image data:
public static Image getInstance(byte[] img)
This method has the same effect as the other getInstance-methods discussed earlier: it returns a new Image-object of type Gif, Jpeg or Png.
In example 9, we first add an image that was read from a jpeg-file into an array of bytes. It is evident that in this case it is better to use another getInstance-method, but this is just an example. This getInstance-method is especially useful when you have images that were created 'on the fly', images that were never saved to a file as such.
The example also demonstrates how you can create a Raw Image and use:
public static Image getInstance(int width, int height, int components, int bpc, byte data[])
In the example an image of 100 by 100 pixels is created. The images is 100 x 100 x 3 bytes large, because every pixels is described by a RGB-value. You can see the result of the algorithm in file Chap0609.pdf.


System.Drawing.Bitmap
Example 10 is a very advanced example for three reasons:
  1. In the first place the class System.Drawing.Bitmap is used. This is a class in the .Net Framework and it can be used for a big variety of image-types, for instance TIFF-files, GIF-files that are on the iText list of not supported images,... You will have to check the .Net Framework to see if the image type you need is supported.
  2. Also there is something you may have noticed in the previous examples: it doesn't matter when you add an image, the text is allways on top of your image. In this example we want the image to be on top of the text. That's why we are going to use the class iTextSharp.text.pdf.PdfContentByte (this class will be explained in Chapter 10).
  3. Finally, you will notice that the image used in this example is a transparent gif. Check out the resulting PDF-file.

You will need the image h.gif.

TIFF and CCITT
Example 11  is also rather advanced. This examples convert a tiff-file: 338814-00.tif into a PDF file: Chap0611.pdf.

Image masks
In example 13, we create an image that can be used as mask:
                                        3C
                7E
                E7
                C3
                C3
                E7
                7E
                3C

This image has a size of 8 by 8 pixels, 1 component and 1 byte per component. Using the method makeMask(), it can be turned into a mask:

byte maskr[] = {(byte)0x3c, (byte)0x7e, (byte)0xe7, (byte)0xc3, (byte)0xc3, (byte)0xe7, (byte)0x7e, (byte)0x3c};
Image mask = Image.getInstance(8, 8, 1, 1, maskr);
mask.makeMask();
mask.setInvertMask(true);

We can use this mask for explicit masking to clip some parts of an image:

PdfContentByte cb = writer.DirectContent;
Image image = Image.getInstance("vonnegut.gif");
image.ImageMask = mask;

Or we can use this mask for stencil masking:

PdfContentByte cb = writer.DirectContent;
cb.setRGBColorFill(255, 0, 0);
cb.addImage(mask, mask.scaledWidth() * 8, 0, 0, mask.scaledHeight() * 8, 100, 400);

Please take a look at the resulting PDF.
(for more info on the ContentByte-object read Chapter 10).


Images and other objects
Images inside a Chunk
In some cases it can be handy to wrap an image inside a Chunk. Just create a Chunk with an image and an offset:
Chunk ck = new Chunk(img, 0, -5);
As you can see in example 14 and the resulting PDF, we can add this special image chunk to a phrase, a table,...

You will need the image pngnow.png.

Images inside a Table
You can add an image to a Cell, but because of the technical complexity, you have to take two side-effects into account:

  • The width of a Table is calculated internally. If an image doesn't fit the cell, the image is 'scaled-to-fit' automatically.
  • You can't use Image.TEXTWRAP or Image.UNDERLYING.
See example 15 (Chap0615.pdf).

Annotations and images
If you want a clickable image or you want to add an annotation to an image, you have to construct an Annotation-object and add it to the image. You don't need to specify a position (you can take 0, 0, 0, 0). The position will be internally updated to fit the image:
gif.Annotation = new Annotation(0, 0, 0, 0, "Chap1102b.pdf", 3);
jpeg.Annotation = new Annotation("picture", "These are my children", 0, 0, 0, 0);

This is demonstrated inexample 16 (Chap0616.pdf).




[Top] [Previous] [TOC] [Next] [PDF]