Description:-
iTextSharp
supports all the main image types: jpg, tif, gif, bmp, png and wmf. There are a
number of ways to create images with iTextSharp using the Image.GetInstance()
method. Probably the most used option will be to pass a filesystem path and
file name into the method:
string pdfpath = Server.MapPath("PDFs");
string imagepath = Server.MapPath("Images");
Document doc = newDocument();
try
{
PdfWriter.GetInstance(doc, newFileStream(pdfpath + "/Images.pdf", FileMode.Create));
doc.Open();
//New
doc.Add(newParagraph("GIF"));
iTextSharp.text.Image gif = iTextSharp.text.Image.GetInstance(imagepath + "/ajax-loader(1).gif");
doc.Add(gif);
}
catch (Exception ex)
{
//Log error;
}
finally
{
doc.Close();
}
Alternative
constructors that you may use include passing a URL or a System.Drawing.Image
object (as opposed to an iTextSharp.text.Image). Note - the following snippet
that System.Drawing.Image.FromStream() method shows the use of namespace
aliasing again (sd.Image.FromStream(fs)), as was highlighted to avoid clashes
with the two different types of Image object:
doc.Add(newParagraph("JPG"));
string url = @"D:\Done\AnimationChart\AnimationChart\Images\Jellyfish.jpg";
iTextSharp.text.Image jpg = iTextSharp.text.Image.GetInstance(newUri(url));
jpg.ScaleToFit(250f, 100f);
doc.Add(jpg);
doc.Add(newParagraph("PNG"));
using (FileStreamfs = new FileStream(imagepath + "/vuserpic_1.png", FileMode.Open))
{
iTextSharp.text.Imagepng = iTextSharp.text.Image.GetInstance(System.Drawing.Image.FromStream(fs), ImageFormat.Png);
doc.Add(png);
}
It's
difficult to tell from the images I have provided so far, but the resolution of
the resulting images in the PDF file is not that great. By default, images are
embedded at 72 dpi (Dots Per Inch) which coincidentally, matches the number of
points in an inch. If this file was being prepared for printing, the final job
would be a bit nasty. Generally, commercial printers require that colour images
for printing have a resolution of 300 dpi. To achieve this, you can scale the
image to 24%. What you are actually trying to do is squeeze 300 pixels into the
space that 72 normally occupies. 72/300 * 100 = 24%. The image stays the same
in terms of file size but occupies less space in the document.
doc.Add(newParagraph("TIF Scaled to 300dpi"));
iTextSharp.text.Imagetif = iTextSharp.text.Image.GetInstance(imagepath + "/WelcomeFax.tif");
tif.ScalePercent(24f);
doc.Add(tif);
Now,
I have a large tif file that I want to use as a logo on an A4 letterhead. It
measures 300 x 890 pixels. So at the default 72 dpi, it will measure 4.17
inches wide by12.36 inches deep. Increasing the resolution to 300 dpi will
reduce the width to 1 inch, and the depth to 2.97 inches (72 points by 213.6
points). That part is fine. We can do that using the code above. Now I want to
place the 300 dpi image in a particular position on the page. I have in mind
the top right hand corner. The SetAbsolutePosition() method will do this, but I
need to get a calculator out.
SetAbsolutePosition()
accepts 2 floats as parameters. The first represents the co-ordinate along the
X-axis, which starts at the left hand edge of the document and finishes at the
right hand edge of the document. The second represents the Y-axis co-ordinate
which starts from the bottom of the document and goes to the top. An A4
document is 595 points wide and 842 pixels high with a 36 point margin all
around by default.
The
actual co-ordinate that needs to be passed in is the bottom left of the image
position. This image will butt right up to the right-hand margin. The image is
72 points wide (1 inch) + the margin at 36 points (total 108 points) from the
right hand edge of the document, or 595 - 108 = 487 points along the X-axis.
The Y-axis co-ordinate is the height of the image + the margin away from the
top of the document, or 842 - (213.6 + 36) = 592.4 points from the bottom.
Cripes. I don't really want to have to remember all the various sizes of
different documents and do these calculations every time I want to set the
absolute position of an element. And fortunately, I don't have to. I can use
the
Document.PageSize object to do the work for me.
iTextSharp.text.Image tif1 = iTextSharp.text.Image.GetInstance(imagepath + "/NewFile.tif");
tif1.ScalePercent(24f);
tif1.SetAbsolutePosition(doc.PageSize.Width - 36f - 72f,
doc.PageSize.Height - 36f - 216.6f);
doc.Add(tif1);
doc.PageSize.Width
gives me the width in points of the document, and I just remove the margin (36
points) and the width of the image (72 points) for the X-axis co-ordinate, and
the margin and height of the image from the total height of the document for
the Y-axis co-ordinate.
Another
scenario that might need to be catered for is to fit a user-supplied image into
a fixed size box somewhere on a form. I've pinched the Sunset image that I
found in the Sample Images folder in My Pictures that comes as part of the
default install of WindowsXP to illustrate how to use the ScaleToFit() method
to achieve this. The following code takes an image of 800 x 600 and forces it
to resize, maintaining its aspect ratio, into a rectangle measuring 250 points
square.
iTextSharp.text.Image jpg1 = iTextSharp.text.Image.GetInstance(imagepath + "/Desert.jpg");
jpg1.ScaleToFit(250f, 250f);
jpg1.Border = Rectangle.BOX;
jpg1.BorderColor = Color.YELLOW;
jpg1.BorderWidth = 5f;
doc.Add(jpg1);
doc.Add(new Paragraph("Original Width: " + jpg1.Width.ToString()));
doc.Add(new Paragraph("Original Height " + jpg1.Height.ToString()));
doc.Add(new Paragraph("Scaled Width: " + jpg1.ScaledWidth.ToString()));
doc.Add(new Paragraph("Scaled Height " + jpg1.ScaledHeight.ToString()));
float Resolution = jpg1.Width / jpg1.ScaledWidth * 72f;
doc.Add(new Paragraph("Resolution: " + Resolution));
I
have also taken the opportunity to add a yellow border to the embedded image,
which is 5 points wide, and then shown the original dimensions, followed by the
scaled dimensions, and the resulting resolution of the image.
If
you use SetAbsolutePosition() you end up with the same effect as if you had set
the Alignment property of the image to Image.UNDERLYING, in that text added to
the document will run over the top of it. Unless you want to achieve this kind
of watermark effect, you need to use Image.TEXTWRAP instead.
iTextSharp.text.Image jpg2 = iTextSharp.text.Image.GetInstance(imagepath + "/Desert.jpg");
Paragraphparagraph = newParagraph(@"Loremipsum dolor sit amet, consectetueradipiscingelit. Suspendisseblanditblanditturpis.Nam in lectusut dolor consectetuerbibendum.Morbinequeipsum, laoreet id; dignissimet, viverra id, mauris. Nullamauriselit, consectetuer sit amet, accumsaneget, congue ac, libero. Vivamussuscipit.Nuncdignissimconsectetuerlectus.Fusceelit nisi; commodonon, facilisisquis, hendreriteu, dolor? Suspendisseeleifend nisi ut magna.Phasellus id lectus! Vivamuslaoreetenimet dolor. Integer arcumauris, ultriciesvel, portaquis, venenatis at, libero.Donecnibhest, adipiscing et, ullamcorper vitae, placerat at, diam. Integer ac turpisvel ligula rutrumauctor! Morbiegestaserat sit amet diam. Ututipsum? Aliquam non sem. Nullarisuseros, mollisquis, blanditut; luctuseget, urna.Vestibulumvestibulumdapibuserat.Proinegestasleo a metus?");
paragraph.Alignment = Element.ALIGN_JUSTIFIED;
jpg2.ScaleToFit(250f, 250f);
jpg2.Alignment = iTextSharp.text.Image.TEXTWRAP | iTextSharp.text.Image.ALIGN_RIGHT;
jpg2.IndentationLeft = 9f;
jpg2.SpacingAfter = 9f;
jpg2.BorderWidthTop = 36f;
jpg2.BorderColorTop = Color.WHITE;
doc.Add(jpg2);
doc.Add(paragraph);
In
this instance, I added a white border to the image to align it with the top of
the text, and a bit of padding to the left and bottom of the image to stop the
text running right up to its edge. Left and Right padding can be added using
the IndentationLeft and IndentationRight properties, while SpacingBefore and
SpacingAfter is used to pad the top and bottom. You may ask why I didn't use
SapcingBefore instead of adding a white border, and that's a good question. The
fact is that whatever I set the value to for SpacingBefore, it seemed to have
no effect whatsover in this instance. I have no idea why this should be, but if
anyone does, I'll be pleased to hear from them.
One
final thing with images - you can rotate them if you need to. One way to do
this is to set the Rotation property, which takes a float. The float value
represents an angle measured in Radians. If you did more Mathematics than I did
at school, you may be comfortable with this, but if you are like me and ask
"What??". you can either work out that a quarter turn (90°) is Pi /
2, or simply set the RotationDegrees property instead. Rotation by default is
anti-clockwise. The following are equally valid and equivalent:
jpg2.Rotation = (float)Math.PI / 2;
jpg2.RotationDegrees = 90f;