Android的PdfRenderer类生成低质量图像

Gio*_*oli 16 pdf android bitmap pdfrenderer

我正在使用PdfRenderer上面的api 21在我的应用程序中显示pdf,我注意到页面的质量非常差.我也跟着谷歌样本使用PdfRenderer,这就是我Bitmap为页面创建的方式:

//mCurrentPage is a PdfRenderer.Page and mImageView is an ImageView
Bitmap bitmap = Bitmap.createBitmap(mCurrentPage.getWidth(), 
                    mCurrentPage.getHeight(),
                    Bitmap.Config.ARGB_8888);
mCurrentPage.render(bitmap, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY);
mImageView.setImageBitmap(bitmap);
Run Code Online (Sandbox Code Playgroud)

我用过,ARGB_8888因为据我所知,它是显示位图的最佳质量.难道我做错了什么?

编辑

这是PdfRenderer类和经典Pdf阅读器之间的巨大差异:

在此输入图像描述 在此输入图像描述

Eug*_*ene 38

ARGB_8888`仅用于颜色质量,但打印/显示质量与分辨率有关(在屏幕上显示时每英寸点数).

例如,如果您有400 DPI屏幕(每英寸400点)并且想要显示具有此质量的PDF,那么您应该通过Bitmap.createBitmap()渲染位图,该像素将像素作为其大小:

Bitmap bitmap = Bitmap.createBitmap(
    getResources().getDisplayMetrics().densityDpi * mCurrentPage.getWidth() / 72,                        
    getResources().getDisplayMetrics().densityDpi * mCurrentPage.getHeight() / 72,
    Bitmap.Config.ARGB_8888
);
Run Code Online (Sandbox Code Playgroud)

哪里:

  1. getResources().getDisplayMetrics().densityDpi 是目标DPI分辨率
  2. mCurrentPage.getWidth()返回Postscript点的宽度,每个点pt都是1/72英寸.
  3. 72(DPI)是默认的PDF分辨率.

因此,在#72乘以72我们得到英寸并乘以DPI得到像素.换句话说,为了匹配显示器的打印设备的质量,您应该增加所呈现的图像的大小,因为默认的PDF分辨率是72 DPI.还请查看这篇文章

  • 这将使位图足够大,以便在与PDF页面大小相同的设备上实现完全分辨率.由于大多数设备都小得多,因此这需要更多的内存.对于我的420 DPI Nexus 5x上的8.5"x11"PDF,这会产生69 MB的位图.使用getResources().getDisplayMetrics().widthPixels/heightPixels(或根据下面的blae的答案进行缩放)给出了一个6.5 MB的位图,小于内存使用率的10%,这是我的设备无论如何都能呈现的最佳位图.更高的唯一原因是如果一个人正在放大特定部分. (4认同)
  • 小心使用此密度Dpi/72 - 在我这样做之后,它在新的高DPI设备上导致OutOfMemory错误.所以现在,我只是将我的身高和宽度乘以2来获得更清晰的图像,看起来非常好. (2认同)

小智 6

我有点晚了.答案标并不能帮助我,因为位图得大,因此无法呈现.我发现原来的职位,因为我有完全相同的问题,也许这个答案将帮助其他人在我的处境.

我四处搜索,看看是否有人有一个整洁的解决方案来缩放位图,同时保持比例.我遇到过这个网站:

https://guides.codepath.com/android/Working-with-the-ImageView#scaling-a-bitmap

真的,这不是复杂的东西.我只需要另外两行代码:

int height = DeviceDimensionsHelper.getDisplayHeight(this);
Bitmap scaledBitmap = BitmapUtil.scaleToFitHeight(bitmap, height);
Run Code Online (Sandbox Code Playgroud)

我添加了类似于网站建议的helper/util类(因此在实践中,它超过两行;)).高度来自

context.getResources().getDisplayMetrics().widthPixels;
Run Code Online (Sandbox Code Playgroud)

缩放只是将设备高度与原始位图高度分开以获得一个因子,该因子又与原始位图宽度相乘以找到缩放宽度.

这在我的Nexus 5上完美运行.我无法在多个设备上测试它,但它似乎是一个可靠的解决方案.