David PHAM-VAN

Update Image dependency

@@ -17,7 +17,7 @@ dependencies: @@ -17,7 +17,7 @@ dependencies:
17 url_launcher: ^6.0.6 17 url_launcher: ^6.0.6
18 18
19 dev_dependencies: 19 dev_dependencies:
20 - flutter_launcher_icons: ^0.10.0 20 + # flutter_launcher_icons: ^0.10.0
21 flutter_lints: ^1.0.4 21 flutter_lints: ^1.0.4
22 flutter_test: 22 flutter_test:
23 sdk: flutter 23 sdk: flutter
1 # Changelog 1 # Changelog
2 2
3 -## 3.8.5 3 +## 3.9.0
4 4
5 - Improve TTF Writer compatibility 5 - Improve TTF Writer compatibility
6 - Apply THE BIDIRECTIONAL ALGORITHM using dart_bidi [Milad akarie] 6 - Apply THE BIDIRECTIONAL ALGORITHM using dart_bidi [Milad akarie]
7 - Add Inseparable Widget 7 - Add Inseparable Widget
8 - Fix unit tests 8 - Fix unit tests
  9 +- Update Image dependency
9 10
10 ## 3.8.4 11 ## 3.8.4
11 12
@@ -41,4 +41,5 @@ export 'src/pdf/obj/smask.dart'; @@ -41,4 +41,5 @@ export 'src/pdf/obj/smask.dart';
41 export 'src/pdf/obj/ttffont.dart'; 41 export 'src/pdf/obj/ttffont.dart';
42 export 'src/pdf/page_format.dart'; 42 export 'src/pdf/page_format.dart';
43 export 'src/pdf/point.dart'; 43 export 'src/pdf/point.dart';
  44 +export 'src/pdf/raster.dart';
44 export 'src/pdf/rect.dart'; 45 export 'src/pdf/rect.dart';
@@ -21,6 +21,7 @@ import 'package:image/image.dart' as im; @@ -21,6 +21,7 @@ import 'package:image/image.dart' as im;
21 import '../data_types.dart'; 21 import '../data_types.dart';
22 import '../document.dart'; 22 import '../document.dart';
23 import '../exif.dart'; 23 import '../exif.dart';
  24 +import '../raster.dart';
