颤振 - 将混合模式保存到图像



我正在尝试实现一个UI,用户可以在其中编辑效果并将其应用于上传的图像,并希望保存合并到图像的BlendMode。是否可以保存混合图像的结果或使用画布应用它?

有一些包应用了一些特定的过滤器,但我希望为最终用户提供更可定制的东西。

我已经看到了一些如何实现 Canvas 来绘制图像的示例,但无法弄清楚如何使用加载图像并应用文档中相关的混合。有人可以举个例子吗?

更新:

对于有相同问题的人,下面遵循代码,介绍如何将图像从画布保存到应用 blendMode 的文件。 但我仍然没有预期的结果。生成的图像质量与原始图像不同,混合似乎也不是我应用的混合。而且我不能另存为 jpg,只能另存为 png 文件。

那么,如何在不损失质量的情况下加载图像、应用与画布的混合并另存为 jpg 文件呢?

法典:

const kCanvasSize = 200.0;
class CanvasImageToFile {
CanvasImageToFile._();
static final instance = CanvasImageToFile._();
ByteData _readFromFile(File file) {
// File file = getSomeCorrectFile();
Uint8List bytes = file.readAsBytesSync();
return ByteData.view(bytes.buffer);
}
Future<File> _writeToFile(ByteData data) async {
String dir = (await getTemporaryDirectory()).path;
String filePath = '$dir/tempImage.jpg';
final buffer = data.buffer;
return new File(filePath).writeAsBytes(
buffer.asUint8List(data.offsetInBytes, data.lengthInBytes));
}
Future<ui.Image> _loadImageSource(File imageSource) async {
// ByteData data = await rootBundle.load(asset);
ByteData data = _readFromFile(imageSource);
ui.Codec codec = await ui.instantiateImageCodec(data.buffer.asUint8List());
ui.FrameInfo fi = await codec.getNextFrame();
return fi.image;
}
Future<File> generateImage(File imageSource) async {
File imageResult;
ui.Image image;
await _loadImageSource(imageSource).then((value) {
image = value;
});
if (image != null) {
final recorder = ui.PictureRecorder();
var rect =
Rect.fromPoints(Offset(0.0, 0.0), Offset(kCanvasSize, kCanvasSize));
final canvas = Canvas(recorder, rect);
Size outputSize = rect.size;
Paint paint = new Paint();
//OVERLAY - BlendMode uses the previously drawn content as a mask
paint.blendMode = BlendMode.colorBurn;
paint.color = Colors.red;
// paint.colorFilter = ColorFilter.mode(Colors.blue, BlendMode.colorDodge);
// paint = Paint()..color = Colors.red;
// paint = Paint()..blendMode = BlendMode.multiply;
//Image
Size inputSize = Size(image.width.toDouble(), image.height.toDouble());
final FittedSizes fittedSizes =
applyBoxFit(BoxFit.cover, inputSize, outputSize);
final Size sourceSize = fittedSizes.source;
final Rect sourceRect =
Alignment.center.inscribe(sourceSize, Offset.zero & inputSize);
canvas.saveLayer(rect, paint);
canvas.drawImageRect(
image, sourceRect, rect, paint);
canvas.restore();
final picture = recorder.endRecording();
final img = await picture.toImage(200, 200);
final byteData = await img.toByteData(format: ImageByteFormat.png);
await _writeToFile(byteData).then((value) {
imageResult = value;
});
return imageResult;
}

经过一些研究,在我以前的代码中使用(位图包(将图像从 png 解码为 rawUnmodified 进行了一些调整,我可以以原始格式 (jpg( 保存图像并实现我想要的。如果有人有同样的问题,bellow 按照代码加载带有画布的图像,应用混合并写入具有相同质量的文件:

Future<File> generateImage(
File imageSource, Color color, BlendMode blendMode) async {
File imageResult;
ui.Image image;
await _loadImageSource(imageSource).then((value) {
image = value;
});
if (image != null) {
final recorder = ui.PictureRecorder();
var rect = Rect.fromPoints(Offset(0.0, 0.0),
Offset(image.width.toDouble(), image.height.toDouble()));
final canvas = Canvas(recorder, rect);
Size outputSize = rect.size;
Paint paint = new Paint();
//OVERLAY - BlendMode uses the previously drawn content as a mask
// paint.blendMode = blendMode;
// paint.color = color;
paint.colorFilter = ColorFilter.mode(color, blendMode);
//Image
Size inputSize = Size(image.width.toDouble(), image.height.toDouble());
final FittedSizes fittedSizes =
applyBoxFit(BoxFit.contain, inputSize, outputSize);
final Size sourceSize = fittedSizes.source;
final Rect sourceRect =
Alignment.center.inscribe(sourceSize, Offset.zero & inputSize);
canvas.drawImageRect(image, sourceRect, rect, paint);
final picture = recorder.endRecording();
final img = await picture.toImage(image.width, image.height);
ByteData byteData =
await img.toByteData(format: ui.ImageByteFormat.rawUnmodified);
Bitmap bitmap = Bitmap.fromHeadless(
image.width, image.height, byteData.buffer.asUint8List());
Uint8List headedIntList = bitmap.buildHeaded();
await _writeToFile(headedIntList.buffer.asByteData()).then((value) {
imageResult = value;
});
return imageResult;
}
}

最新更新