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