How can I convert CameraImageStream CameraImage to jpeg or bitmap in Flutter using Flutter's image-processing libraries?

huangapple go评论84阅读模式
英文:

How can I convert CameraImageStream CameraImage to jpeg or bitmap in Flutter using Flutter's image-processing libraries?

问题

I can help with the translation of the code you provided. Here's the translated code:

无法将CameraImage从bgra8888转换为jpeg
我已经尝试了不同的方法,但都不起作用。

我最后尝试的是:

```dart
void testB(CameraImage i) async {

    cameraRepository.stopRecording();

    print(i.format.group);

    imglib.Image im = imglib.Image.fromBytes(
      width: (i.planes[0].bytesPerRow / 4).round(),
      height: i.height,
      bytes: (i.planes[0].bytes).buffer);

    imglib.PngEncoder pngEncoder = new imglib.PngEncoder();

    Uint8List png = pngEncoder.encode(im);

    //Uint8List jpeg = imglib.encodeJpg(im);

    imageList.add(png);

当我像这样在小部件中显示它:

return Scaffold(
          appBar: AppBar(
            title: const Text('Test'),
          ),
          body: ListView.builder(
          itemCount: 1,
          itemBuilder: (BuildContext context, int index) {
            return SizedBox(width:500, height:500, child: Container(
              decoration: BoxDecoration(
                image: new DecorationImage(fit: BoxFit.cover, image: MemoryImage(BlocProvider.of<CameraBloc>(context).imageList[0], scale: 0.5)),
        )
            ));
          }),
        );

图像会显示出来,但是转换似乎有问题:

图片链接

(这是我的键盘,所以图像不是完全的噪音)。

我尝试了这段代码:

import 'package:image/image.dart' as imglib;
import 'package:camera/camera.dart';

Future<List<int>> convertImagetoPng(CameraImage image) async {
  try {
    imglib.Image img;
    if (image.format.group == ImageFormatGroup.yuv420) {
      img = _convertYUV420(image);
    } else if (image.format.group == ImageFormatGroup.bgra8888) {
      img = _convertBGRA8888(image);
    }

    imglib.PngEncoder pngEncoder = new imglib.PngEncoder();

    // 转换为png
    List<int> png = pngEncoder.encodeImage(img);
    return png;
  } catch (e) {
    print(">>>>>>>>>> ERROR:" + e.toString());
  }
  return null;
}

// CameraImage BGRA8888 -> PNG
// 颜色
imglib.Image _convertBGRA8888(CameraImage image) {
  return imglib.Image.fromBytes(
    image.width,
    image.height,
    image.planes[0].bytes,
    format: imglib.Format.bgra,
  );
}

// CameraImage YUV420_888 -> PNG -> Image(压缩:0,过滤器:无)
// 黑色
imglib.Image _convertYUV420(CameraImage image) {
  var img = imglib.Image(image.width, image.height); // 创建图像缓冲区

  Plane plane = image.planes[0];
  const int shift = (0xFF << 24);

  // 使用YUV420_888的plane[0]填充图像缓冲区
  for (int x = 0; x < image.width; x++) {
    for (int planeOffset = 0;
        planeOffset < image.height * image.width;
        planeOffset += image.width) {
      final pixelColor = plane.bytes[planeOffset + x];
      // 颜色:0x FF  FF  FF  FF
      //          A   B   G   R
      // 计算像素颜色
      var newVal = shift | (pixelColor << 16) | (pixelColor << 8) | pixelColor;

      img.data[planeOffset + x] = newVal;
    }
  }

  return img;
}

但似乎已经过时。尝试时出现不同的错误。

更新

imglib.Image im = imglib.Image.fromBytes(
      width: (i.planes[0].bytesPerRow / 4).round(),
      height: i.height,
      bytes: (i.planes[0].bytes).buffer);

将高度更改为宽度,宽度更改为高度后,图像不会更清晰,几乎是好的。我搞混了这一点,因为看起来似乎不对。

但仍然不好。


Please note that the code comments have also been translated for your convenience.

<details>
<summary>英文:</summary>

I cant convert CameraImage from bgra8888 to an jpeg.
I have found different approaches but none of them work.

The last what I tried is:


void testB(CameraImage i) async {

cameraRepository.stopRecording();

print(i.format.group);

imglib.Image im = imglib.Image.fromBytes(
  width: (i.planes[0].bytesPerRow / 4).round(),
  height: i.height,
  bytes: (i.planes[0].bytes).buffer);

imglib.PngEncoder pngEncoder = new imglib.PngEncoder();

Uint8List png = pngEncoder.encode(im);

//Uint8List jpeg = imglib.encodeJpg(im);

imageList.add(png);

When I display it in a widget like this:


return Scaffold(
appBar: AppBar(
title: const Text('Test'),
),
body: ListView.builder(
itemCount: 1,
itemBuilder: (BuildContext context, int index) {
return SizedBox(width:500, height:500, child: Container(
decoration: BoxDecoration(
image: new DecorationImage(fit: BoxFit.cover, image: MemoryImage(BlocProvider.of<CameraBloc>(context).imageList[0], scale: 0.5)),
)
));
}),
);


I images shows up, but something is wrong with the conversion:

https://pasteboard.co/5yMYpLFxsPkR.jpg

(Thats my Keyboard, so the image isnt complete Noise).



I&#39;ve tried this code:


import 'package:image/image.dart' as imglib;
import 'package:camera/camera.dart';

Future<List<int>> convertImagetoPng(CameraImage image) async {
try {
imglib.Image img;
if (image.format.group == ImageFormatGroup.yuv420) {
img = _convertYUV420(image);
} else if (image.format.group == ImageFormatGroup.bgra8888) {
img = _convertBGRA8888(image);
}

imglib.PngEncoder pngEncoder = new imglib.PngEncoder();

// Convert to png
List&lt;int&gt; png = pngEncoder.encodeImage(img);
return png;

} catch (e) {
print(">>>>>>>>>>>> ERROR:" + e.toString());
}
return null;
}

// CameraImage BGRA8888 -> PNG
// Color
imglib.Image _convertBGRA8888(CameraImage image) {
return imglib.Image.fromBytes(
image.width,
image.height,
image.planes[0].bytes,
format: imglib.Format.bgra,
);
}

// CameraImage YUV420_888 -> PNG -> Image (compresion:0, filter: none)
// Black
imglib.Image _convertYUV420(CameraImage image) {
var img = imglib.Image(image.width, image.height); // Create Image buffer

Plane plane = image.planes[0];
const int shift = (0xFF << 24);

// Fill image buffer with plane[0] from YUV420_888
for (int x = 0; x < image.width; x++) {
for (int planeOffset = 0;
planeOffset < image.height * image.width;
planeOffset += image.width) {
final pixelColor = plane.bytes[planeOffset + x];
// color: 0x FF FF FF FF
// A B G R
// Calculate pixel color
var newVal = shift | (pixelColor << 16) | (pixelColor << 8) | pixelColor;

  img.data[planeOffset + x] = newVal;
}

}

return img;
}


But it seems outdated. Got different errors when i tried it.

**UPDATE**

    imglib.Image im = imglib.Image.fromBytes(
      width: (i.planes[0].bytesPerRow / 4).round(),
      height: i.height,
      bytes: (i.planes[0].bytes).buffer);

After changing height to width and width to height, the image is no clearer and almost good. I confused this as it seems.

But its still not good.


</details>


# 答案1
**得分**: 1

如果有人在iPhone上将此流式相机图像(brga8888)转换时遇到困难,由于图像包的新版本,参数已更改:

```dart
imglib.Image im = imglib.Image.fromBytes(
      height: i.height,
      width: i.width,
      bytes: (i.planes[0].bytes).buffer,
      format: imglib.Format.uint8,
      order: ChannelOrder.bgra
    );

这将生成一个清晰的图像。

英文:

If someone is struggling to convert this Streaming CameraImage on IPhone (brga8888),
since a new Version of Image Package the Parameter have changed:

imglib.Image im = imglib.Image.fromBytes(
      height: i.height,
      width: i.width,
      bytes: (i.planes[0].bytes).buffer,
      format: imglib.Format.uint8,
      order: ChannelOrder.bgra
    );

This produced a clean Image.

huangapple
  • 本文由 发表于 2023年5月31日 22:45:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/76374739.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定