David PHAM-VAN

Add imageFromAssetBundle and networkImage

1 # Changelog 1 # Changelog
2 2
  3 +## 5.0.0-nullsafety.2
  4 +
  5 +- Add imageFromAssetBundle and networkImage
  6 +
3 ## 5.0.0-nullsafety.1 7 ## 5.0.0-nullsafety.1
4 8
5 - Fix PdfPreview default locale 9 - Fix PdfPreview default locale
@@ -46,16 +46,15 @@ doc.addPage(pw.Page( @@ -46,16 +46,15 @@ doc.addPage(pw.Page(
46 pageFormat: PdfPageFormat.a4, 46 pageFormat: PdfPageFormat.a4,
47 build: (pw.Context context) { 47 build: (pw.Context context) {
48 return pw.Center( 48 return pw.Center(
49 - child: pw.Text("Hello World"), 49 + child: pw.Text('Hello World'),
50 ); // Center 50 ); // Center
51 })); // Page 51 })); // Page
52 ``` 52 ```
53 53
54 -To load an image from an ImageProvider: 54 +To load an image from a Flutter asset:
55 55
56 ```dart 56 ```dart
57 -const imageProvider = const AssetImage('assets/image.png');  
58 -final image = await flutterImageProvider(imageProvider); 57 +final image = await imageFromAssetBundle('assets/image.png');
59 58
60 doc.addPage(pw.Page( 59 doc.addPage(pw.Page(
61 build: (pw.Context context) { 60 build: (pw.Context context) {
@@ -68,8 +67,7 @@ doc.addPage(pw.Page( @@ -68,8 +67,7 @@ doc.addPage(pw.Page(
68 To use a TrueType font from a flutter bundle: 67 To use a TrueType font from a flutter bundle:
69 68
70 ```dart 69 ```dart
71 -final font = await rootBundle.load("assets/open-sans.ttf");  
72 -final ttf = pw.Font.ttf(font); 70 +final ttf = await fontFromAssetBundle('assets/open-sans.ttf');
73 71
74 doc.addPage(pw.Page( 72 doc.addPage(pw.Page(
75 build: (pw.Context context) { 73 build: (pw.Context context) {
@@ -83,7 +81,7 @@ To save the pdf file using the [path_provider](https://pub.dev/packages/path_pro @@ -83,7 +81,7 @@ To save the pdf file using the [path_provider](https://pub.dev/packages/path_pro
83 81
84 ```dart 82 ```dart
85 final output = await getTemporaryDirectory(); 83 final output = await getTemporaryDirectory();
86 -final file = File("${output.path}/example.pdf"); 84 +final file = File('${output.path}/example.pdf');
87 await file.writeAsBytes(await doc.save()); 85 await file.writeAsBytes(await doc.save());
88 ``` 86 ```
89 87
@@ -15,10 +15,13 @@ @@ -15,10 +15,13 @@
15 */ 15 */
16 16
17 import 'dart:async'; 17 import 'dart:async';
  18 +import 'dart:io';
  19 +import 'dart:typed_data';
18 import 'dart:ui' as ui; 20 import 'dart:ui' as ui;
19 21
20 import 'package:flutter/rendering.dart' as rdr; 22 import 'package:flutter/rendering.dart' as rdr;
21 import 'package:flutter/services.dart'; 23 import 'package:flutter/services.dart';
  24 +import 'package:pdf/pdf.dart';
22 import 'package:pdf/widgets.dart'; 25 import 'package:pdf/widgets.dart';
23 26
24 /// Loads an image from a Flutter [ImageProvider] 27 /// Loads an image from a Flutter [ImageProvider]
@@ -63,7 +66,108 @@ Future<ImageProvider> flutterImageProvider( @@ -63,7 +66,108 @@ Future<ImageProvider> flutterImageProvider(
63 66
64 /// Loads a font from an asset bundle key. If used multiple times with the same font name, 67 /// Loads a font from an asset bundle key. If used multiple times with the same font name,
65 /// it will be included multiple times in the pdf file 68 /// it will be included multiple times in the pdf file
66 -Future<TtfFont> fontFromAssetBundle(String key, AssetBundle bundle) async { 69 +Future<TtfFont> fontFromAssetBundle(String key, [AssetBundle? bundle]) async {
  70 + bundle ??= rootBundle;
67 final data = await bundle.load(key); 71 final data = await bundle.load(key);
68 return TtfFont(data); 72 return TtfFont(data);
69 } 73 }
  74 +
  75 +/// Load an image from an asset bundle key.
  76 +Future<ImageProvider> imageFromAssetBundle(String key,
  77 + [AssetBundle? bundle]) async {
  78 + bundle ??= rootBundle;
  79 + final data = await bundle.load(key);
  80 + return MemoryImage(data.buffer.asUint8List());
  81 +}
  82 +
  83 +final HttpClient _sharedHttpClient = HttpClient();
  84 +
  85 +/// Store network images in a cache
  86 +abstract class PdfBaseImageCache {
  87 + /// Create a network image cache
  88 + const PdfBaseImageCache();
  89 +
  90 + /// The default cache used when none specified
  91 + static final defaultCache = PdfMemoryImageCache();
  92 +
  93 + /// Add an image to the cache
  94 + Future<void> add(String key, Uint8List bytes);
  95 +
  96 + /// Retrieve an image from the cache
  97 + Future<Uint8List?> get(String key);
  98 +
  99 + /// Does the cache contains this image?
  100 + Future<bool> contains(String key);
  101 +
  102 + /// Remove an image from the cache
  103 + Future<void> remove(String key);
  104 +
  105 + /// Clear the cache
  106 + Future<void> clear();
  107 +}
  108 +
  109 +/// Memory image cache
  110 +class PdfMemoryImageCache extends PdfBaseImageCache {
  111 + /// Create a memory image cache
  112 + PdfMemoryImageCache();
  113 +
  114 + final _imageCache = <String, Uint8List>{};
  115 +
  116 + @override
  117 + Future<void> add(String key, Uint8List bytes) async {
  118 + _imageCache[key] = bytes;
  119 + }
  120 +
  121 + @override
  122 + Future<Uint8List?> get(String key) async {
  123 + return _imageCache[key];
  124 + }
  125 +
  126 + @override
  127 + Future<void> clear() async {
  128 + _imageCache.clear();
  129 + }
  130 +
  131 + @override
  132 + Future<bool> contains(String key) async {
  133 + return _imageCache.containsKey(key);
  134 + }
  135 +
  136 + @override
  137 + Future<void> remove(String key) async {
  138 + _imageCache.remove(key);
  139 + }
  140 +}
  141 +
  142 +/// Download an image from the network.
  143 +Future<ImageProvider> networkImage(
  144 + String url, {
  145 + bool cache = true,
  146 + Map<String, String>? headers,
  147 + PdfImageOrientation? orientation,
  148 + double? dpi,
  149 + PdfBaseImageCache? imageCache,
  150 +}) async {
  151 + imageCache ??= PdfBaseImageCache.defaultCache;
  152 +
  153 + if (cache && await imageCache.contains(url)) {
  154 + return MemoryImage((await imageCache.get(url))!,
  155 + orientation: orientation, dpi: dpi);
  156 + }
  157 +
  158 + final request = await _sharedHttpClient.getUrl(Uri.parse(url));
  159 + headers?.forEach((String name, String value) {
  160 + request.headers.add(name, value);
  161 + });
  162 + final response = await request.close();
  163 + final builder = await response.fold(
  164 + BytesBuilder(), (BytesBuilder b, List<int> d) => b..add(d));
  165 + final List<int> data = builder.takeBytes();
  166 + final bytes = Uint8List.fromList(data);
  167 +
  168 + if (cache) {
  169 + await imageCache.add(url, bytes);
  170 + }
  171 +
  172 + return MemoryImage(bytes, orientation: orientation, dpi: dpi);
  173 +}
@@ -4,7 +4,7 @@ description: Plugin that allows Flutter apps to generate and print documents to @@ -4,7 +4,7 @@ description: Plugin that allows Flutter apps to generate and print documents to
4 homepage: https://github.com/DavBfr/dart_pdf/tree/master/printing 4 homepage: https://github.com/DavBfr/dart_pdf/tree/master/printing
5 repository: https://github.com/DavBfr/dart_pdf 5 repository: https://github.com/DavBfr/dart_pdf
6 issue_tracker: https://github.com/DavBfr/dart_pdf/issues 6 issue_tracker: https://github.com/DavBfr/dart_pdf/issues
7 -version: 5.0.0-nullsafety.1 7 +version: 5.0.0-nullsafety.2
8 8
9 environment: 9 environment:
10 sdk: ">=2.12.0-0 <3.0.0" 10 sdk: ">=2.12.0-0 <3.0.0"