0

在 Flutter 中,不使用 Image 包更改具有 ui.Image 类型的图像的像素数据的正确方法是什么?我可以使用 Image 包更新像素,但我不想多次转换图像。所以我正在尝试探索更新 Uint8List 数据的可能性。下面是代码片段。但是,当我尝试使用操纵的 Uint8List 更新图像时,我得到了“异常:无效的图像数据”。想知道我做错了什么吗?感谢任何反馈。

int clamp(int x, int a, int b) {
    return (x < a)
        ? a
        : (x > b)
            ? b
            : x;
  }

int getColorY(int a, int r, int g, int b ) =>
      (clamp(a, 0, 255) << 24) |
      (clamp(r, 0, 255) << 16) |
      (clamp(g, 0, 255) << 8) |
      (clamp(b, 0, 255));

 Future<ui.Image> setImageData(ui.Image uiX) async 

    int w = uiX.width;
    int h = uiX.height;

    //get byteData

    final rgbaImageData =
           await uiX.toByteData(format: ui.ImageByteFormat.png);

    // convert to Uint32

    Uint32List words = Uint32List.view(
        rgbaImageData.buffer,
        rgbaImageData.offsetInBytes,
        rgbaImageData.lengthInBytes ~/ Uint32List.bytesPerElement);
   
    int a = 0;
    int r = 0;
    int g = 0;
    int b = 0;

    for (int idx = 0; idx < words.length; idx++) {
      Color color = Color(words[idx]);

      if (color.red > 128) {
         a = 0;
      } else {
        r = 128;
        g = 135;
        b = 110;
   
      }
      words[idx] = getColorY(a, r, g, b);
    }
    //convert Uint32List to Uint8List 

    Uint8List bytes = words.buffer.asUint8List();
   
    final Completer<ui.Image> imageCompleter = new Completer();
    ui.decodeImageFromList(bytes, (ui.Image img) {
      imageCompleter.complete(img);
    });
    return imageCompleter.future;
  }
4

1 回答 1

0

您可以转换ui.Image为原始字节数据,对其进行操作,然后将其转换回ui.Image使用ui.imageFromBytes.

final ui.Image image = ...;

// Convert to raw rgba
final ByteData bytes = image.toByteData(format: 
  ImageByteFormat.rawRgba,
);

// Set the first pixel of the image to red.
bytes.setUint32(0, 0xFF0000FF);

// Set pixel at (x, y) to green.
final x = 10;
final y = 10;
bytes.setUint32((y * image.width + x) * 4, 0x00FF00FF);

ui.decodeImageFromPixels(
  bytes.buffer.asUint8List(),
  image.width,
  image.height,
  ui.PixelFormat.rgba8888,
  (ui.Image result) {
    // use your result image
  },
);

您的代码中的错误部分是:

final rgbaImageData = await uiX.toByteData(format: ui.ImageByteFormat.png);

Asformat:指定返回字节的格式。所以,你必须通过ui.ImageByteFormat.rawRgba

此外,Color(int)需要 ARGB 格式而不是 RGBA。

于 2021-07-20T10:29:40.037 回答