0

I'm making an app that can display and print images in a pdf package.

Create a pdf with the pdf package and print it with the printing package.

To print, Uint8List data must be sent to save() function of pdf. However, the loading screen stops because the size of my pdf is not small.

I think you should use compute() to solve this problem.

draw pdf

 Future<pdfWidget.Document> _drawEnsembleScorePrint(BuildContext context) async {
    DrawScore drawScore = DrawScore();
    pdfWidget.Document scorePdf = pdfWidget.Document(version: PdfVersion.pdf_1_5, compress: true);

    print('drawEnsemble print start');
    for(int nCurPage=0; nCurPage<scorePngList.length; nCurPage++) {
      File imageFile = File(scorePngList[nCurPage].path);
      final image = pdfWidget.MemoryImage(imageFile.readAsBytesSync());

      final watermarkingImage = await imageFromAssetBundle('assets/images/ELF_CI.png');
      final underElfimage = await imageFromAssetBundle('assets/images/ELF_CI2.png');

      scorePdf.addPage(
        pdfWidget.Page(
            pageFormat: PdfPageFormat.a4,

            ///2480 * 3508
            build: (pdfWidget.Context pContext) {
              return pdfWidget.Stack(
                children: [

                  drawScore.drawWatermarking(context, watermarkingImage, 1.0),

                  pdfWidget.Container(
                    width: 2480,
                    height: 3508,
                    child: pdfWidget.Image(image, fit: pdfWidget.BoxFit.fill),
                  ),


                  pdfWidget.Positioned(
                    top: 100,
                    left: 2190,
                    child: pdfWidget.Container(
                      width: 201,
                      height: 100,
                      color: PdfColor.fromInt(0xFFFFFFFF),
                    ),
                  ),

                  // pdfWidget.Positioned(
                  //   top: 100,
                  //   left: 2190,
                  //   child: pdfWidget.Container(
                  //     width: 201,
                  //     height: 100,
                  //     alignment: pdfWidget.Alignment.centerRight,
                  //     child: pdfWidget.Text(
                  //       httpCommunicate.nDispNumber.toString(),
                  //       style: pdfWidget.TextStyle(
                  //         font: context.read<CustomFontProvider>().SOURCE_HANSANS_MEDIUM,
                  //         fontSize: 48,
                  //       ),
                  //     ),
                  //   ),
                  // ),

                  // drawScore.drawWatermarking(context, watermarkingImage, httpCommunicate),

                  pdfWidget.Positioned(
                    top: 3424,
                    left: 24,
                    child: pdfWidget.Container(
                      width: 2432,
                      height: 83,
                      alignment: pdfWidget.Alignment.topCenter,
                      child: pdfWidget.Text(
                        '${nCurPage + 1} / ${scorePngList.length}',
                        style: pdfWidget.TextStyle(
                          // font: context.read<CustomFontProvider>().SOURCE_HANSANS_NORMAL,
                          fontSize: 36,
                        ),
                      ),
                    ),
                  ),

                  pdfWidget.Positioned(
                    top: 3424,
                    left: 24,
                    child: pdfWidget.Container(
                      width: 2432,
                      height: 83,
                      alignment: pdfWidget.Alignment.topLeft,
                      child: pdfWidget.Text(
                        strUserID,
                        style: pdfWidget.TextStyle(
                            // font: context.read<CustomFontProvider>().SOURCE_HANSANS_NORMAL,
                            fontSize: 36,
                            color: PdfColor.fromInt(0xFF000000)
                        ),
                      ),
                    ),
                  ),

                  pdfWidget.Positioned(
                    top: 3424,
                    left: 24,
                    child: pdfWidget.Container(
                      width: 2432,
                      height: 83,
                      alignment: pdfWidget.Alignment.topRight,
                      child: pdfWidget.Image(underElfimage, width: 190, height: 72),
                    ),
                  ),


                ],
              );
            }
        ),
      );
    }
    return scorePdf;
  }

call draw pdf func

_realDrawEnsembleScore(BuildContext context, HttpCommunicate httpCommunicate) async {

    DrawScore drawScore = DrawScore();

    pdfWidget.Document scorePdf = pdfWidget.Document(version: PdfVersion.pdf_1_5, compress: true);

      if(httpCommunicate.bIsPreViewScore == true){
        // scorePdf = await compute(_drawEnsemblePreview, 0);
        scorePdf = await _drawEnsemblePreview(context);
      }
      else{
        // scorePdf = await compute(_drawEnsembleScorePrint, 0);
        scorePdf = await _drawEnsembleScorePrint(context);
      }

    return scorePdf;
  }

call realDrawEnsembleScore func

Future<pdfWidget.Document> addScorePDF(BuildContext context, HttpCommunicate httpCommunicate, bool bIsTiff)async{
    DrawScore drawScore = DrawScore();
    pdfWidget.Document scorePdf = pdfWidget.Document(version: PdfVersion.pdf_1_5, compress: true);
    final cutpaperImage = await imageFromAssetBundle('assets/images/CutPaper.png');
    final watermarkingImage = await imageFromAssetBundle('assets/images/ELF_CI.png');
    final underElfimage = await imageFromAssetBundle('assets/images/ELF_CI2.png');

    if(!bIsTiff){
      scorePdf = await _realDrawScore(context, httpCommunicate);
    }
    else{
      scorePdf = await _realDrawEnsembleScore(context, httpCommunicate);
    }

    return scorePdf;

  }

compute code

pdfWidget.Document? scorePdf;
scorePdf = await context.read<PDFProvider>().addScorePDF(context, httpCommunicate, true);
Uint8List uintData = await compute(_testfunction, 0);

////
Future<Uint8List> _testfunction(int x) async {
    pdfWidget.Document scorePdf = pdfWidget.Document(version: PdfVersion.pdf_1_5, compress: true);

    print("_test function start");

    Uint8List data;

    data = g_scorePdf!.save();
    return data;
  }

But _testfunction is never called. g_scorePdf is not null, but Save() throws an error.

Jungwon
  • 1,038
  • 7
  • 20

1 Answers1

1

You need to make sure the function you are calling is a top-level function. I would also avoid sending BuildContext as an argument to the isolate.

Future<Uint8List> _testfunction(int x) async {
  pdfWidget.Document scorePdf = pdfWidget.Document(version: PdfVersion.pdf_1_5, compress: true);

  for (int i = 0; i < 3; i++) {
    scorePdf.addPage(
      pdfWidget.Page(build: (pdfWidget.Context context) {
        return pdfWidget.Stack(
          children: [
            pdfWidget.Positioned(
              top: 1000,
              left: 1000,
              child: pdfWidget.Text('top 1000, left 1000'),
            ),
          ],
        );
      }),
    );
  }
  debugPrint('Done');

  return await scorePdf.save();
}

class MyStatefulWidget extends StatefulWidget {
  const MyStatefulWidget({super.key});

  @override
  State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
}

class _MyStatefulWidgetState extends State<MyStatefulWidget> {
  Future<Uint8List> addPdfTest(BuildContext context) async {
    Uint8List data = await compute(_testfunction, 1);

    return data;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      extendBody: true,
      body: Center(
        child: GestureDetector(
          onTap: () async {
            await addPdfTest(context);
          },
          child: Container(color: Colors.red),
        ),
      ),
    );
  }
}

You can read more about using compute here and here.

pdf package link for anyone else that's interested: https://pub.dev/packages/pdf

Code on the Rocks
  • 11,488
  • 3
  • 53
  • 61