Showing
7 changed files
with
81 additions
and
8 deletions
| @@ -14,6 +14,7 @@ | @@ -14,6 +14,7 @@ | ||
| 14 | - Improve image buffer management | 14 | - Improve image buffer management |
| 15 | - Optimize memory footprint | 15 | - Optimize memory footprint |
| 16 | - Add an exception if a jpeg image is not a supported format | 16 | - Add an exception if a jpeg image is not a supported format |
| 17 | +- Add more image loading functions | ||
| 17 | 18 | ||
| 18 | ## 1.5.0 | 19 | ## 1.5.0 |
| 19 | 20 |
| @@ -49,15 +49,13 @@ pdf.addPage(pw.Page( | @@ -49,15 +49,13 @@ pdf.addPage(pw.Page( | ||
| 49 | })); // Page | 49 | })); // Page |
| 50 | ``` | 50 | ``` |
| 51 | 51 | ||
| 52 | -To load an image it is possible to use the dart library [image](https://pub.dev/packages/image): | 52 | +To load an image from a file: |
| 53 | 53 | ||
| 54 | ```dart | 54 | ```dart |
| 55 | -final img = decodeImage(File('test.webp').readAsBytesSync()); | ||
| 56 | -final image = PdfImage( | 55 | +final img = decodeImage(); |
| 56 | +final image = PdfImage.file( | ||
| 57 | pdf.document, | 57 | pdf.document, |
| 58 | - image: img.data.buffer.asUint8List(), | ||
| 59 | - width: img.width, | ||
| 60 | - height: img.height, | 58 | + bytes: File('test.webp').readAsBytesSync(), |
| 61 | ); | 59 | ); |
| 62 | 60 | ||
| 63 | pdf.addPage(pw.Page( | 61 | pdf.addPage(pw.Page( |
| @@ -22,6 +22,7 @@ import 'dart:math' as math; | @@ -22,6 +22,7 @@ import 'dart:math' as math; | ||
| 22 | import 'dart:typed_data'; | 22 | import 'dart:typed_data'; |
| 23 | 23 | ||
| 24 | import 'package:crypto/crypto.dart'; | 24 | import 'package:crypto/crypto.dart'; |
| 25 | +import 'package:image/image.dart' as im; | ||
| 25 | import 'package:meta/meta.dart'; | 26 | import 'package:meta/meta.dart'; |
| 26 | import 'package:utf/utf.dart'; | 27 | import 'package:utf/utf.dart'; |
| 27 | import 'package:vector_math/vector_math_64.dart'; | 28 | import 'package:vector_math/vector_math_64.dart'; |
| @@ -41,6 +41,8 @@ class PdfImage extends PdfXObject { | @@ -41,6 +41,8 @@ class PdfImage extends PdfXObject { | ||
| 41 | bool alpha = true, | 41 | bool alpha = true, |
| 42 | PdfImageOrientation orientation = PdfImageOrientation.topLeft, | 42 | PdfImageOrientation orientation = PdfImageOrientation.topLeft, |
| 43 | }) { | 43 | }) { |
| 44 | + assert(image != null); | ||
| 45 | + | ||
| 44 | final PdfImage im = PdfImage._( | 46 | final PdfImage im = PdfImage._( |
| 45 | pdfDocument, | 47 | pdfDocument, |
| 46 | width, | 48 | width, |
| @@ -107,6 +109,42 @@ class PdfImage extends PdfXObject { | @@ -107,6 +109,42 @@ class PdfImage extends PdfXObject { | ||
| 107 | return im; | 109 | return im; |
| 108 | } | 110 | } |
| 109 | 111 | ||
| 112 | + factory PdfImage.fromImage( | ||
| 113 | + PdfDocument pdfDocument, { | ||
| 114 | + @required im.Image image, | ||
| 115 | + PdfImageOrientation orientation = PdfImageOrientation.topLeft, | ||
| 116 | + }) { | ||
| 117 | + assert(image != null); | ||
| 118 | + | ||
| 119 | + return PdfImage( | ||
| 120 | + pdfDocument, | ||
| 121 | + image: image.getBytes(format: im.Format.rgba), | ||
| 122 | + width: image.width, | ||
| 123 | + height: image.height, | ||
| 124 | + alpha: image.channels == im.Channels.rgba, | ||
| 125 | + orientation: orientation, | ||
| 126 | + ); | ||
| 127 | + } | ||
| 128 | + | ||
| 129 | + factory PdfImage.file( | ||
| 130 | + PdfDocument pdfDocument, { | ||
| 131 | + @required Uint8List bytes, | ||
| 132 | + PdfImageOrientation orientation = PdfImageOrientation.topLeft, | ||
| 133 | + }) { | ||
| 134 | + assert(bytes != null); | ||
| 135 | + | ||
| 136 | + if (im.JpegDecoder().isValidFile(bytes)) { | ||
| 137 | + return PdfImage.jpeg(pdfDocument, image: bytes); | ||
| 138 | + } | ||
| 139 | + | ||
| 140 | + final im.Image image = im.decodeImage(bytes); | ||
| 141 | + return PdfImage.fromImage( | ||
| 142 | + pdfDocument, | ||
| 143 | + image: image, | ||
| 144 | + orientation: orientation, | ||
| 145 | + ); | ||
| 146 | + } | ||
| 147 | + | ||
| 110 | factory PdfImage._alpha( | 148 | factory PdfImage._alpha( |
| 111 | PdfDocument pdfDocument, | 149 | PdfDocument pdfDocument, |
| 112 | Uint8List image, | 150 | Uint8List image, |
| @@ -84,6 +84,34 @@ void main() { | @@ -84,6 +84,34 @@ void main() { | ||
| 84 | ); | 84 | ); |
| 85 | }); | 85 | }); |
| 86 | 86 | ||
| 87 | + test('Pdf Image decode', () { | ||
| 88 | + final Iterable<Widget> imageWidgets = imageFiles.map<Widget>( | ||
| 89 | + (String image) => SizedBox( | ||
| 90 | + child: Image( | ||
| 91 | + PdfImage.file( | ||
| 92 | + pdf.document, | ||
| 93 | + bytes: gzip.decode(base64.decode(image)), | ||
| 94 | + ), | ||
| 95 | + ), | ||
| 96 | + width: 200, | ||
| 97 | + height: 200, | ||
| 98 | + ), | ||
| 99 | + ); | ||
| 100 | + | ||
| 101 | + pdf.addPage( | ||
| 102 | + Page( | ||
| 103 | + build: (Context context) => Center( | ||
| 104 | + child: Wrap( | ||
| 105 | + spacing: 20, | ||
| 106 | + runSpacing: 20, | ||
| 107 | + alignment: WrapAlignment.spaceEvenly, | ||
| 108 | + children: imageWidgets.toList(), | ||
| 109 | + ), | ||
| 110 | + ), | ||
| 111 | + ), | ||
| 112 | + ); | ||
| 113 | + }); | ||
| 114 | + | ||
| 87 | tearDownAll(() { | 115 | tearDownAll(() { |
| 88 | final File file = File('jpeg.pdf'); | 116 | final File file = File('jpeg.pdf'); |
| 89 | file.writeAsBytesSync(pdf.save()); | 117 | file.writeAsBytesSync(pdf.save()); |
| @@ -110,3 +138,9 @@ const List<String> images = <String>[ | @@ -110,3 +138,9 @@ const List<String> images = <String>[ | ||
| 110 | '/9j/4AAQSkZJRgABAQEA3ADcAAD/4QAiRXhpZgAASUkqAAgAAAABABIBAwABAAAABwAAAAAAAAD/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSj/2wBDAQcHBwoIChMKChMoGhYaKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCj/wAARCAAwAFADASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAAkI/8QAFBABAAAAAAAAAAAAAAAAAAAAAP/EABQBAQAAAAAAAAAAAAAAAAAAAAD/xAAUEQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIRAxEAPwDVIAAAAAAAJVgAqoAAACVYAKqAAlWAAAAAAAAAAAD/2Q==', | 138 | '/9j/4AAQSkZJRgABAQEA3ADcAAD/4QAiRXhpZgAASUkqAAgAAAABABIBAwABAAAABwAAAAAAAAD/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSj/2wBDAQcHBwoIChMKChMoGhYaKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCj/wAARCAAwAFADASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAAkI/8QAFBABAAAAAAAAAAAAAAAAAAAAAP/EABQBAQAAAAAAAAAAAAAAAAAAAAD/xAAUEQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIRAxEAPwDVIAAAAAAAJVgAqoAAACVYAKqAAlWAAAAAAAAAAAD/2Q==', |
| 111 | '/9j/4AAQSkZJRgABAQEA3ADcAAD/4QAiRXhpZgAASUkqAAgAAAABABIBAwABAAAACAAAAAAAAAD/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSj/2wBDAQcHBwoIChMKChMoGhYaKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCj/wAARCAAwAFADASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAAkI/8QAFBABAAAAAAAAAAAAAAAAAAAAAP/EABQBAQAAAAAAAAAAAAAAAAAAAAD/xAAUEQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIRAxEAPwDKgAAAAAAAAAKqAAAAlWACqgAJVgAqoAAAAAAACVYAP//Z', | 139 | '/9j/4AAQSkZJRgABAQEA3ADcAAD/4QAiRXhpZgAASUkqAAgAAAABABIBAwABAAAACAAAAAAAAAD/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSj/2wBDAQcHBwoIChMKChMoGhYaKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCj/wAARCAAwAFADASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAAkI/8QAFBABAAAAAAAAAAAAAAAAAAAAAP/EABQBAQAAAAAAAAAAAAAAAAAAAAD/xAAUEQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIRAxEAPwDKgAAAAAAAAAKqAAAAlWACqgAJVgAqoAAAAAAACVYAP//Z', |
| 112 | ]; | 140 | ]; |
| 141 | + | ||
| 142 | +const List<String> imageFiles = <String>[ | ||
| 143 | + 'H4sIAKx0cl4AA/t/4/8DBgEvN083BkZGRgYPIGT4f5vBmeE/pQBoCCPFhhxgEORgUGQwYmZUYmASZGQWZPx/hEEM7FQUwMgEFBcVQBdmEAQJY6hmAJkiIoguyvD/FgMPMyPQImZBBnuGVU0LGLS1GpoaVqiyCi1lm8gY4iDK4MAYwMDA/v8mAIKohPQ4AQAA', | ||
| 144 | + 'H4sIAAV2cl4AA+sM8HPn5ZLiYmBg4PX0cAkC0kZArMjBBCRF5PMvAylTTxfHkIjDb88ZMjIYcDAoxP5XM9vcsvrBS0bOEy+7quPmLFmKDrZ+Yjx0ienafeXk7UADGDxd/VzWOSU0AQCMWbgebgAAAA==', | ||
| 145 | + 'H4sIAFZ2cl4AA3P3dLMwTzRiUGRoYGDIXCUJRDoMQAASYWBSb+lfefot/+I5W251b7635zd/2yOPac86l706te0d9/FPPte/9T7/de41K4M1ANAWLyFIAAAA' | ||
| 146 | +]; |
No preview for this file type
-
Please register or login to post a comment