代码之家  ›  专栏  ›  技术社区  ›  Giorgio Antonioli

Android的PdfRenderer类生成低质量图像

  •  25
  • Giorgio Antonioli  · 技术社区  · 10 年前

    我正在使用 PdfRenderer 我注意到页面的质量非常差。 我也遵循了谷歌示例来使用 Pdf渲染器 这就是我创作的方式 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

    3 回复  |  直到 10 年前
        1
  •  58
  •   soshial    8 年前

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

    例如,如果您有400 DPI屏幕(每英寸400点),并希望以这种质量显示PDF,则应通过位图渲染位图。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分辨率。

    因此,将#2除以72得到英寸,乘以DPI得到像素。换句话说,为了匹配显示器的打印设备的质量,您应该增加渲染的图像的大小,因为默认PDF分辨率为72DPI。请同时检查 this post ?

        2
  •  7
  •   stianak    9 年前

    我迟到了一点。标记的答案对我没有帮助,因为位图变大了,因此无法渲染。我找到了原来的帖子,因为我有完全相同的问题,也许这个答案会帮助我处境中的其他人。

    我四处寻找,看看是否有人在保持比例的同时,有一个简单的解决方案来缩放位图。我遇到了这个网站:

    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上运行得很好。我无法在多个设备上测试这一点,但这似乎是一个可靠的解决方案。

        3
  •  1
  •   javaxian    6 年前

    PdfRenderer 您将在ImageView中显示PDF页面,最简单的方法是创建一个最大大小的ImageView位图,并添加一些数学以保持PDF的比例。由于PDF通常是为打印而制作的,因此它们的分辨率始终高于屏幕,因此您不会冒着获得像素化图像的风险。为了确保 ImageView 有没有 measuredWidth measuredHeight 分配,使用 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)
        }