Flutter中使用printing包转换PDF为PNG时页面边距丢失问题
Flutter PDF转PNG丢失页面边距的解决方法
我在Flutter应用中用pdf库生成带边距的PDF,使用printing包将PDF转成PNG图片时,发现生成的图片丢失了原PDF设置的页面边距。
对比效果:
- 原PDF截图:

- 转换后的PNG:

原转换代码
var pageNo = 0; await for (var page in Printing.raster(widget.pdf, dpi: 100)) { pageNo++; final image = await page.toPng(); await File('/storage/emulated/0/Download/Invoice-${widget.invoiceNo}-page$pageNo.png') .writeAsBytes(image); }
生成PDF的PageTheme代码
pw.PageTheme( margin: const pw.EdgeInsets.all(40), theme: pw.ThemeData(defaultTextStyle: pw.TextStyle(font: font)), pageFormat: PdfPageFormat.a4.copyWith( marginRight: 40, marginLeft: 40, marginBottom: 40, marginTop: 40, ), buildBackground: (_) => pw.FullPage( ignoreMargins: false, child: pw.Container(color: PdfColors.white), ), )
解决办法
printing包的Printing.raster方法默认只渲染PDF的内容区域(即去掉边距后的部分),要保留边距,可通过以下两种方式处理:
方法1:使用fullPage参数(推荐)
调用Printing.raster时添加fullPage: true参数,强制渲染整个PDF页面(包含边距):
var pageNo = 0; await for (var page in Printing.raster(widget.pdf, dpi: 100, fullPage: true)) { pageNo++; final image = await page.toPng(); await File('/storage/emulated/0/Download/Invoice-${widget.invoiceNo}-page$pageNo.png') .writeAsBytes(image); }
方法2:手动为图片添加边距
若fullPage参数不生效,可借助image库手动为生成的PNG添加对应边距:
- 先在
pubspec.yaml添加依赖:
dependencies: image: ^4.0.17
- 修改转换代码:
import 'package:image/image.dart' as img; var pageNo = 0; await for (var page in Printing.raster(widget.pdf, dpi: 100)) { pageNo++; final image = await page.toPng(); // 解析原图片 final srcImg = img.decodePng(image)!; // 换算边距对应的像素值(40pt = 40 * dpi/72) final marginPx = (40 * 100 / 72).round(); // 创建带边距的新画布 final newImg = img.Image( width: srcImg.width + marginPx * 2, height: srcImg.height + marginPx * 2, ); // 填充和PDF一致的白色背景 img.fill(newImg, img.getColor(255, 255, 255)); // 将原图片绘制到新画布的边距内侧 img.copyInto( newImg, srcImg, dstX: marginPx, dstY: marginPx, ); // 编码为PNG并保存 final newPng = img.encodePng(newImg); await File('/storage/emulated/0/Download/Invoice-${widget.invoiceNo}-page$pageNo.png') .writeAsBytes(newPng); }
说明
方法1利用printing包原生参数实现完整页面渲染,操作最简单;方法2适合自定义边距样式或旧版本printing包不支持fullPage参数的场景。
内容的提问来源于stack exchange,提问作者Surya
相关产品推荐
相关产品推荐

