13
votes

I'm using iTextSharp to print a PDF document. Everything goes ok until I have to print the company logo in it.

First I noticed that the logo had poor quality, but after testing with several images, I realize that was the iTextSharp rendering it poorly. The test I did to say this was to print the PDF using my code and then edit the document with Acrobat 8.0 and I drew an image. Then printed the two documents and saw the noticeable difference. My question is that if anyone know if this can be due to a scaling problem where I'm failing to tell iTextSharp how it must render the image or is an iTextSharp limitation.

The code to render the image is the following:

            Dim para As Paragraph = New Paragraph
            para.Alignment = Image.RIGHT_ALIGN
            para.Add(text)

            Dim imageFile As String = String.Format("{0}{1}", GetAppSetting("UploadDirectory"), myCompany.LogoUrl)

            Dim thisImage As Image = Image.GetInstance(imageFile)
            thisImage.Alignment = Image.LEFT_ALIGN

            para.Add(thisImage)

The printed images are the following: alt text http://img710.imageshack.us/img710/4199/sshot2y.png

Image printed directly with iTextSharp

alt text http://img231.imageshack.us/img231/3610/sshot1z.png

Image edited and printed with Acrobat 8

EDIT: These logo images are loaded from an Upload page where the user uploades whatever the logo image he wants, and I was scaling that image using the following code:

            Dim graph As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(newImage)

            graph.CompositingMode = Drawing.Drawing2D.CompositingMode.SourceOver
            graph.CompositingQuality = Drawing.Drawing2D.CompositingQuality.HighQuality
            graph.InterpolationMode = Drawing.Drawing2D.InterpolationMode.Bicubic
            graph.SmoothingMode = Drawing.Drawing2D.SmoothingMode.HighQuality
            graph.PixelOffsetMode = Drawing.Drawing2D.PixelOffsetMode.HighQuality

            graph.DrawImage(newImage, 0, 0, newWidth, newHeight)

            graph.Dispose()
            graph = Nothing

This was causing to lose info from the original image, so when printed in the pdf, that lose of info was very noticeable because, somehow, iTextSharp was drawing bigger than it was, no matter the scaling I put in there. So I tried to store the image as it was originally, preventing the user to not upload images bigger than 200K and resizing the image so I could mantain the aspect ratio, and using that resizing with the iTextSharp Image object before it was printed. This solved my problem of the image being printed with poor quality for these bigger images but caused the pdf document to have a page break or just not fit in the page, weird thing because the picture looks good in size but it behaves like it was bigger. This is a screen capture of the new image: alt text http://img38.imageshack.us/img38/5756/sshot3tc.png

EDIT 2:

When inspecting the iTextSharp Image that is sent to be printed, it shows no changes after the scaling using ScaleAbsolute, that's why the page breaks. But is shown correctly, like the image was successfully scaled, but the background "paper" wasn't. The code used so far is the following:

                Dim imageFile As String = String.Format("{0}{1}", GetAppSetting("UploadDirectory"), myCompany.LogoUrl)

Dim thisImage As Image = Image.GetInstance(imageFile) thisImage.Alignment = Image.LEFT_ALIGN

            Dim newWidth As Integer = myCompany.LogoWidth
            Dim newHeight As Integer = myCompany.LogoHeight
            ResizeImageToMaxValues(newWidth, newHeight)
            thisImage.ScaleAbsolute(newWidth, newHeight)

            para.Add(thisImage)

            pdf.PdfDocument.Add(para)

The method ResizeImage() do the resizing of the width and height respecting the aspect ratio and keeping in a max width and a max height limits.

Please let me know if I need to provide more info. Thanks

8
My first thought would be that this is a resolution problem, that when I create the image from the file and set its size, I'm doing it wrong so it is created with less resolution than the itextSharp needs to render it with fair quality, but I'd like to know what do you think.Sebastian

8 Answers

7
votes

Apart from the printer issue (See above), the 3 X tip by Your Friend was the final solution.

So, to rephrase, if you want the image to be 100 X 100 on the PDF, then make sure that your image is 300px X 300px or larger.

I try to also use 300dpi images and I have not tested with lower quality images.

This is my image adding code:

