Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/391.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Swing和iText字体呈现之间的差异_Java_Swing_Pdf_Itext - Fatal编程技术网

Java Swing和iText字体呈现之间的差异

Java Swing和iText字体呈现之间的差异,java,swing,pdf,itext,Java,Swing,Pdf,Itext,我正在开发一个应用程序,其中包括允许用户使用图层将文本插入PDF 可以使用应用程序设置文本在PDF页面中的位置,该应用程序使用JPanel内部呈现PDF。选择层的位置和大小后,应用程序使用(5.3.2)将其渲染到PDF 我面临的问题是,Swing中的字体渲染与PDF中的最终结果有明显不同 以下是一些屏幕截图,它们都使用同一边界框内的Helvetica普通字体: 使用Swing呈现文本: protected void paintComponent(Graphics g){ //for

我正在开发一个应用程序,其中包括允许用户使用图层将文本插入PDF

可以使用应用程序设置文本在PDF页面中的位置,该应用程序使用JPanel内部呈现PDF。选择层的位置和大小后,应用程序使用(5.3.2)将其渲染到PDF

我面临的问题是,Swing中的字体渲染与PDF中的最终结果有明显不同

以下是一些屏幕截图,它们都使用同一边界框内的Helvetica普通字体:

使用Swing呈现文本:

protected void paintComponent(Graphics g){
      //for each line...
      g.drawString(text, b0, b1);
      //b0 and b1 are computed from the selected bounding box for the text
}
我有这个:

使用iText呈现文本:

PdfTemplate t; //PdfTemplate is created elsewhere
ColumnText ct = new ColumnText(t);
ct.setRunDirection(PdfWriter.RUN_DIRECTION_NO_BIDI);
ct.setSpaceCharRatio(1);
ct.setSimpleColumn(new Phrase(text, font), b0, b1, b3, b4, font.getSize(), Element.ALIGN_BOTTOM); 
//b0, b1, b2 and b3 are the bounding box of the text
ct.go();
我有这个:

所以问题是:如何使Swing和iText呈现字体的方式完全相同?我可以调整Swing或iText,所以无论修改什么代码,我都需要用户真正的体验

我尝试了其他字体和类型,但它们之间仍然存在一些差异。我想我缺少一些配置

谢谢。

编辑:

Java中的字体是以像素为单位的,但iText是以点为单位的,我们知道每英寸有72个点,对于标准的windows机器,每英寸每dpi有96个像素

首先,我们需要找出点和像素之间的差异:

difference = 72 / dpi
      0.75 = 72 / 96
接下来,我们可以将Java字体大小与差值相乘得到iText字体大小,如果Java字体大小为16,那么当与96dpi一起使用时,iText字体大小应该为12

iTextFontSize = difference x javaFontSize
           12 = 0.75 x 16
在windows机器上,96dpi通常是标准的,但请记住,情况并非总是如此,您应该为每台不同的机器计算它


原职

我相信这种差异是由暗示造成的

解决方案1:

最好的方法是在缓冲图像上绘制所有内容。然后将缓冲图像绘制到swing组件,并将完全相同的缓冲图像绘制到PDF,这样它们之间应该没有区别

另一个想法:

另一种可能不太管用,但在现有代码中效果更好的方法是将swing组件的内容直接绘制到缓冲图像,然后将缓冲图像绘制到PDF

下面是一个快速示例,它将使用几个不同的渲染提示将JPanel的内容绘制到缓冲图像。(更改提示以适合您的swing组件)

所以问题是:如何使Swing和iText呈现字体的方式完全相同

完全一样?很少。假定您为两者提供相同的字体特征,在呈现时可能仍然会引入差异

PDF文件(或者实际上是文本短语)包含字体信息系列、大小、样式等,但将文本呈现到设备上的是PDF阅读器。根据您使用的程序,它可以使用平台的渲染器,也可以选择自己的渲染器

另外,JavaSwing使用自己的字体渲染引擎,这与底层平台的渲染器不同。这使得它在不同平台上看起来更加一致,但也使得文本不太可能以其他程序相同的方式呈现

知道这一点,您的选择是有限的:

  • 使用同样使用Swing字体呈现的PDF阅读器。这是一个相当有限的解决方案

  • 使用平台的渲染引擎绘制Swing。这听起来像是不确定的工作,也像SWT应该解决的问题。也许你可以嵌入一个SWT组件


您使用哪些字体?您可以尝试在PDF中嵌入字体。你也可以检查字符对的紧排,并在两边自定义。我在两边都使用Helvetica plain。Helvetica是核心字体之一,所以我认为我不必导入它。紧排可能是问题之一。你知道我如何在Swing中改变它吗?你在使用itext的fontmapper吗?是否嵌入字体?虽然此解决方案可以工作,但最终结果可能很差。渲染文本(而不是图像)时,文本在渲染时与PDF的其余部分比例良好。如果我改为使用图像,当用户缩放文档时,图像会变成(主要是文本)。为了缓解这个问题,我必须使用一个更大的图像(更多的dpi),这会增加PDF的大小。嘿,以防万一,我已经用一个更好的解决方案编辑了我的文章。我不知道这是否是问题所在。。。将iTextFontSize减少任何值都会使差异比以前更大。是否确实正确调整了itext字体大小而不是摇摆大小?从你的图片上看,它显示的是更大的itext字体,所以通过减少itext字体大小,正如我所建议的,文本应该与swing的大小相同,如果不是这样,那么你的程序中肯定出了其他问题。是的,我正在调整字体大小。我面临的问题是字符间距和粗体。我不知道该怎么做才能解决这个问题,所以目前我正在使用“不完美但足够好”的方法。
public BufferedImage createImage(JPanel panel)
{
    BufferedImage swingComponent = new BufferedImage(
            panel.getHeight(), panel.getWidth(), 
            BufferedImage.TYPE_INT_RGB);

    Graphics2D g = swingComponent.createGraphics();

    g.setRenderingHint(RenderingHints.KEY_RENDERING,
                       RenderingHints.VALUE_RENDER_QUALITY);

    g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                       RenderingHints.VALUE_ANTIALIAS_ON);

    g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
                       RenderingHints.VALUE_INTERPOLATION_BILINEAR);

    g.dispose();
    return swingComponent; //print this to your PDF
}