Flutter从URL下载SVG图片遇PlatformException问题求助
SVG图片保存失败问题解决
我用代码从URL下载SVG图片转成Uint8List后,用ImageGallerySaver保存时触发如下错误:
PlatformException (PlatformException(error, decodeByteArray(image, 0, image.size) must not be null, null, java.lang.NullPointerException: decodeByteArray(image, 0, image.size) must not be null
同样的代码保存PNG格式图片完全正常,相关代码如下:
调用逻辑
String url = 'https://qodevault-staging.s3.us-east-2.amazonaws.com/qrcodes/6136f35c3a5e9824329fdd8166d01715.svg' final bytes = await kNetworkImageToBytes(url); kSaveImageFromBytes(imgData: bytes, name: 'qrcode');
网络图片转字节函数
///converts network image (Except for svg) to [Uint8List] Future<Uint8List> kNetworkImageToBytes(String imageUrl) async { try { var response = await Dio().get( imageUrl, options: Options(responseType: ResponseType.bytes), ); return Uint8List.fromList(response.data); } catch (e) { rethrow; } }
图片保存函数
Future<void> kSaveImageFromBytes({ required Uint8List imgData, required String name, bool appendRandomString = true, }) async { final random = generateRandomString(10); final filename = appendRandomString ? '${name}_$random' : name; final bool hasPermission = await PermissionHandler.requestPermission(Permission.storage); if (!hasPermission) throw 'Permission not granted'; final result = await ImageGallerySaver.saveImage( imgData, quality: 100, name: 'QV_$filename', ); print(result); if (result is Map) { if (result['isSuccess'].toString() == 'false') { throw 'Error saving image'; } } }
问题原因与解决方案
原因
ImageGallerySaver仅支持保存PNG/JPG这类位图格式的字节数据,而SVG是矢量图格式,无法直接被它解码处理,因此抛出空指针异常。
解决步骤
需要先将SVG矢量图渲染成位图(比如PNG),再进行保存,具体实现如下:
- 添加SVG渲染依赖
在pubspec.yaml中加入flutter_svg依赖(版本请根据你的Flutter版本选择兼容的最新版):
dependencies: flutter_svg: ^2.0.9
- 新增SVG转PNG的工具函数
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter/services.dart'; Future<Uint8List> svgBytesToPngBytes(Uint8List svgBytes) async { // 解析SVG字节数据 final svgDrawableRoot = await svg.fromSvgBytes(svgBytes, ''); // 指定渲染尺寸(可根据需求调整) final picture = svgDrawableRoot.toPicture(size: const Size(300, 300)); // 转换为Image对象 final image = await picture.toImage(300, 300); // 导出为PNG字节数据 final byteData = await image.toByteData(format: ImageByteFormat.png); return byteData!.buffer.asUint8List(); }
- 修改调用逻辑
String url = 'https://qodevault-staging.s3.us-east-2.amazonaws.com/qrcodes/6136f35c3a5e9824329fdd8166d01715.svg'; // 下载SVG字节 final svgBytes = await kNetworkImageToBytes(url); // 转换为PNG字节 final pngBytes = await svgBytesToPngBytes(svgBytes); // 保存图片 await kSaveImageFromBytes(imgData: pngBytes, name: 'qrcode');
内容的提问来源于stack exchange,提问作者Sujan Gainju
相关产品推荐
相关产品推荐

