Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Build pdf with images included #51

Closed
crushman1 opened this issue Mar 24, 2019 · 10 comments
Closed

Build pdf with images included #51

crushman1 opened this issue Mar 24, 2019 · 10 comments

Comments

@crushman1
Copy link

Describe the bug
I have been trying for days now and i cannot seem to add an image with my pdf document. When i run the function that creates the pdf, the text shows in the pdf perfectly, but the image shows as a black square.

To Reproduce
Steps to reproduce the behavior:
Enter code below ::

ByteData bytes = await rootBundle.load('assets/images/1.jpg');
  var codec = await instantiateImageCodec ( bytes.buffer.asUint8List() );
  var frame = await codec.getNextFrame();
  var imageBytes = await frame.image.toByteData();
  PdfImage image = new PdfImage(pdf.document, image: imageBytes.buffer.asUint8List(),
      width: 20, height: 20);

Am i doing something wrong here?

Expected behavior
Pdf document would include the jpg or png image.

Smartphone (please complete the following information):

  • Android , ios

Additional context
cant use the printing plugin along with firebase messaging. it doesn't compile.

@DavBfr
Copy link
Owner

DavBfr commented Mar 24, 2019

Use:

PdfImage image = await pdfImageFromImageProvider(
    pdf: document, 
    image: AssetImage('assets/images/1.jpg'),
);

pdfImageFromImageProvider is part of the printing package

@DavBfr DavBfr closed this as completed Mar 24, 2019
@crushman1
Copy link
Author

this is the only way? the printing package conflicts with firestore messaging and i need firestore messaging. is there no other way to do it without printing package?

@crushman1
Copy link
Author

This is the error i receive the minute i add printing package to yaml :

android\app\src\main\AndroidManifest.xml Error:
WARNING: This version of firebase_messaging will break your Android build if it or its dependencies aren't compatible with AndroidX.
	uses-sdk:minSdkVersion 16 cannot be smaller than version 19 declared in library [:printing] C:\apps\tyrone_wreckers_management\build\printing\intermediates\library_manifest\debug\AndroidManifest.xml as the library might be using APIs not available in 16
	Suggestion: use a compatible library with a minSdk of at most 16,
         See https://goo.gl/CP92wY for more information on the problem and how to fix it.
		or increase this project's minSdk version to at least 19,
		or use tools:overrideLibrary="net.nfet.flutter.printing" to force usage (may lead to runtime failures)
         This warning prints for all Android build failures. The real root cause of the error may be unrelated.
         *********************************************************

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:processDebugManifest'.
> Manifest merger failed : uses-sdk:minSdkVersion 16 cannot be smaller than version 19 declared in library [:printing] C:\apps\tyrone_wreckers_management\build\printing\intermediates\library_manifest\debug\AndroidManifest.xml as the library might be using APIs not available in 16
  	Suggestion: use a compatible library with a minSdk of at most 16,
  		or increase this project's minSdk version to at least 19,
  		or use tools:overrideLibrary="net.nfet.flutter.printing" to force usage (may lead to runtime failures)

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 33s
Finished with error: Gradle task assembleDebug failed with exit code 1

@crushman1
Copy link
Author

crushman1 commented Mar 24, 2019

changing my minSDK to 19 does not fix the issue. changing my firestore messaging version does nothing and changing printing packing version also does nothing,
I have all the usual stuff done / enabled for example multiDexEnabled true

@DavBfr
Copy link
Owner

DavBfr commented Mar 24, 2019

Just copy the function in your project then:

/// Loads an image from a Flutter [ImageProvider]
/// into a [PdfImage] instance
Future<PdfImage> pdfImageFromImageProvider(
    {@required PdfDocument pdf,
    @required ImageProvider image,
    ImageConfiguration configuration,
    ImageErrorListener onError}) async {
  final Completer<PdfImage> completer = Completer<PdfImage>();
  final ImageStream stream =
      image.resolve(configuration ?? ImageConfiguration.empty);

  Future<void> listener(ImageInfo image, bool sync) async {
    final PdfImage result =
        await pdfImageFromImage(pdf: pdf, image: image.image);
    if (!completer.isCompleted) {
      completer.complete(result);
    }
    stream.removeListener(listener);
  }

  void errorListener(dynamic exception, StackTrace stackTrace) {
    if (!completer.isCompleted) {
      completer.complete(null);
    }
    if (onError != null) {
      onError(exception, stackTrace);
    } else {
      FlutterError.reportError(FlutterErrorDetails(
        context: 'image failed to load',
        library: 'printing',
        exception: exception,
        stack: stackTrace,
        silent: true,
      ));
    }
  }

  stream.addListener(listener, onError: errorListener);
  return completer.future;
}

@crushman1
Copy link
Author

Thanks! Works perfectly. I didn't think of simply tearing the function out of the pack as an option!
But for people having the same issue, you may have to do some editing:

  1. its most probably going to say pdfImageFromImage is undefined. I had to go into the printing package to search for it. make sure to add it in :
/// Loads an image from a Flutter [ui.Image]
/// into a [PdfImage] instance
Future<PdfImage> pdfImageFromImage(
    {@required PdfDocument pdf, @required ui.Image image}) async {
  final ByteData bytes =
  await image.toByteData(format: ui.ImageByteFormat.rawRgba);

  return PdfImage(pdf,
      image: bytes.buffer.asUint8List(),
      width: image.width,
      height: image.height);
}

  1. the ui.image is referring to the import import 'dart:ui' as ui;

@crushman1
Copy link
Author

This no longer works on the latest stable version of flutter version 1.7.8+hotfix.3 . this statement here no longer wants the listener to be a future but now it wants it to be an ImageStreamListener : stream.removeListener(listener);

@DavBfr
Copy link
Owner

DavBfr commented Jul 17, 2019

You can copy the updated function from the source here.

@crushman1
Copy link
Author

got it.

@biancashouse
Copy link

Dave,

The web impl gives this error:

Image.toByteData is not supported in Flutter for Web

Is there a web-friendly way to convert the image to bytes ?

Ian

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants