【问题标题】:Android Bitmap from View to PDF A4Android 位图从 View 到 PDF A4
【发布时间】:2022-08-15 16:36:48
【问题描述】:

嗨,我正在尝试按照 this resource 从视图创建 A4 PDF。我已经能够成功地创建 pdf,但它切断了我的视野。我已经对视图大小进行了几次调整并调整了所有测量功能,但似乎仍然无法独立于屏幕来扩展此视图。我相信我的问题在于这段代码的某个地方。

/**
 * Entry point for creating PDF
 *
 * @param context (app context)
 * @param activity
 */
fun createPdf(
    context: Context,
    activity: Activity
) {
    val inflater = LayoutInflater.from(context)
    val view = inflater.inflate(R.layout.layout_pdf_page_one, null)

    val bitmap = createBitmapFromView(context, view, activity, 1)
    convertBitmapToPdf(bitmap, activity, nPage = 1)
}

private fun createBitmapFromView(
    context: Context,
    view: View,
    activity: Activity,
    page: Int
): Bitmap {

    val binding = LayoutPdfPageOneBinding.bind(view)
    binding.lifecycleOwner = binding.root.findViewTreeLifecycleOwner()
    initPageOne(binding, context)

    return createBitmap(context, binding.root, activity, binding)
}

private fun createBitmap(
    context: Context,
    view: View,
    activity: Activity,
    binding: LayoutPdfPageOneBinding
): Bitmap {
    // whats going on here is getting the display metrics I think I need the layout 
 size as losing some of the bottom.
    val displayMetrics = DisplayMetrics()
    activity.display?.getRealMetrics(displayMetrics)
    displayMetrics.densityDpi
    view
    view.measure(
        View.MeasureSpec.makeMeasureSpec(
            displayMetrics.widthPixels, View.MeasureSpec.EXACTLY
        ),
        View.MeasureSpec.makeMeasureSpec(
            displayMetrics.heightPixels, View.MeasureSpec.EXACTLY
        )
    )
    view.layout(0, 0, displayMetrics.widthPixels, displayMetrics.heightPixels)

    val bitmap = Bitmap.createBitmap(
        view.measuredWidth,
        view.measuredWidth,
        Bitmap.Config.ARGB_8888
    )

    Log.d(TAG, \"createBitmap: ${binding.pdfLayoutPageOne.width}\")
    Log.d(TAG, \"createBitmap: ${binding.pdfLayoutPageOne.height}\")

    val canvas = Canvas(bitmap)
    view.draw(canvas)
    return Bitmap.createScaledBitmap(bitmap, 595, 842, true)
}

我意识到这目前取决于屏幕,但我已将这些变量调整为没有成功。我还尝试更改布局视图大小以计算 dp 宽度和大小以及尝试 mm 宽度和大小。可以在这里看到前两个块,它们当前都是匹配父块,但请放心,我已经尝试了几种不同的大小调整方法。

<?xml version=\"1.0\" encoding=\"utf-8\"?>

<layout xmlns:android=\"http://schemas.android.com/apk/res/android\"
xmlns:app=\"http://schemas.android.com/apk/res-auto\"
xmlns:tools=\"http://schemas.android.com/tools\">
 

<androidx.constraintlayout.widget.ConstraintLayout
    android:id=\"@+id/pdf_layout_page_one\"
    android:layout_width=\"match_parent\"
    android:layout_height=\"match_parent\"
    android:layout_margin=\"10sp\"
    android:paddingStart=\"24sp\"
    android:paddingTop=\"24sp\"
    android:paddingEnd=\"24sp\"
    android:paddingBottom=\"88sp\">

问题是如何制作一个 A4 大小的 xml,以便设计看起来像我成功导出和导出该视图时的样子?任何 cmets 都非常受欢迎。我真的不想使用外部库,因为我要在视图中导出一些 mpandroidcharts 以便从位图导出到 pdf。

    标签: android android-layout android-bitmap android-pdf-api


    【解决方案1】:

    问题出在代码上

    val displayMetrics = DisplayMetrics()
        activity.display?.getRealMetrics(displayMetrics)
        displayMetrics.densityDpi
        view
        view.measure(
            View.MeasureSpec.makeMeasureSpec(
                displayMetrics.widthPixels, View.MeasureSpec.EXACTLY
            ),
            View.MeasureSpec.makeMeasureSpec(
                displayMetrics.heightPixels, View.MeasureSpec.EXACTLY
            )
        )
        view.layout(0, 0, displayMetrics.widthPixels, displayMetrics.heightPixels)
    

    这会将视图调整为屏幕大小,并将其布局到屏幕大小。

    替换为(希望我的 Kotlin 是正确的,我通常在 Java 中这样做):-

        view.measure(
            // Measure to A4 width
            View.MeasureSpec.makeMeasureSpec(
                595, View.MeasureSpec.EXACTLY
            ),
            // Measure to A4 height
            View.MeasureSpec.makeMeasureSpec(
                842, View.MeasureSpec.EXACTLY
            )
        )
        // Layout the view out to the measure dimensions
        view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight())
    
    

    如果之前从未将视图绘制到屏幕上,您可能还需要将布局参数设置/重置为WRAP_CONTENT(我通常会创建一个从未绘制到屏幕上的单独视图以用于 PDF 生成)

    也不确定为什么要查看 -> 绘制到位图 -> 将位图绘制到 PDF

    什么时候

    可以查看 -> 绘制到 PDF 并生成更好的 PDF

    当你val page = pdfDocument.startPage(pageInfo)时这样做

    改为

    val page = pdfDocument.startPage(pageInfo)
    // Draw the view direct to the PDF's Canvas instead via Bitmap
    view.draw(page.canvas)
    

    更新

    更多关于我实际做什么的信息。

    我只是以编程方式创建一个linearLayout来将我想要绘制的东西放到pdf中,而不是膨胀xml,这个linearLayout是PDF而不是屏幕的大小。

    例如

    LinearLayout linearLayout = new LinearLayout(getApplicationContext());
    

    在测量之前需要设置布局参数

    例如

    linearLayout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
                            LinearLayout.LayoutParams.WRAP_CONTENT));
    

    但我想在你的 xml 中可能会改变

    
    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/pdf_layout_page_one"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="10sp"
        android:paddingStart="24sp"
        android:paddingTop="24sp"
        android:paddingEnd="24sp"
        android:paddingBottom="88sp">
    

    【讨论】:

    • 感谢这非常有用。我只是在学习教程,我没有意识到你可以直接画到 PDF。不过,我仍然遇到尺寸问题。你的 xml 布局是什么尺寸的?你会在哪里重置 wrap_content 我已经遵循了所有明确提供更好分辨率的 pdf 文件。但我只捕获了视图的顶部四分之一。 (我还使用了一个永远不会被绘制到屏幕上的单独视图)。非常感谢您的指点!
    猜你喜欢
    • 2020-08-16
    • 1970-01-01
    • 1970-01-01
    • 2017-07-31
    • 2020-10-26
    • 2018-12-23
    • 2017-10-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多