Android PdfDocument.Page - 图像大小的问题

12

我在将内容绘制到PdfDocument.Page上时遇到了图像过大的问题。 该应用程序针对运行Android 4.4.4(API级别19)的设备。

我按照以下方式生成pdf文档并添加图像:

PdfDocument document = new PdfDocument();

//Create an A4 sized page 595 x 842 in Postscript points.
PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo.Builder(595, 842, 1).create();

PdfDocument.Page page = document.startPage(pageInfo);
Canvas canvas = page.getCanvas();

Bitmap logo = BitmapFactory.decodeResource(context.getResources(), R.drawable.pdf_logo);

Log.i(Consts.LOG_TAG, "pdf canvas density = " + canvas.getDensity());
Log.i(Consts.LOG_TAG, "pdf UOD logo density = " + logo.getDensity());

canvas.drawBitmap(logo, 50, 50, null);

document.finishPage(page);

/*
document is written out to a FileOuputStream().
Details omitted.
*/

文档书写正确,使用Canvas.drawText()方法呈现的其他文本看起来不错。但是,在PDF文档中绘制的图像始终过大。
我已经检查了图像和画布的密度是相同的。 图像(pdf_logo.jpg)如下:
- 160 dpi
- 分辨率为160 x 160个物理像素。
- 因此大小为1英寸x 1英寸。
上述代码中的日志还返回了以下内容: 04-22 11:55:50.607: I/App(7856): pdf画布密度 = 160
04-22 11:55:50.607: I/App(7856): pdf UOD标志密度= 160
这表明图像dpi与Canvas密度匹配。 但是,当图像绘制到pdf文档中时,图像比1英寸x 1英寸要大得多。它大约是原始图像大小的两倍,略大于2英寸x 2英寸。 我的怀疑是Android使用了图像的物理分辨率(160 x 160),并将其转换为PdfDocument.Page大小单位,即每英寸72点的Postscript点。因此,160个Postscript点相当于2.2英寸〜原始图像的两倍大小(1 x 1英寸)。 如果我把图像的大小减半,那么就会出现像素化,因为实际上是将一个0.5 x 0.5英寸的图像绘制到1 x 1英寸的空间中。 我想知道如何在PdfDocument.Page上以实际大小绘制图像,而不会出现这些缩放/大小问题。


由于位图根据密度进行缩放,您是否尝试使用Bitmap.setDensity()来设置不同的密度? - shadowbrush
我尝试将位图密度设置为比它认为应该更高的值:logo.setDensity(DisplayMetrics.DENSITY_XHIGH); 这样做可以解决问题。 我最初将其设置为 DENSITY_HIGH,但仍然稍微缩放了图像,因此将其更改为 DENSITY_XHIGH。 现在看起来好多了。 谢谢 @shadowbrush - Glenster
4个回答

4
这是一个晚回答,但我也遇到了同样的问题,并找到了解决方案和解释。
解释:
PdfDocument.Page大小单位是Postscript点,即1/72英寸。
这意味着,当在物理上打印时,PdfDocument使用测量1/72英寸的点,也就是说,在打印文档中,1英寸将有72个点。这也被称为72 DPI(Dots Per Inch)。
因此,使用72 DPI,如果您想以与打印文件相同的确切大小在屏幕上查看文档(无缩放),则需要每英寸72个像素(PPI)。
与图片不同,PDF文件具有物理大小,因此PdfDocument.Page的画布可以被理解为您打印文档的“屏幕”。该“屏幕”必须具有72 PPI的密度,才能将内容表示为原始内容。
解决方案:

不需要使用logo.setDensity(DisplayMetrics.DENSITY_XHIGH);,因为您不想改变图像的比例,您需要指定画布的密度。

解决方案是canvas.setDensity(72);


1
但是,将画布的密度设置为72时,位图显示在左上角。此外,与A4纸张相比,位图太小了。 - Akash Chaudhary

3

确切的解决方案是将Canvas的密度设置为72(但为什么?)

  • logo.setDensity(dpi); (通过所需图像在pt中的尺寸和位图大小计算dpi)
  • canvas.setDensity(72);
  • canvas.drawBitmap(logo, ....);

由于Postscript点的测量单位为1/72英寸,请检查我的答案。 - Pablo Rodriguez

1
根据要求,我找到的解决方案是将密度设置为比实际值更高的值。将位图密度设置为DENSITY_XHIGH而不是DENSITY_HIGH可以显著改善渲染的位图。当生成PDF时,位图的大小更接近我期望的大小。

2
这应该是注释 - ketan

0

[我将您的解决方案复制到了一个答案中。如果您已经找到了解决方案,请创建一个答案并自行接受它]

我尝试将位图密度设置为比我认为应该更高的值:logo.setDensity(DisplayMetrics.DENSITY_XHIGH); 这样就解决了问题。(最初我将其设置为DENSITY_HIGH,但仍然略微缩放图像,因此将其更改为 DENSITY_XHIGH。)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接