如何从 Flutter web 中的 pdf 中的资产文件夹加载图像?
How to load image from assets folder inside a pdf in Flutter web?
我们想在 Flutter Web 应用程序的资产文件夹中显示 pdf 图像:
import 'package:pdf/pdf.dart';
import 'package:pdf/widgets.dart' as pw;
import 'package:flutter/material.dart';
.............
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Expanded(
child: Container(
height: 400,
width: 900,
child: PdfPreview(
build: (format) => _generatePdf(format, "SOME TITLE"),
)),
),
]));
}
Future<Uint8List> _generatePdf(PdfPageFormat format) async {
final pdf = pw.Document();
pdf.addPage(
pw.Page(
pageFormat: format,
build: (context) {
return pw.Image(AssetImage('assets/imglogo.png')); //This line gives the error
}));
return pdf.save();
}
此代码给出错误:
The argument type 'AssetImage' can't be assigned to the parameter type 'ImageProvider'
documentation addresses only two cases To load an image from a file:
(dart.io
is not supported on the web), and To load an image from the network using the printing package:
, which is not the case, so we tried the solutions provided here: ,,但每一个都给出了不同的异常。
还有其他方法可以实现吗?
为此,您可以将资产图像作为文件获取,然后在 PDF 中使用该文件。如果我使用你的代码,我们可以添加一个函数来获取你的资产图像的文件表示:
Future<File> getImageFileFromAssets(String path) async {
final byteData = await rootBundle.load('assets/$path');
final file = File('${(await getTemporaryDirectory()).path}/$path');
await file.writeAsBytes(byteData.buffer
.asUint8List(byteData.offsetInBytes, byteData.lengthInBytes));
return file;
}
要使其正常工作,您需要将 path_provider 添加到您的依赖项中。
然后你就可以在你的pdf生成函数中使用这个函数了:
final pdf = pw.Document();
final file = await getImageFileFromAssets(yourpath);
final image = pw.MemoryImage(
file.readAsBytesSync(),
);
pdf.addPage(pw.Page(
pageFormat: format,
build: (context) {
return pw.Image(image);
}));
return pdf.save();
您可以将 ByteData
直接转换为 Uint8List
,如以下示例代码所示。然后可以将其传递给 MemoryImage
构造函数:
Future<void> addPage(pw.Document pdf, String filename) async {
final imageByteData = await rootBundle.load('assets/$filename');
// Convert ByteData to Uint8List
final imageUint8List = imageByteData.buffer
.asUint8List(imageByteData.offsetInBytes, imageByteData.lengthInBytes);
final image = pw.MemoryImage(imageUint8List);
pdf.addPage(
pw.Page(
build: (pw.Context context) {
return pw.Center(
child: pw.Image(image),
); // Center
},
),
);
}
我们想在 Flutter Web 应用程序的资产文件夹中显示 pdf 图像:
import 'package:pdf/pdf.dart';
import 'package:pdf/widgets.dart' as pw;
import 'package:flutter/material.dart';
.............
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Expanded(
child: Container(
height: 400,
width: 900,
child: PdfPreview(
build: (format) => _generatePdf(format, "SOME TITLE"),
)),
),
]));
}
Future<Uint8List> _generatePdf(PdfPageFormat format) async {
final pdf = pw.Document();
pdf.addPage(
pw.Page(
pageFormat: format,
build: (context) {
return pw.Image(AssetImage('assets/imglogo.png')); //This line gives the error
}));
return pdf.save();
}
此代码给出错误:
The argument type 'AssetImage' can't be assigned to the parameter type 'ImageProvider'
documentation addresses only two cases To load an image from a file:
(dart.io
is not supported on the web), and To load an image from the network using the printing package:
, which is not the case, so we tried the solutions provided here:
还有其他方法可以实现吗?
为此,您可以将资产图像作为文件获取,然后在 PDF 中使用该文件。如果我使用你的代码,我们可以添加一个函数来获取你的资产图像的文件表示:
Future<File> getImageFileFromAssets(String path) async {
final byteData = await rootBundle.load('assets/$path');
final file = File('${(await getTemporaryDirectory()).path}/$path');
await file.writeAsBytes(byteData.buffer
.asUint8List(byteData.offsetInBytes, byteData.lengthInBytes));
return file;
}
要使其正常工作,您需要将 path_provider 添加到您的依赖项中。
然后你就可以在你的pdf生成函数中使用这个函数了:
final pdf = pw.Document();
final file = await getImageFileFromAssets(yourpath);
final image = pw.MemoryImage(
file.readAsBytesSync(),
);
pdf.addPage(pw.Page(
pageFormat: format,
build: (context) {
return pw.Image(image);
}));
return pdf.save();
您可以将 ByteData
直接转换为 Uint8List
,如以下示例代码所示。然后可以将其传递给 MemoryImage
构造函数:
Future<void> addPage(pw.Document pdf, String filename) async {
final imageByteData = await rootBundle.load('assets/$filename');
// Convert ByteData to Uint8List
final imageUint8List = imageByteData.buffer
.asUint8List(imageByteData.offsetInBytes, imageByteData.lengthInBytes);
final image = pw.MemoryImage(imageUint8List);
pdf.addPage(
pw.Page(
build: (pw.Context context) {
return pw.Center(
child: pw.Image(image),
); // Center
},
),
);
}