Android的PdfRenderer类会产生低质量的图像

时间:2015-08-28 14:55:32

标签: android pdf bitmap pdfrenderer

我使用api 21上方的PdfRenderer在我的应用中显示pdf,我发现页面质量非常差。 我也跟着google示例使用了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);

我使用了ARGB_8888,因为据我所知,它是显示位图的最佳质量。 我做错了吗?

修改

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

enter image description here enter image description here

4 个答案:

答案 0 :(得分:33)

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

其中:

  1. getResources().getDisplayMetrics().densityDpi是目标DPI解决方案
  2. mCurrentPage.getWidth()在Postscript点返回宽度,其中每个pt为1/72英寸。
  3. 72(DPI)是默认的PDF分辨率。
  4. 因此,将#2跳到72,我们得到英寸并乘以DPI得到像素。换句话说,为了匹配显示器的打印设备的质量,您应该增加所呈现的图像的大小,因为默认的PDF分辨率是72 DPI。还请检查this post

答案 1 :(得分:5)

我有点晚了。标记的答案对我没有帮助,因为位图变大了,因此无法渲染。我找到了原帖,因为我遇到了完全相同的问题,也许这个答案在我的情况下会帮助其他人。

我四处搜索,看看是否有人有一个整洁的解决方案来缩放位图,同时保持比例。我偶然发现了这个网站:

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

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

int height = DeviceDimensionsHelper.getDisplayHeight(this);
Bitmap scaledBitmap = BitmapUtil.scaleToFitHeight(bitmap, height);

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

context.getResources().getDisplayMetrics().widthPixels;

缩放只是将设备高度与原始位图高度相除,得到一个因子,然后乘以原始位图宽度以找到缩放的宽度。

这完全适用于我的Nexus 5.我无法在多台设备上测试,但它似乎是一个可靠的解决方案。

答案 2 :(得分:1)

PdfRenderer一样,您将在ImageView中显示PDF页面,最简单的方法是简单地创建ImageView的最大大小的位图,并添加一些数学运算来保留PDF的比例。由于PDF通常是用于打印的,因此它们的分辨率始终比屏幕高,因此您不必冒像素化图像的风险。为确保为ImageView分配了measuredWidthmeasuredHeight,请在代码中使用ImageView::post()(对不起,我的Kotlin):

    pdfPageImageView.post {
        val viewWidth = pdfPageImageView.measuredWidth
        val viewHeight = pdfPageImageView.measuredHeight
        val pageWidth = page.width
        val pageHeight = page.height
        val pageRatio = 1.0 * pageWidth / pageHeight
        val viewRatio = 1.0 * viewWidth / viewHeight
        val bitmapWidth: Int
        val bitmapHeight: Int
        if (pageRatio > viewRatio) {
            bitmapWidth = viewWidth
            bitmapHeight = (viewWidth / pageRatio).toInt()
        } else {
            bitmapHeight = viewHeight
            bitmapWidth = (viewHeight * pageRatio).toInt()
        }
        val bitmap = Bitmap.createBitmap(bitmapWidth, bitmapHeight, Bitmap.Config.ARGB_8888)
        page.render(bitmap, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY)
        pdfPageImageView.setImageBitmap(bitmap)
    }

答案 3 :(得分:0)

您可以尝试使用PDFViewer类关注this sample,不确定质量,因为我从未使用它,但它仍然是尝试:)