24 import 'xobject.dart'; 25 import 'xobject.dart';
25 26
26 /// Represents the position of the first pixel in the data stream 27 /// Represents the position of the first pixel in the data stream
@@ -152,12 +153,13 @@ class PdfImage extends PdfXObject { @@ -152,12 +153,13 @@ class PdfImage extends PdfXObject {
152 required im.Image image, 153 required im.Image image,
153 PdfImageOrientation orientation = PdfImageOrientation.topLeft, 154 PdfImageOrientation orientation = PdfImageOrientation.topLeft,
154 }) { 155 }) {
  156 + final raster = PdfRasterBase.fromImage(image);
155 return PdfImage( 157 return PdfImage(
156 pdfDocument, 158 pdfDocument,
157 - image: image.getBytes(format: im.Format.rgba),  
158 - width: image.width,  
159 - height: image.height,  
160 - alpha: image.channels == im.Channels.rgba, 159 + image: raster.pixels,
  160 + width: raster.width,
  161 + height: raster.height,
  162 + alpha: raster.alpha,
161 orientation: orientation, 163 orientation: orientation,
162 ); 164 );
163 } 165 }
  1 +/*
  2 + * Copyright (C) 2017, David PHAM-VAN <dev.nfet.net@gmail.com>
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +
  17 +import 'dart:async';
  18 +import 'dart:typed_data';
  19 +
  20 +import 'package:image/image.dart' as im;
  21 +
  22 +import 'color.dart';
  23 +
  24 +/// Represents a bitmap image
  25 +class PdfRasterBase {
  26 + /// Create a bitmap image
  27 + const PdfRasterBase(
  28 + this.width,
  29 + this.height,
  30 + this.alpha,
  31 + this.pixels,
  32 + );
  33 +
  34 + factory PdfRasterBase.fromImage(im.Image image) {
  35 + final data = image
  36 + .convert(format: im.Format.uint8, numChannels: 4, noAnimation: true)
  37 + .toUint8List();
  38 + return PdfRasterBase(image.width, image.height, true, data);
  39 + }
  40 +
  41 + factory PdfRasterBase.fromPng(Uint8List png) {
  42 + final img = im.PngDecoder().decode(png)!;
  43 + return PdfRasterBase.fromImage(img);
  44 + }
  45 +
  46 + static im.Image shadowRect(
  47 + double width,
  48 + double height,
  49 + double spreadRadius,
  50 + double blurRadius,
  51 + PdfColor color,
  52 + ) {
  53 + final shadow = im.Image(
  54 + width: (width + spreadRadius * 2).round(),
  55 + height: (height + spreadRadius * 2).round(),
  56 + format: im.Format.uint8,
  57 + numChannels: 4,
  58 + );
  59 +
  60 + im.fillRect(
  61 + shadow,
  62 + x1: spreadRadius.round(),
  63 + y1: spreadRadius.round(),
  64 + x2: (spreadRadius + width).round(),
  65 + y2: (spreadRadius + height).round(),
  66 + color: im.ColorUint8(4)
  67 + ..r = color.red * 255
  68 + ..g = color.green * 255
  69 + ..b = color.blue * 255
  70 + ..a = color.alpha * 255,
  71 + );
  72 +
  73 + return im.gaussianBlur(shadow, radius: blurRadius.round());
  74 + }
  75 +
  76 + static im.Image shadowEllipse(
  77 + double width,
  78 + double height,
  79 + double spreadRadius,
  80 + double blurRadius,
  81 + PdfColor color,
  82 + ) {
  83 + final shadow = im.Image(
  84 + width: (width + spreadRadius * 2).round(),
  85 + height: (height + spreadRadius * 2).round(),
  86 + format: im.Format.uint8,
  87 + numChannels: 4,
  88 + );
  89 +
  90 + im.fillCircle(
  91 + shadow,
  92 + x: (spreadRadius + width / 2).round(),
  93 + y: (spreadRadius + height / 2).round(),
  94 + radius: (width / 2).round(),
  95 + color: im.ColorUint8(4)
  96 + ..r = color.red * 255
  97 + ..g = color.green * 255
  98 + ..b = color.blue * 255
  99 + ..a = color.alpha * 255,
  100 + );
  101 +
  102 + return im.gaussianBlur(shadow, radius: blurRadius.round());
  103 + }
  104 +
  105 + /// The width of the image
  106 + final int width;
  107 +
  108 + /// The height of the image
  109 + final int height;
  110 +
  111 + /// The alpha channel is used
  112 + final bool alpha;
  113 +
  114 + /// The raw RGBA pixels of the image
  115 + final Uint8List pixels;
  116 +
  117 + @override
  118 + String toString() => 'Image ${width}x$height ${width * height * 4} bytes';
  119 +
  120 + /// Convert to a PNG image
  121 + Future<Uint8List> toPng() async {
  122 + final img = asImage();
  123 + return im.PngEncoder().encode(img);
  124 + }
  125 +
  126 + /// Returns the image as an [Image] object from the pub:image library
  127 + im.Image asImage() {
  128 + return im.Image.fromBytes(
  129 + width: width,
  130 + height: height,
  131 + bytes: pixels.buffer,
  132 + format: im.Format.uint8,
  133 + numChannels: 4,
  134 + );
  135 + }
  136 +}
@@ -15,6 +15,7 @@ @@ -15,6 +15,7 @@
15 */ 15 */
16 16
17 import 'dart:convert'; 17 import 'dart:convert';
  18 +import 'dart:typed_data';
