我一直在使用
Camera package
通过 cameraController.startImageStream()
创建实时人脸检测,所以我每帧都会得到一个 CameraImage
图像。
我需要通过 WebSockets 以 PNG、JPG 或 Base64 字符串格式发送该帧。
我一直在使用改编自
这里的最佳答案,它有效(图像仍然旋转 90°,但至少它完成了从 CameraImage 到 PNG 到 Base64 字符串的转换)。
但是 PNG 转换真的很慢! :c
有时,每帧需要 20 秒来处理。 还有其他更快的解决方案吗?
我当前使用的代码是:
import 'dart:convert';
import 'package:camera/camera.dart';
mport 'package:image/image.dart' as imglib;
相机图像转PNG方法:
Future<List<int>> convertYUV420toImageColor(CameraImage image) async {
try {
final int width = image.width;
final int height = image.height;
final int uvRowStride = image.planes[1].bytesPerRow;
final int? uvPixelStride = image.planes[1].bytesPerPixel;
//print("uvRowStride: " + uvRowStride.toString());
//print("uvPixelStride: " + uvPixelStride.toString());
// imgLib -> Image package from https://pub.dartlang.org/packages/image
var img =
imglib.Image(width: width, height: height); // Create Image buffer
// Fill image buffer with plane[0] from YUV420_888
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
final int uvIndex =
uvPixelStride! * (x / 2).floor() + uvRowStride * (y / 2).floor();
final int index = y * width + x;
final yp = image.planes[0].bytes[index];
final up = image.planes[1].bytes[uvIndex];
final vp = image.planes[2].bytes[uvIndex];
// Calculate pixel color
int r = (yp + vp * 1436 / 1024 - 179).round().clamp(0, 255);
int g = (yp - up * 46549 / 131072 + 44 - vp * 93604 / 131072 + 91)
.round()
.clamp(0, 255);
int b = (yp + up * 1814 / 1024 - 227).round().clamp(0, 255);
// color: 0x FF FF FF FF
// A B G R
img.data?.elementAt(index).setRgba(r, g, b, 255);
}
}
imglib.PngEncoder pngEncoder = imglib.PngEncoder(level: 0);
List<int> png = pngEncoder.encode(img);
//muteYUVProcessing = false;
return png;
} catch (e) {
print(">>>>>>>>>>>> ERROR:" + e.toString());
}
return [];
}
PNG转Base64方法:
Future<String> convertirImagenABase64AMAZON(List<int> bytes) async {
// Encodes the bytes of a PNG to Base64 String
final String base64String = base64.encode(bytes);
return base64String;
}