image - 在 Flutter 移动应用中添加图像水印
问题描述
我一直在查看图像包示例。绘制图像的示例使用 dart:html 包。
我设法通过图像和 dart:ui 的组合得到了一些东西,但它运行得非常慢。有谁知道什么可能是更好的方法?
final double canvasWidth = canvasImage.width.toDouble();
final double canvasHeight = canvasImage.height.toDouble();
final ui.Paint paint = ui.Paint();
final recorder = ui.PictureRecorder();
final canvas = ui.Canvas(
recorder,
ui.Rect.fromPoints(
ui.Offset(0.0, 0.0),
ui.Offset(canvasWidth, canvasHeight),
),
);
// draw image to background
ui.Codec backgroundCodec =
await ui.instantiateImageCodec(img.encodePng(canvasImage));
final ui.FrameInfo backgroundFrameInfo =
await backgroundCodec.getNextFrame();
final ui.Image backgroundImage = backgroundFrameInfo.image;
canvas.drawImage(backgroundImage, ui.Offset(0.0, 0.0), paint);
// Add watermark
// Get watermark from assets
final ByteData watermarkBytes =
await rootBundle.load("images/watermark.png");
img.Image originalWatermark =
img.decodeImage(watermarkBytes.buffer.asUint8List());
// resize the watermark to 1/6th of the smallest dimension (the watermark is a square)
final int watermarkDimension =
(min(canvasWidth, canvasHeight) / 6).floor();
img.Image resizeImage = img.copyResize(originalWatermark,
height: watermarkDimension, width: watermarkDimension);
ui.Codec watermarkCodec =
await ui.instantiateImageCodec(img.encodePng(resizeImage));
final ui.FrameInfo watermarkFrameInfo =
await watermarkCodec.getNextFrame();
// get ui image
ui.Image watermarkImage = watermarkFrameInfo.image;
// draw watermark to the canvas
canvas.drawImage(watermarkImage, ui.Offset(0.0, 0.0), paint);
// export the recording
ui.Picture pic = recorder.endRecording();
ui.Image finalImage =
await pic.toImage(canvasWidth.floor(), canvasHeight.floor());
ByteData finalByteData =
await finalImage.toByteData(format: ui.ImageByteFormat.png);
解决方案
我遇到的是使用图像库很慢,或者,我使用 RepaintBoundary 来截取某个小部件:
用一个键将你的小部件包装在 RepaintBoundary 内
RepaintBoundary(
key: _repaintKey,
child: Stack(
alignment: Alignment.bottomRight,
children: <Widget>[
Image.asset(
'images/food01.jpeg',
fit: BoxFit.cover,
),
Icon(Icons.translate,),
],
),
)
然后写入字节:
RenderRepaintBoundary boundary =
_repaintKey.currentContext.findRenderObject();
ui.Image image = await boundary.toImage();
ByteData byteData = await image.toByteData(format: ui.ImageByteFormat.png);
Uint8List pngBytes = byteData.buffer.asUint8List();
File(tempPath).writeAsBytes(pngBytes);
推荐阅读
- ios - 使用 CoreML 推断金属纹理子区域
- windows - 在没有 Chocolatey 的情况下安装 Meteor.js
- javascript - 如何使用 Express-Validato 验证出生日期?
- c# - c# Xamarin - System.IO.FileNotFoundException
- liferay - 我可以在 1&1 上使用 Liferay 门户吗?
- java - Java hashCode 方法是否同时进行转换和压缩?
- javascript - Asp 和 javascript 错误:消息:预期的 ')'
- java - 通过用户输入从控制台按模式搜索文件 - java
- javascript - 在javascript中创建更深的颜色?
- java - 删除链表中的元素