try
{
    string uri = Environment.CurrentDirectory + "/" + "pdfwithimage_" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".pdf";
    string strImgJpg = Environment.CurrentDirectory + "/HeaderImage.jpg";

    Image imgJpg = Image.GetInstance(System.Drawing.Image.FromFile(strImgJpg), new BaseColor(System.Drawing.Color.White));

    using (Document pdf = new Document(PageSize.A4, 20, 20, 20, 20))
    {
        if (pdf == null)
        {
            throw new NullReferenceException("PDF has not been instanciated");
        }

        if (File.Exists(uri))
        {
            File.Delete(uri);
        }

        using (PdfWriter pdfwriter = PdfWriter.GetInstance(pdf, new FileStream(uri, FileMode.Create)))
        {
            pdf.Open();

            imgJpg.SetDpi(300, 300);

            imgJpg.ScaleToFit(100f, 100f);

            pdf.Add(imgJpg);

            pdf.Close();
        }
    }
}
catch (Exception ex)
{
    Console.WriteLine(ex.ToString());
    Console.ReadLine();
}
6
votes

I also have good experience with iTextSharp rendering very sharp and clear images. I tried both adding the image directly to the document and adding it to a paragraph first. Both give very clear results.

Dim document As Document = New Document(pSize, 20, 20, 20, 20)
PdfWriter.GetInstance(document, New FileStream(myPath & "Test.pdf", FileMode.Create))
document.Open()

Dim png As Image = Image.GetInstance(myPath & "myImageFile.png")
document.Add(png)

Dim pgr As New Paragraph
pgr.Add(png)
document.Add(pgr)
document.Close()

I normally use .png images, but I have had the same success with jpeg, gif, etc.

Are you certain that when you retrieve the image in iTextSharp it is the exact same image that you retrieve when you are in Acrobat? I ask because it is unclear what exaclty is happening in your code:

Dim imageFile As String=String.Format(.....

EDIT

Also, to make sure that the image is displaying at the size you are expecting, save your images at 72dpi. 72 dpi is what iTextSharp uses for everything (images, margins, etc..). That way, a 100px x 100px image will show up as 100x100 on your pdf document. You won't have to worry about scaling or re-sizing then. Any time that you scale an image (up or down) you run the risk of introducing aliasing artifacts (blurriness).

2
votes

To make the rendering clear, try to make the image 3 times the original image, then you can apply ScalePercent or ScaleToFit to resize to certain size.

Sample:

Image logo = Image.GetInstance(pdfReportData.CompanyLogoPath);
logo.ScaleToFit(175f, 108f);
document.Add(logo);
2
votes

The trick is to use larger images and scale them down. If the scale is not set and the image has its natural size, it will be poor quality. If the scale is set down and the image is drawn smaller than its natural size, the quality will be better.

Example of scaling down to 7 percent size (high quality):

var logo = Image.GetInstance(RImages.logo_600_icon, BaseColor.WHITE);
logo.ScalePercent(7);
var cell = new PdfPCell(logo);
cell.Border = 0;
table.AddCell(cell);
1
votes

That's strange. I get super-crisp images in my pdf files. There are few differences between what I do and what you have. For example I create the image like this:

Image instance = Image.GetInstance(System.Drawing.Image.FromFile(pathToImage), Color.WHITE);

Furthermore, since my image is too big to fit I call:

instance.ScalePercent(90f);

Another difference is that I add the image directly to the Document and not to a Paragraph, although I doubt that that's it.

Edit:

And finally, my images are jpegs.

Hope it helps.

1
votes

I ran into the same problem. I was able to fix it by turning off compression. My pdf files I'm generating aren't very large so the file size hit wasn't too expensive.

var writer = iTextSharp.text.pdf.PdfWriter.GetInstance(document, stream);
writer.SetPdfVersion(iTextSharp.text.pdf.PdfWriter.PDF_VERSION_1_7);
writer.CompressionLevel = PdfStream.NO_COMPRESSION;
0
votes

On my side it ended up being a printer setting!

Changing the graphics to Raster (from Vector) made the images as crisp as they should be, but slowed the system down tremendously.

The second solution (thanks to the FD) was to change the graphics back to Vector, but to set the "Image Processing" to Best.

We are using a RICOH Aficio MP C2050 PCL 6.

0
votes

Use bigger png images and than with iTextSharp change the size.

logoImage.ScalePercent(24f);