iText Tutorial
|
|
iText, a Free Java-PDF library
by Bruno Lowagie
|
[Home] |
[Previous] |
[TOC] |
[Next] |
[PDF] |
Part I: Simple iText
Chapter 6: Images
Remark: in contrast to some other PDF libraries, there are no special X requirements
for running iText on a Unix box, except when you are adding a java.awt.Image.
|
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(URL url) throws BadElementException, MalformedURLException, IOException
public static Image getInstance(String filename) throws BadElementException, MalformedURLException, IOException
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 my 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. The resulting HTML file is 1 kByte: it contains
the references to the urls 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.
- In order to be able to use such a library, you often need to change some
UNIX configurations (X11).
- 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 there is a big difference in the resulting HTML file.
If we study the source code, we can immediately see what causes the problem:
<IMG BORDER="0" HEIGHT="149" SRC="file:/D:/cvs/lib/vonnegut.gif" WIDTH="198">
I generated the HTML file on the D:-drive of my NT workstation and afterwards I put
this file on my LINUX webserver. It is evident that the links to my local D:-drive
are broken (or isn't it: I see lots of similar errors on amateur webpages).
You can avoid this problem by telling the HtmlWriter
to use a given basepath for images:
HtmlWriter writer = HtmlWriter.getInstance(document, new FileOutputStream("Chap0603.html"));
writer.setImagepath("../../images/kerstmis/");
In this example, we tell the writer to use a relative
path (in this case the path to some Christmas photo's)
for every image we add. This is the resulting PDF and
HTML.
|
Positioning the Image
alignment
An image can be aligned, using the method
setAlignment(Image.RIGHT)
setAlignment(Image.MIDDLE)
setAlignment(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):
setAlignment(Image.RIGHT | Image.TEXTWRAP)
setAlignment(Image.MIDDLE)
setAlignment(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 my 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.
Finally, there is also the ScaleToFit-method.
This method is used in the Calendar-class.
It reduces the image, preserving the original aspect ratio. In the
Calendar-application,
this method is used to allow you to put images of different size on each
Calendar-page. They are all resized to Fit on a certain area of the page.
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.
|
java.awt.Image
Example 10 is a very advanced example for three reasons:
- In the first place the
class java.awt.Image is used. This is a class in the JDK 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 JDK to see if the image type you need
is supported.
- 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
com.lowagie.text.pdf.PdfContentByte (this class will be explained in
Chapter 10).
-
Finally, you will notice that the image used in this example is a transparent gif.
Check out the resulting PDF-file.
|
TIFF and CCITT
Example 11 and
example 12 are also
rather advanced. These examples convert two tiff-files:
338814-00.tif and
12.tif into a PDF file:
Chap0612.pdf and
Chap0612.pdf.
You need the Java Advanced Imaging API
from SUN in order to compile and execute these examples. More specific: you need to add two extra jars to your classpath:
jai_codec.jar and jai_core.jar. You can find these jars at http://java.sun.com/.
|
Image masks
In example 13, we create an image that can be used as mask:
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.getDirectContent();
Image image = Image.getInstance("vonnegut.gif");
image.setImageMask(mask);
Or we can use this mask for stencil masking:
PdfContentByte cb = writer.getDirectContent();
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,...
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.setAnnotation(new Annotation(0, 0, 0, 0, "Chap1102b.pdf", 3));
jpeg.setAnnotation(new Annotation("picture", "These are my children", 0, 0, 0, 0));
This is demonstrated inexample 16
(Chap0616.pdf).
|
[Top] |
[Previous] |
[TOC] |
[Next] |
[PDF] |
Page Updated: $Date: 2003/06/25 07:36:35 $
Copyright © 2000, 2001 by Bruno Lowagie
|
Adolf Baeyensstraat 121, 9040 Gent, BELGIUM,
tel +00 32 92 28 10 97 mailto:itext-questions@lists.sourceforge.net
|
|