【问题标题】:Android PdfDocument.Page - Problems with image sizeAndroid PdfDocument.Page - 图像大小问题
【发布时间】:2015-06-30 00:56:38
【问题描述】:

在 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 大小单位,即 1/72 英寸的 Postscript 点。所以 160 Postscript 点等于 2.2 英寸 ~ 两倍于原始图像的大小(1 x 1 英寸)。

如果我将图像的大小减半,则会出现像素化,因为它将有效地将 0.5 x 0.5 英寸的图像绘制到 1 x 1 英寸的空间中。

我想知道如何在 PdfDocument.Page 上将图像绘制为实际大小,而不会出现这些缩放/大小问题。

【问题讨论】:

  • 由于位图是根据密度缩放的,您是否尝试过设置不同的密度:Bitmap.setDensity()
  • 我尝试将位图密度设置为高于它认为的值:logo.setDensity(DisplayMetrics.DENSITY_XHIGH); 这成功了。我最初将它设置为 DENSITY_HIGH,但它仍然略微放大图像,因此将其更改为 DENSITY_XHIGH。现在看起来好多了。谢谢@shadowbrush

标签: android image pdf canvas size


【解决方案1】:

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

我尝试将位图密度设置为高于我认为的值:logo.setDensity(DisplayMetrics.DENSITY_XHIGH); 这成功了。 (我最初设置为 DENSITY_HIGH,但它仍然将图像稍微放大,所以将其更改为DENSITY_XHIGH。)

【讨论】:

    【解决方案2】:

    根据要求,我找到的解决方案是将密度设置为高于应有的值。 将位图密度设置为 DENSITY_XHIGH 而不是 DENSITY_HIGH 对我来说显着改善了渲染位图。位图更接近我在生成 pdf 时所期望的大小。

    【讨论】:

    • 这应该是评论
    【解决方案3】:

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

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

    【讨论】:

    • 因为 Postscript 点的尺寸为 1/72 英寸。检查我的答案。
    【解决方案4】:

    这是一个迟到的答案,但一直在处理同样的问题,并找到了解决方案,并附有解释。

    解释:

    PdfDocument.Page 大小单位,Postscript 点为 1/72 英寸。

    这意味着,PdfDocument 使用物理打印时测量 1/72 英寸的点,这等于说在打印的文档中,1 英寸将有 72 个点。这也称为 72 DPI (Dots Per Inch)。

    因此,在 72 DPI 的情况下,如果您想在屏幕上以与打印文档完全相同的尺寸查看文档(没有 c 缩放),则需要每英寸 72 像素 (PPI)

    与图片不同,PDF 文件具有物理大小,因此 PdfDocument.Page 的 Canvas 可以理解为您正在打印文档的“屏幕”。此“屏幕”的密度必须为 72 PPI,才能将内容表示为原始内容。

    解决办法:

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

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

    【讨论】:

    • 但是使用画布的密度为72,在左上角显示位图。与 A4 尺寸相比,位图也太小了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-20
    • 2017-12-09
    • 1970-01-01
    相关资源
    最近更新 更多