如何从 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
        },
      ),
    );
  }