I'm using iTextSharp to convert large images to PDF documents.
This works, but the images appear cropped, because they exceed boundaries of the generated document.
So the question is - how to make the document same size as the image being inserted into it?
I'm using the following code:
Document doc = new Document(PageSize.LETTER.Rotate());
try
{
PdfWriter.GetInstance(doc, new FileStream(saveFileDialog1.FileName,FileMode.Create));
doc.Open();
doc.Add(new Paragraph());
iTextSharp.text.Image img = iTextSharp.text.Image.GetInstance(imagePath);
doc.Add(img);
}
catch
{
// add some code here incase you have an exception
}
finally
{
//Free the instance of the created doc as well
doc.Close();
}
The Document
object in iText and iTextSharp is an abstraction that takes care of various spacings, paddings and margins for you automatically. Unfortunately for you, this also means that when you call doc.Add()
it takes into account existing margins of the document. (Also, if you happen to add anything else the image will be added relative to that, too.)
One solution would be to just remove the margins:
doc.SetMargins(0, 0, 0, 0);
Instead, it's easier to add the image directly to the PdfWriter
object which you get from calling PdfWriter.GetInstance()
. You're currently throwing away and not storing that object but you can easily change your line to:
PdfWriter writer = PdfWriter.GetInstance(doc, new FileStream(saveFileDialog1.FileName,FileMode.Create));
Then you can access the DirectContent
property of the PdfWriter
and call its AddImage()
method:
writer.DirectContent.AddImage(img);
Before doing this you must also absolutely position the image by calling:
img.SetAbsolutePosition(0, 0);
Below is a full working C# 2010 WinForms app targeting iTextSharp 5.1.1.0 that shows the DirectContent
method above. It dynamically creates two images of different sizes with two red arrows stretching across both vertically and horizontally. Your code would obviously just use standard image loading and could thus omit a lot of this but I wanted to deliver a full working example. See the notes in the code for more details.
using System;
using System.Drawing;
using System.Windows.Forms;
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;
namespace WindowsFormsApplication1 {
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e) {
//File to write out
string outputFilename = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Images.pdf");
//Standard PDF creation
using (FileStream fs = new FileStream(outputFilename, FileMode.Create, FileAccess.Write, FileShare.None)) {
//NOTE, we are not setting a document size here at all, we'll do that later
using (Document doc = new Document()) {
using (PdfWriter writer = PdfWriter.GetInstance(doc, fs)) {
doc.Open();
//Create a simple bitmap with two red arrows stretching across it
using (Bitmap b1 = new Bitmap(100, 400)) {
using (Graphics g1 = Graphics.FromImage(b1)) {
using(Pen p1 = new Pen(Color.Red,10)){
p1.StartCap = System.Drawing.Drawing2D.LineCap.ArrowAnchor;
p1.EndCap = System.Drawing.Drawing2D.LineCap.ArrowAnchor;
g1.DrawLine(p1, 0, b1.Height / 2, b1.Width, b1.Height / 2);
g1.DrawLine(p1, b1.Width / 2, 0, b1.Width / 2, b1.Height);
//Create an iTextSharp image from the bitmap (we need to specify a background color, I think it has to do with transparency)
iTextSharp.text.Image img1 = iTextSharp.text.Image.GetInstance(b1, BaseColor.WHITE);
//Absolutely position the image
img1.SetAbsolutePosition(0, 0);
//Change the page size for the next page added to match the source image
doc.SetPageSize(new iTextSharp.text.Rectangle(0, 0, b1.Width, b1.Height, 0));
//Add a new page
doc.NewPage();
//Add the image directly to the writer
writer.DirectContent.AddImage(img1);
}
}
}
//Repeat the above but with a larger and wider image
using (Bitmap b2 = new Bitmap(4000, 1000)) {
using (Graphics g2 = Graphics.FromImage(b2)) {
using (Pen p2 = new Pen(Color.Red, 10)) {
p2.StartCap = System.Drawing.Drawing2D.LineCap.ArrowAnchor;
p2.EndCap = System.Drawing.Drawing2D.LineCap.ArrowAnchor;
g2.DrawLine(p2, 0, b2.Height / 2, b2.Width, b2.Height / 2);
g2.DrawLine(p2, b2.Width / 2, 0, b2.Width / 2, b2.Height);
iTextSharp.text.Image img2 = iTextSharp.text.Image.GetInstance(b2, BaseColor.WHITE);
img2.SetAbsolutePosition(0, 0);
doc.SetPageSize(new iTextSharp.text.Rectangle(0, 0, b2.Width, b2.Height, 0));
doc.NewPage();
writer.DirectContent.AddImage(img2);
}
}
}
doc.Close();
}
}
}
this.Close();
}
}
}
Try something like this to correct your issue
foreach (var image in images)
{
iTextSharp.text.Image pic = iTextSharp.text.Image.GetInstance(image, System.Drawing.Imaging.ImageFormat.Jpeg);
if (pic.Height > pic.Width)
{
//Maximum height is 800 pixels.
float percentage = 0.0f;
percentage = 700 / pic.Height;
pic.ScalePercent(percentage * 100);
}
else
{
//Maximum width is 600 pixels.
float percentage = 0.0f;
percentage = 540 / pic.Width;
pic.ScalePercent(percentage * 100);
}
pic.Border = iTextSharp.text.Rectangle.BOX;
pic.BorderColor = iTextSharp.text.BaseColor.BLACK;
pic.BorderWidth = 3f;
document.Add(pic);
document.NewPage();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With