flutter图片添加水印-优化

张开发
2026/4/3 16:06:12 15 分钟阅读
flutter图片添加水印-优化
上一篇添加水印的代码有问题在image高版本如4.5.4水印中文字变成乱码花屏。修复后效果添加水印工具类importdart:async;importdart:io;importdart:typed_data;importpackage:util/easy_loading_util.dart;importpackage:flutter/foundation.dart;importpackage:flutter/material.dart;importpackage:image/image.dartasimg;importdart:uiasui;importpackage:path_provider/path_provider.dart;//制造带Logo和文字的水印图片_makeWatermarkImage(Stringstr,double fontSize,img.ImagelogoImage)async{// 调整Logo大小 - 保持原始宽高比只限制高度finallogoHeightfontSize.toInt();finalresizedLogoimg.copyResize(logoImage,height:logoHeight,);finallogoWidthresizedLogo.width;// 创建文字图片finalpicRecorderui.PictureRecorder();finalparagraphBuilderui.ParagraphBuilder(ui.ParagraphStyle(textAlign:TextAlign.left,fontSize:fontSize,),);paragraphBuilder.pushStyle(ui.TextStyle(fontSize:fontSize,color:Colors.white,shadows:Shadow[Shadow(color:Colors.black54,blurRadius:1.0,offset:Offset(1,1),),],),);paragraphBuilder.addText(str);finalparagraphparagraphBuilder.build()..layout(ui.ParagraphConstraints(width:fontSize*15.0));finallineMetricsparagraph.computeLineMetrics();double textWidth0;for(varelementinlineMetrics){if(element.widthtextWidth){textWidthelement.width;}}// 计算总宽度和高度finalspacing(fontSize*0.5).toInt();// Logo和文字之间的间距finaltotalWidthlogoWidthspacingtextWidth;finaltotalHeightlogoHeightparagraph.height?logoHeight:paragraph.height;finalcvsCanvas(picRecorder,Rect.fromLTRB(0,0,totalWidth,totalHeight.toDouble()),);// 计算垂直居中的偏移量finallogoY(totalHeight-logoHeight)/2;finaltextY(totalHeight-paragraph.height)/2;// 绘制Logo左侧// 先将img.Image转换为ui.ImagefinallogoUiImageawait_convertImgImageToUiImage(resizedLogo);if(logoUiImage!null){cvs.drawImage(logoUiImage,Offset(0,logoY),Paint());}// 绘制文字右侧垂直居中cvs.drawParagraph(paragraph,Offset((logoWidthspacing).toDouble(),textY));finalpicpicRecorder.endRecording();finalwaterMarkawaitpic.toImage(totalWidth.toInt(),totalHeight.toInt(),);returnwaterMark;}//将 img.Image 转换为 ui.ImageFutureui.Image?_convertImgImageToUiImage(img.ImageimgImage)async{finalpngBytesimg.encodePng(imgImage);finalcodecawaitui.instantiateImageCodec(pngBytes);finalframeawaitcodec.getNextFrame();returnframe.image;}//将 ui.Image 转换为 img.ImageFutureimg.Image?_convertUiImageToImgImage(ui.ImageuiImage)async{finalbyteDataawaituiImage.toByteData(format:ui.ImageByteFormat.png);if(byteDatanull)returnnull;finalpngBytesbyteData.buffer.asUint8List();returnimg.decodeImage(pngBytes);}//确定水印位置并将水印添加到原图_makeImageMark(img.Imageimage,StringmarkStr,img.ImageimageLogo,[bool isLefttrue,])async{finalimgHeightimage.height;finalimgWidthimage.width;finalratioimgWidth/375.0;finalfontSize(ratio*14.0).toDouble();finaledgeSize(ratio*12.0).toInt();// 创建组合水印Logo 文字finalwaterMarkImageawait_makeWatermarkImage(markStr,fontSize,imageLogo);finalwaterMarkImgawait_convertUiImageToImgImage(waterMarkImage);if(waterMarkImgnull){esLoadingToast(添加水印失败);return;}// 计算位置右下角int dstX;int dstYimgHeight-waterMarkImg.height-edgeSize;if(isLeft){dstXedgeSize;}else{dstXimgWidth-edgeSize-waterMarkImg.width;}// 将水印合成到原图img.compositeImage(image,waterMarkImg,dstX:dstX,dstY:dstY);}/* * 图片左、右下脚添加图片文字水印 * */FutureStringaddWatermarkToImage(Uint8ListuInt8List,{Uint8List?markUInt8List,String?markUserName,})async{CompleterStringcompleterCompleterString();finalmarkLogoawaitgetDecodeImage(markUInt8List!);finaloriginImageawaitgetDecodeImage(uInt8List);Directory?directory;if(Platform.isAndroid){directoryawaitgetExternalStorageDirectory();}elseif(Platform.isIOS){directoryawaitgetApplicationDocumentsDirectory();}else{directoryawaitgetTemporaryDirectory();}finalDirectoryimageDirectoryawaitDirectory(${directory?.path}/image/,).create(recursive:true);StringtargetPathimageDirectory.path;await_makeImageMark(originImage,markUserNamenull?:$markUserName,markLogo,false,);finalbytesimg.encodeJpg(originImage);StringimagePath${targetPath}watermark${DateTime.now().millisecondsSinceEpoch}.jpg;finalsuccessawaitimg.writeFile(imagePath,bytes);if(successtrue){completer.complete(imagePath);print(targetFilePath$imagePath);}else{completer.complete();}returncompleter.future;}getDecodeImage(Uint8ListuInt8List){Completerimg.ImagecompleterCompleterimg.Image();img.Image?originImageimg.decodeImage(uInt8List);if(originImagenull){throwException(图片解码失败);}completer.complete(originImage);returncompleter.future;}调用//获取水印图标FutureUint8ListgetWatermarkLogo()async{finalfawaitrootBundle.load(PathConfig.iconWatermark);DEBUG.show(图片数据${f.buffer.asUint8List()});Uint8ListmarkUint8Listf.buffer.asUint8List();returnFuture.value(markUint8List);}//图片添加水印addWatermarkToImages()async{waterImages.clear();watermarkUint8ListawaitgetWatermarkLogo();if(addWaterMarkstate.selectImageList.isNotEmpty){ByteDatabyteData;for(int i0;istate.selectImageList.length;i){// Asset asset state.selectImageList[i];// byteData await asset.getByteData();Filefilestate.selectImageList[i];// Uint8List uint8ListData byteData.buffer.asUint8List();Uint8Listuint8ListDatafile.readAsBytesSync();StringwatermarkImagePathawaitaddWatermarkToImage(uint8ListData,markUInt8List:watermarkUint8List,markUserName:userInfo.user!.nickname);if(watermarkImagePath.isNotEmpty){waterImages.add(watermarkImagePath);print(waterImages length$i${waterImages.length});}}//发布submit();update();}}

更多文章