Flutter-将BlendMode保存到图像

问题描述 投票:0回答:1

我正在尝试实现一个用户界面,用户可以在其中编辑和应用效果到上传的图像,并希望保存合并到图像的BlendMode。是否可以保存融合图像的结果或使用Canvas应用它?

有些应用某些特定过滤器的软件包,但我希望为最终用户提供更多可定制的内容。

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

UPDATED:

对于谁有相同的问题,贝娄遵循以下代码,说明如何将图像从画布保存到应用了blendMode的文件中。但是我仍然没有得到预期的结果。生成的图像的质量与原始图像不同,两种混合似乎都不是我应用的混合。而且我无法另存为jpg和png文件。

所以,如何在不损失画质的情况下加载图像,应用画布混合并另存为jpg文件?

CODE:

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;
    }
image flutter canvas jpeg blend
1个回答
0
投票

经过一些研究,有些人使用(Bitmap包)调整了将图像从png解码为rawUnmodified的代码,我可以将图像保存为原始格式(jpg)并达到我想要的效果。如果有人有相同的问题,贝娄会遵循以下代码以使用画布加载图像,应用混合并以相同的质量写入文件:

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;
    }
  }
© www.soinside.com 2019 - 2024. All rights reserved.