18 19
19 import 'package:image/image.dart' as im; 20 import 'package:image/image.dart' as im;
20 import 'package:vector_math/vector_math_64.dart'; 21 import 'package:vector_math/vector_math_64.dart';
@@ -74,7 +75,7 @@ class SvgImg extends SvgOperation { @@ -74,7 +75,7 @@ class SvgImg extends SvgOperation {
74 final img = im.decodeImage(bytes)!; 75 final img = im.decodeImage(bytes)!;
75 image = PdfImage( 76 image = PdfImage(
76 painter.document, 77 painter.document,
77 - image: img.data.buffer.asUint8List(), 78 + image: img.data?.buffer.asUint8List() ?? Uint8List(0),
78 width: img.width, 79 width: img.width,
79 height: img.height, 80 height: img.height,
80 ); 81 );
@@ -16,7 +16,6 @@ @@ -16,7 +16,6 @@
16 16
17 import 'dart:math' as math; 17 import 'dart:math' as math;
18 18
19 -import 'package:image/image.dart' as im;  
20 import 'package:meta/meta.dart'; 19 import 'package:meta/meta.dart';
21 import 'package:vector_math/vector_math_64.dart'; 20 import 'package:vector_math/vector_math_64.dart';
22 21
@@ -251,45 +250,6 @@ class BoxShadow { @@ -251,45 +250,6 @@ class BoxShadow {
251 final PdfPoint offset; 250 final PdfPoint offset;
252 final double blurRadius; 251 final double blurRadius;
253 final double spreadRadius; 252 final double spreadRadius;
254 -  
255 - im.Image _rect(double width, double height) {  
256 - final shadow = im.Image(  
257 - (width + spreadRadius * 2).round(),  
258 - (height + spreadRadius * 2).round(),  
259 - );  
260 -  
261 - im.fillRect(  
262 - shadow,  
263 - spreadRadius.round(),  
264 - spreadRadius.round(),  
265 - (spreadRadius + width).round(),  
266 - (spreadRadius + height).round(),  
267 - color.toInt(),  
268 - );  
269 -  
270 - im.gaussianBlur(shadow, blurRadius.round());  
271 -  
272 - return shadow;  
273 - }  
274 -  
275 - im.Image _ellipse(double width, double height) {  
276 - final shadow = im.Image(  
277 - (width + spreadRadius * 2).round(),  
278 - (height + spreadRadius * 2).round(),  
279 - );  
280 -  
281 - im.fillCircle(  
282 - shadow,  
283 - (spreadRadius + width / 2).round(),  
284 - (spreadRadius + height / 2).round(),  
285 - (width / 2).round(),  
286 - color.toInt(),  
287 - );  
288 -  
289 - im.gaussianBlur(shadow, blurRadius.round());  
290 -  
291 - return shadow;  
292 - }  
293 } 253 }
294 254
295 enum BoxShape { circle, rectangle } 255 enum BoxShape { circle, rectangle }
@@ -329,7 +289,8 @@ class BoxDecoration { @@ -329,7 +289,8 @@ class BoxDecoration {
329 if (borderRadius == null) { 289 if (borderRadius == null) {
330 if (boxShadow != null) { 290 if (boxShadow != null) {
331 for (final s in boxShadow!) { 291 for (final s in boxShadow!) {
332 - final i = s._rect(box.width, box.height); 292 + final i = PdfRasterBase.shadowRect(box.width, box.height,
  293 + s.spreadRadius, s.blurRadius, s.color);
333 final m = PdfImage.fromImage(context.document, image: i); 294 final m = PdfImage.fromImage(context.document, image: i);
334 context.canvas.drawImage( 295 context.canvas.drawImage(
335 m, 296 m,
@@ -342,7 +303,8 @@ class BoxDecoration { @@ -342,7 +303,8 @@ class BoxDecoration {
342 } else { 303 } else {
343 if (boxShadow != null) { 304 if (boxShadow != null) {
344 for (final s in boxShadow!) { 305 for (final s in boxShadow!) {
345 - final i = s._rect(box.width, box.height); 306 + final i = PdfRasterBase.shadowRect(box.width, box.height,
  307 + s.spreadRadius, s.blurRadius, s.color);
346 final m = PdfImage.fromImage(context.document, image: i); 308 final m = PdfImage.fromImage(context.document, image: i);
347 context.canvas.drawImage( 309 context.canvas.drawImage(
348 m, 310 m,
@@ -357,7 +319,8 @@ class BoxDecoration { @@ -357,7 +319,8 @@ class BoxDecoration {
357 case BoxShape.circle: 319 case BoxShape.circle:
358 if (boxShadow != null && box.width == box.height) { 320 if (boxShadow != null && box.width == box.height) {
359 for (final s in boxShadow!) { 321 for (final s in boxShadow!) {
360 - final i = s._ellipse(box.width, box.height); 322 + final i = PdfRasterBase.shadowEllipse(box.width, box.height,
  323 + s.spreadRadius, s.blurRadius, s.color);
361 final m = PdfImage.fromImage(context.document, image: i); 324 final m = PdfImage.fromImage(context.document, image: i);
362 context.canvas.drawImage( 325 context.canvas.drawImage(
363 m, 326 m,
@@ -187,6 +187,6 @@ class RawImage extends ImageImage { @@ -187,6 +187,6 @@ class RawImage extends ImageImage {
187 required int height, 187 required int height,
188 PdfImageOrientation? orientation, 188 PdfImageOrientation? orientation,
189 double? dpi, 189 double? dpi,
190 - }) : super(im.Image.fromBytes(width, height, bytes), 190 + }) : super(PdfRasterBase(width, height, true, bytes).asImage(),
191 orientation: orientation, dpi: dpi); 191 orientation: orientation, dpi: dpi);
192 } 192 }
@@ -3,7 +3,7 @@ description: A pdf producer for Dart. It can create pdf files for both web or fl @@ -3,7 +3,7 @@ description: A pdf producer for Dart. It can create pdf files for both web or fl
3 homepage: https://github.com/DavBfr/dart_pdf/tree/master/pdf 3 homepage: https://github.com/DavBfr/dart_pdf/tree/master/pdf
4 repository: https://github.com/DavBfr/dart_pdf 4 repository: https://github.com/DavBfr/dart_pdf
5 issue_tracker: https://github.com/DavBfr/dart_pdf/issues 5 issue_tracker: https://github.com/DavBfr/dart_pdf/issues
6 -version: 3.8.5 6 +version: 3.9.0
7 7
8 environment: 8 environment:
9 sdk: ">=2.12.0 <3.0.0" 9 sdk: ">=2.12.0 <3.0.0"
@@ -11,9 +11,9 @@ environment: @@ -11,9 +11,9 @@ environment:
11 dependencies: 11 dependencies:
12 archive: ^3.1.0 12 archive: ^3.1.0
13 barcode: ">=2.2.3 <3.0.0" 13 barcode: ">=2.2.3 <3.0.0"
14 - bidi: ^2.0.2 14 + bidi: ^2.0.2
15 crypto: ^3.0.0 15 crypto: ^3.0.0
16 - image: ">=3.0.1 <4.0.0" 16 + image: ^4.0.0
17 meta: ">=1.3.0 <2.0.0" 17 meta: ">=1.3.0 <2.0.0"
18 path_parsing: ">=0.2.0 <2.0.0" 18 path_parsing: ">=0.2.0 <2.0.0"
19 vector_math: ^2.1.0 19 vector_math: ^2.1.0
@@ -179,7 +179,7 @@ void main() { @@ -179,7 +179,7 @@ void main() {
179 )); 179 ));
180 }); 180 });
181 181
182 - test('Container Widgets BoxShadow', () { 182 + test('Container Widgets BoxShadow Rectangle', () {
183 pdf.addPage(Page( 183 pdf.addPage(Page(
184 build: (Context context) => Container( 184 build: (Context context) => Container(
185 margin: const EdgeInsets.all(30), 185 margin: const EdgeInsets.all(30),
@@ -200,6 +200,28 @@ void main() { @@ -200,6 +200,28 @@ void main() {
200 )); 200 ));
201 }); 201 });
202 202
  203 + test('Container Widgets BoxShadow Ellipse', () {
  204 + pdf.addPage(Page(
  205 + build: (Context context) => Container(
  206 + margin: const EdgeInsets.all(30),
  207 + padding: const EdgeInsets.all(20),
  208 + decoration: const BoxDecoration(
  209 + shape: BoxShape.circle,
  210 + boxShadow: <BoxShadow>[
  211 + BoxShadow(
  212 + blurRadius: 4,
  213 + spreadRadius: 10,
  214 + offset: PdfPoint(2, 2),
  215 + ),
  216 + ],
  217 + color: PdfColors.blue,
  218 + ),
  219 + width: 200,
  220 + height: 200,
  221 + ),
  222 + ));
  223 + });
  224 +
203 tearDownAll(() async { 225 tearDownAll(() async {
204 final file = File('widgets-container.pdf'); 226 final file = File('widgets-container.pdf');
205 await file.writeAsBytes(await pdf.save()); 227 await file.writeAsBytes(await pdf.save());
@@ -4,6 +4,7 @@ @@ -4,6 +4,7 @@
4 4
5 - Remove deprecated Android embedding 5 - Remove deprecated Android embedding
6 - Add custom pages builder to PdfPreview widget [Milad akarie] 6 - Add custom pages builder to PdfPreview widget [Milad akarie]
  7 +- Update Image dependency
7 8
8 ## 5.9.3 9 ## 5.9.3
9 10
@@ -24,7 +24,6 @@ import 'dart:ui'; @@ -24,7 +24,6 @@ import 'dart:ui';
24 24
25 import 'package:flutter/foundation.dart'; 25 import 'package:flutter/foundation.dart';
26 import 'package:flutter_web_plugins/flutter_web_plugins.dart'; 26 import 'package:flutter_web_plugins/flutter_web_plugins.dart';
27 -import 'package:image/image.dart' as im;  
28 import 'package:pdf/pdf.dart'; 27 import 'package:pdf/pdf.dart';
29 28
30 import 'src/callback.dart'; 29 import 'src/callback.dart';
@@ -358,11 +357,7 @@ class _WebPdfRaster extends PdfRaster { @@ -358,11 +357,7 @@ class _WebPdfRaster extends PdfRaster {
358 357
359 @override 358 @override
360 Uint8List get pixels { 359 Uint8List get pixels {
361 - if (_pixels == null) {  
362 - final img = im.PngDecoder().decodeImage(png)!;  
363 - _pixels = img.data.buffer.asUint8List();  
364 - }  
365 - 360 + _pixels ??= PdfRasterBase.fromPng(png).pixels;
366 return _pixels!; 361 return _pixels!;
367 } 362 }
368 363
@@ -19,28 +19,16 @@ import 'dart:typed_data'; @@ -19,28 +19,16 @@ import 'dart:typed_data';
19 import 'dart:ui' as ui; 19 import 'dart:ui' as ui;
20 20
21 import 'package:flutter/painting.dart'; 21 import 'package:flutter/painting.dart';
22 -import 'package:image/image.dart' as im; 22 +import 'package:pdf/pdf.dart';
23 23
24 /// Represents a bitmap image 24 /// Represents a bitmap image
25 -class PdfRaster { 25 +class PdfRaster extends PdfRasterBase {
26 /// Create a bitmap image 26 /// Create a bitmap image
27 - const PdfRaster(  
28 - this.width,  
29 - this.height,  
30 - this.pixels,  
31 - );  
32 -  
33 - /// The width of the image  
34 - final int width;  
35 -  
36 - /// The height of the image  
37 - final int height;  
38 -  
39 - /// The raw RGBA pixels of the image  
40 - final Uint8List pixels;  
41 -  
42 - @override  
43 - String toString() => 'Image ${width}x$height ${width * height * 4} bytes'; 27 + PdfRaster(
  28 + int width,
  29 + int height,
  30 + Uint8List pixels,
  31 + ) : super(width, height, true, pixels);
44 32
45 /// Decode RGBA raw image to dart:ui Image 33 /// Decode RGBA raw image to dart:ui Image
46 Future<ui.Image> toImage() { 34 Future<ui.Image> toImage() {
@@ -56,16 +44,12 @@ class PdfRaster { @@ -56,16 +44,12 @@ class PdfRaster {
56 } 44 }
57 45
58 /// Convert to a PNG image 46 /// Convert to a PNG image
  47 + @override
59 Future<Uint8List> toPng() async { 48 Future<Uint8List> toPng() async {
60 final image = await toImage(); 49 final image = await toImage();
61 final data = await image.toByteData(format: ui.ImageByteFormat.png); 50 final data = await image.toByteData(format: ui.ImageByteFormat.png);
62 return data!.buffer.asUint8List(); 51 return data!.buffer.asUint8List();
63 } 52 }
64 -  
65 - /// Returns the image as an [Image] object from the pub:image library  
66 - im.Image asImage() {  
67 - return im.Image.fromBytes(width, height, pixels);  
68 - }  
69 } 53 }
70 54
71 /// Image provider for a [PdfRaster] 55 /// Image provider for a [PdfRaster]
@@ -19,10 +19,10 @@ dependencies: @@ -19,10 +19,10 @@ dependencies:
19 flutter_web_plugins: 19 flutter_web_plugins:
20 sdk: flutter 20 sdk: flutter
21 http: ^0.13.0 21 http: ^0.13.0
22 - image: ">=3.0.1 <4.0.0" 22 + image: ^4.0.0
23 js: ^0.6.3 23 js: ^0.6.3
24 meta: ">=1.3.0 <2.0.0" 24 meta: ">=1.3.0 <2.0.0"
25 - pdf: ^3.7.2 25 + pdf: ^3.9.0
26 plugin_platform_interface: ^2.0.0 26 plugin_platform_interface: ^2.0.0
27 27
28 dev_dependencies: 28 dev_dependencies:
No preview for this file type