You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Custom View转Bitmap生成PDF质量低且屏幕图表消失问题

问题解决方案

你的核心问题是浪费了PaintCode输出的矢量绘制能力,强行转位图导致画质下降,同时修改了已挂载到视图树的View布局导致屏幕图表消失。以下是两类可行方案:

最优方案:直接绘制矢量内容到PDF(无清晰度损失,不影响屏幕显示)

Android 原生PdfDocument的Canvas和View绘制用的Canvas完全兼容,你可以直接调用PaintCode生成的StyleKitName.drawCanvas1方法将图表矢量绘制到PDF页面,完全不需要经过View转Bitmap的流程,生成的图表是矢量格式,无限放大也不会模糊。
示例代码:

fun createVectorPdf() {
    val pdfDocument = android.graphics.pdf.PdfDocument()
    // A4尺寸单位是PostScript点,1点=1/72英寸
    val pageInfo = android.graphics.pdf.PdfDocument.PageInfo.Builder(595, 842, 1).create()
    val page = pdfDocument.startPage(pageInfo)
    val canvas = page.canvas

    // 直接绘制背景图
    val background = BitmapFactory.decodeResource(resources, R.drawable.pdfb)
    canvas.drawBitmap(background, null, RectF(0f,0f, 595f, 842f), null)

    // 直接绘制PaintCode生成的图表,矢量无损失
    val chartWidth = 595 * 0.9f
    val chartHeight = 37f
    val chartLeft = (595 - chartWidth)/2
    val chartTop = 842 - 180f - 37f
    StyleKitName.drawCanvas1(
        canvas,
        RectF(chartLeft, chartTop, chartLeft + chartWidth, chartTop + chartHeight),
        StyleKitName.ResizingBehavior.AspectFit,
        0.8f,
        145f
    )

    pdfDocument.finishPage(page)
    // 保存文件
    val file = File(filesDir, "PDFprint.pdf")
    pdfDocument.writeTo(FileOutputStream(file))
    pdfDocument.close()
}

这个方案可以同时解决你两个问题:

  • 完全不涉及屏幕上已显示的View,不会导致屏幕图表消失
  • 生成的图表是矢量格式,清晰度拉满,没有任何锯齿

现有流程修复方案(仍用iText7+Bitmap)

如果你必须保留iText7的生成流程,可以按以下方式修复两个问题:

1. 修复屏幕图表消失问题

不要用已经显示在界面上的header实例生成Bitmap,新建一个未挂载到视图树的HeaderView实例专用于Bitmap生成,不会影响屏幕上的原有View:

// 新建临时View,不添加到界面,完全不影响原有显示
val tempHeaderView = HeaderView(context)
bitmap = createBitmapFromView(tempHeaderView,(sizeWidth * 0.9).toInt(),37)

2. 修复Bitmap清晰度问题

PDF的尺寸单位是pt,你现在直接用pt值当像素生成Bitmap,相当于72DPI的分辨率,远低于打印标准的300DPI。生成Bitmap时放大尺寸,插入PDF时再缩放到原有尺寸即可提升清晰度:

// 按300DPI生成,放大3倍
val scaleFactor = 3
val renderWidth = (sizeWidth * 0.9).toInt() * scaleFactor
val renderHeight = 37 * scaleFactor
bitmap = createBitmapFromView(tempHeaderView, renderWidth, renderHeight)
// 插入PDF时指定回原来的pt尺寸
image = Image(imageData)
image.setFixedPosition(1, (sizeWidth - (sizeWidth * 0.9f)) / 2f, (sizeHeight - 180f) - 37f, (sizeWidth * 0.9f))

内容的提问来源于stack exchange,提问作者Ronald Baks

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 21:45:03