解决Flutter分享微信小程序图片清晰度问题
背景:最近做flutter项目,做微信分享小程序,小程序卡片图片很模糊,经过排查确定了问题以及解决方法,排查思路记录一下。分享微信所用的flutter插件是fluwx^4.4.9
- 刚开始用的是Canvas画布绘制,思考,如果是画布的话出现图片模糊一般是绘制图片的画布比较小,而显示比较大,图片从小放大,会导致图片模糊,且画布绘图比较繁琐。经过调整保存本地发现图片清晰度有提升但未达到理想清晰度
- 转变思路,Flutter自带快照控件RepaintBoundary,思路是通过将要截图的Widget通过Stack放在主页面之下,然后执行快照。得到的图片清晰度很高
- 最终两个方案采用第二种得到了理想的清晰度图片,并且保存到相册核查,清晰度很好了,然后开开心心的去分享去,fluwx代码:
// 微信分享初始化插件
Fluwx fluwx = Fluwx();
state.fluwx.registerApi(
appId: "你的微信开放平台对应项目的APPID",
doOnAndroid: true,
doOnIOS: true,
universalLink: "苹果端universalLink地址",
);
// 分享部分代码:WeChatImage有四种模式:network、asset、file、binary
WeChatShareMiniProgramModel model = WeChatShareMiniProgramModel(
//原始id(gh_5e56a391f33c)不是appid(wxe0338d0acbe46db9)
userName: "小程序ID",
webPageUrl: "${state.url}",
path: "小程序提供地址,在这里给小程序传参也在这里",
title: "小程序标题",
miniProgramType: WXMiniProgramType.release,
compressThumbnail: Platform.isAndroid ? false : true,// 图片是否压缩
thumbnail: WeChatImage.binary(state.shareToWeChatImageSource!),
hdImagePath: WeChatImage.binary(state.shareToWeChatImageSource!),
);
state.fluwx.share(model);
同时这里也贴一下生成快照的代码
// 保存相册方法
Future savePhoto(BuildContext context, GlobalKey key,
{bool shareToWechat = false}) async {
showDialog(
context: context,
useRootNavigator: true,
barrierDismissible: false,
builder: (buildContext) {
state.dialogContext = buildContext;
return LoadingDialog(
outsideDismiss: false,
loadingText: '正在生成...',
);
});
var photosStatus = await Permission.photos.request();
var storageStatus = await Permission.storage.request();
RenderRepaintBoundary? boundary =
key.currentContext!.findRenderObject() as RenderRepaintBoundary?;
double dpr = MediaQuery.of(context).devicePixelRatio; // 获取当前设备的像素比
ui.Image image = await boundary!.toImage(pixelRatio: dpr);
// 将image转化成byte
ByteData? byteData = await image.toByteData(format: ImageByteFormat.png);
Uint8List pngBytes = byteData!.buffer.asUint8List();
if (shareToWechat == false) {
if (photosStatus.isGranted == true ||
(storageStatus.isGranted == true && Platform.isAndroid)) {
Map result = await ImageGallerySaver.saveImage(pngBytes, quality: 100);
bool isSaveSuccess = result['isSuccess'];
dismissLoading();
if (isSaveSuccess) {
MyCommonUtils.showToast("保存成功!");
} else {
MyCommonUtils.showToast("保存失败!");
}
} else {
dismissLoading();
MyCommonUtils.showToast("请打开设置打开保存相册的权限~");
openAppSettings();
}
} else {
if (Platform.isIOS) {
state.shareToWeChatImageSource = pngBytes;
} else {
Directory documentsDir = await getApplicationDocumentsDirectory();
Directory directory = Directory('${documentsDir.path}/flutter');
if (!directory.existsSync()) {
directory.createSync();
}
const filename = 'fenxiang.png';
File file = File('${directory.path}/$filename')
..createSync(recursive: true)
..writeAsBytesSync(pngBytes);
Uint8List? pngBytes1 = await FlutterImageCompress.compressWithFile(
file.absolute.path,
minWidth: image.width,
minHeight: image.height,
quality: 30,
);
print('=========长度${pngBytes1?.length}');
state.shareToWeChatImageSource = pngBytes1;
}
dismissLoading();
}
}
这里需要做一下差异化,fluwx在iOS和安卓的压缩图片是不一样的,iOS这边比较清晰,安卓比较模糊需要自己压缩,然后同时设置微信参数在安卓端不压缩,至此,分享清晰度问题搞定。
注意:fluwx传的图片不管是图片地址还是二进制流,都不能超过128KB