Fenix
Fenix

Reputation: 81

Flutter pdf multiple images

I'm trying to load multiple images (from assets or cache) into the pdf, but it does not work. There are no errors, the pdf is created, but is corrupted somehow and does not want to open. Everything is 100% if there is only 1 image, or if all the images are the same image. What am I doing wrong?

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'dart:io';
import 'package:path_provider/path_provider.dart';
import 'package:pdf/pdf.dart';
import 'package:pdf/widgets.dart' as pw;

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: Scaffold(
            appBar: AppBar(backgroundColor: Colors.red, title: Text('Images')),
            body: Center(child: HomeScreen())));
  }
}

class HomeScreen extends StatefulWidget {
  HomeScreenState createState() => HomeScreenState();
}

class HomeScreenState extends State<HomeScreen> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Center(
      child: ListView(
        children: <Widget>[
          RaisedButton(
            color: Colors.red,
            onPressed: () async {
              writeOnPdf();
              await savePdf();
            },
            child: Text('Create Pdf'),
          ),
        ],
      ),
    ));
  }
}

final pdf = pw.Document();

writeOnPdf() async {
  var assetImage = PdfImage.file(
    pdf.document,
    bytes: (await rootBundle.load('assets/aa.png')).buffer.asUint8List(),
  );

  var otherImage = PdfImage.file(
    pdf.document,
    bytes: (await rootBundle.load('assets/out.png')).buffer.asUint8List(),
  );

  pdf.addPage(pw.MultiPage(
      pageFormat: PdfPageFormat.a4,
      margin: pw.EdgeInsets.all(32),
      build: (pw.Context context) {
        return <pw.Widget>[
          pw.Column(
              crossAxisAlignment: pw.CrossAxisAlignment.center,
              mainAxisAlignment: pw.MainAxisAlignment.spaceBetween,
              children: <pw.Widget>[
                pw.ClipRect(
                  child: pw.Container(
                    width: 550,
                    height: 250,
                    child: pw.Image(assetImage),
                  ),
                ),
              ]),
          pw.ClipRect(
            child: pw.Container(
              width: 100,
              height: 100,
              child: pw.Image(otherImage),
            ),
          )
        ];
      }));
}

final bool isHTML = false;

Future savePdf() async {
  Directory tempDir = await getTemporaryDirectory();
  String tempPath = tempDir.path;
  File file = File('$tempPath/1234.pdf');
  file.writeAsBytesSync(pdf.save());
  print(tempDir.listSync());
}

It would be ideal if I could load one image from the assets and one image from the cache. But at the moment nothing works. Any advice would be appreciated.

Upvotes: 4

Views: 2869

Answers (2)

Ozan Deniz Demirtas
Ozan Deniz Demirtas

Reputation: 1

try like that. its not influent way but it works for multiple images in same pdf page.

  final ByteData bytes1 = await rootBundle.load('assets/images/logo.png');
  final Uint8List img1 = bytes1.buffer.asUint8List();

  final ByteData bytes2 = await rootBundle.load('assets/images/1.jpg');
  final Uint8List img2 = bytes2.buffer.asUint8List();

  final ByteData bytes3 = await rootBundle.load('assets/images/2.png');
  final Uint8List img3 = bytes3.buffer.asUint8List();

  pw.Image imgty(Uint8List img) {
    return pw.Image(
        pw.MemoryImage(
          img,
        ),
        fit: pw.BoxFit.contain);
  }

and use them in pdf page

 Container(
        height: 111,
        width: 111,
        child: imgty(img1),)

Upvotes: 0

Fenix
Fenix

Reputation: 81

DavBfr gave the answer. "It's an issue with async/await."

Multiple Images #425]1

              RaisedButton(
            color: Colors.red,
            onPressed: () async {
              final pdf = await writeOnPdf();
              await savePdf(pdf);
            },
            child: const Text('Create Pdf'),
          ),

 

Upvotes: 2

Related Questions