问题 iTextSharp在PDF中呈现质量较差的图像


我正在使用iTextSharp打印PDF文档。一切顺利,直到我必须在其中打印公司徽标。

首先我注意到徽标的质量很差,但经过几张图片的测试后,我发现iTextSharp渲染效果不佳。 我这样做的测试是使用我的代码打印PDF,然后使用Acrobat 8​​.0编辑文档并绘制图像。然后打印了两份文件,看到了明显的区别。 我的问题是,如果有人知道这是否是由于缩放问题,我没有告诉iTextSharp它必须如何渲染图像或是iTextSharp限制。

呈现图像的代码如下:

            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)

打印的图像如下: 替代文字http://img710.imageshack.us/img710/4199/sshot2y.png

使用iTextSharp直接打印图像

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

使用Acrobat 8​​编辑和打印图像

编辑: 这些徽标图像是从“上载”页面加载的,用户可以在其中上传任何他想要的徽标图像,我使用以下代码缩放该图像:

            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

这导致原始图像丢失信息,所以当在pdf中打印时,信息的丢失非常明显,因为不管怎样,iTextSharp都比它更大,无论我放在那里的缩放。 因此,我尝试按原样存储图像,防止用户上传大于200K的图像并调整图像大小,以便我可以保持纵横比,并在打印之前使用iTextSharp Image对象调整大小。 这解决了我的问题,即这些较大的图像打印的图像质量很差,但是导致pdf文档有一个分页符或者只是不适合页面,这很奇怪,因为图片看起来很好但是它的行为就像它更大。 这是新图像的屏幕截图: alt text http://img38.imageshack.us/img38/5756/sshot3tc.png

编辑2:

检查要发送的iTextSharp图像时,使用ScaleAbsolute进行缩放后,它没有显示任何变化,这就是页面中断的原因。但正确显示,就像图像成功缩放,但背景“纸”不是。 到目前为止使用的代码如下:

                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)

ResizeImage()方法根据纵横比调整宽度和高度,并保持最大宽度和最大高度限制。

如果我需要提供更多信息,请告诉我。谢谢


4570
2018-03-26 15:11


起源

我的第一个想法是,这是一个解决问题,当我从文件创建图像并设置其大小时,我做错了所以它创建的分辨率低于itextSharp需要以合理的质量呈现它,但我想知道你的想法。 - Sebastian


答案:


我也有很好的经验,iTextSharp渲染非常清晰和清晰的图像。我尝试将图像直接添加到文档中,然后将其添加到段落中。两者都给出非常明确的结果

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()

我通常使用.png图像,但我在jpeg,gif等方面取得了同样的成功。

你确定当你在iTextSharp中检索图像时它是 精确 您在Acrobat中时检索的相同图像?我问,因为不清楚你的代码中发生了什么exaclty:

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

编辑

此外,为确保图像以您期望的尺寸显示,请将图像保存为72dpi。 72 dpi是iTextSharp用于所有内容(图像,边距等)。 这样,100px x 100px图像将在您的pdf文档中显示为100x100。您不必担心缩放或重新调整大小。无论何时缩放图像(向上或向下),都存在引入锯齿伪像(模糊)的风险。


5
2018-03-26 16:02



好吧......不,它们不是相同的图像,因为我用iTextSharp的那个是一个调整大小的图像,这就是为什么我改变了上面的那个。谢谢+1 - Sebastian


除了打印机问题(见上文),你的朋友的3 X技巧是最终的解决方案。

因此,换句话说,如果您希望图像在PDF上为100 X 100,请确保您的图像为300px X 300px或更大。

我尝试也使用300dpi图像,我没有测试较低质量的图像。

这是我的图片添加代码:

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();
}

7
2017-07-26 12:38



SetDpi(300,300)对我来说非常合适。 - Chris Brickhouse


若要使渲染清晰,请尝试将图像设置为原始图像的3倍,然后可以应用ScalePercent或ScaleToFit将其调整为特定大小。

样品:

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

2
2018-06-04 16:55





真奇怪。我在我的pdf文件中获得了超清晰的图像。我做什么和你拥有什么之间几乎没有什么区别。例如,我创建这样的图像:

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

此外,由于我的图像太大而不适合我打电话:

instance.ScalePercent(90f);

另一个区别是我直接将图像添加到 Document 而不是一个 Paragraph虽然我怀疑那就是它。

编辑

最后,我的图像是jpegs。

希望能帮助到你。


1
2018-03-26 15:26



@Sebastian,我已经更新了我的答案。 - Klaus Byskov Pedersen
非常感谢!我现在正在看,我会告诉你它是怎么回事 - Sebastian


诀窍是使用更大的图像并缩小它们。如果未设置比例且图像具有自然尺寸,则质量较差。如果缩放比例并且图像的绘制小于其自然尺寸,则质量会更好。

缩小到7%大小(高质量)的示例:

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
2017-08-29 16:54





在我这边它最终成为打印机设置!

将图形更改为Raster(来自Vector)使图像变得清晰,但却大大减慢了系统的速度。

第二个解决方案(感谢FD)是将图形更改回Vector,但将“图像处理”设置为最佳。

我们使用的是RICOH Aficio MP C2050 PCL 6。


0
2017-07-25 07:37





使用更大的png图像,而使用iTextSharp更改大小。

logoImage.ScalePercent(24f);

0
2018-05-14 13:09





我遇到了同样的问题。我能够通过关闭压缩来解决它。我生成的pdf文件不是很大,因此文件大小不太贵。

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
2018-05-28 00:42