Closed mrwebbeast closed 2 months ago
feel free to fork the repo and edit this:
send you PR back with your contribution
CameraX is now the default Android camera in the Camera Package. It would be great if we could get the update.
I believe yuv_420_888
format can have more than a single plane
.
It's unclear how to build an InputImage then. (In previous versions, probably 0.0.6 it worked with multiple planes
, but it seems not anymore).
Also, the documentation of this plugin states to use `.nv21 for android.
@AndreiMisiukevich : feel free to fork the repo and add multiple planes and add yuv_420_888 for Android. Then send your PR. We always welcome contributions.
This topic is also linked to this CameraX issue: https://github.com/flutter/flutter/issues/145961
Isn't it possible to use the ML KIT API with yuv_420_888 InputImageFormat? Maybe it is easier to support this third image format in the Flutter SDK?
@FantaMagier : yes, it is possible. I do not have an ETA for that change. We need a volunteer to work on that. Contributions are always welcome.
Maybe someone need a quick solution, this code helped me to convert yuv420_888 to nv21 manually: (source in java: https://blog.minhazav.dev/how-to-use-renderscript-to-convert-YUV_420_888-yuv-image-to-bitmap/#tonv21image-image-java-approach)
extension Nv21Converter on CameraImage {
Uint8List getNv21Uint8List() {
final width = this.width;
final height = this.height;
final yPlane = planes[0];
final uPlane = planes[1];
final vPlane = planes[2];
final yBuffer = yPlane.bytes;
final uBuffer = uPlane.bytes;
final vBuffer = vPlane.bytes;
final numPixels = (width * height * 1.5).toInt();
final nv21 = List<int>.filled(numPixels, 0);
// Full size Y channel and quarter size U+V channels.
int idY = 0;
int idUV = width * height;
final uvWidth = width ~/ 2;
final uvHeight = height ~/ 2;
// Copy Y & UV channel.
// NV21 format is expected to have YYYYVU packaging.
// The U/V planes are guaranteed to have the same row stride and pixel stride.
// getRowStride analogue??
final uvRowStride = uPlane.bytesPerRow;
// getPixelStride analogue
final uvPixelStride = uPlane.bytesPerPixel ?? 0;
final yRowStride = yPlane.bytesPerRow;
final yPixelStride = yPlane.bytesPerPixel ?? 0;
for (int y = 0; y < height; ++y) {
final uvOffset = y * uvRowStride;
final yOffset = y * yRowStride;
for (int x = 0; x < width; ++x) {
nv21[idY++] = yBuffer[yOffset + x * yPixelStride];
if (y < uvHeight && x < uvWidth) {
final bufferIndex = uvOffset + (x * uvPixelStride);
//V channel
nv21[idUV++] = vBuffer[bufferIndex];
//V channel
nv21[idUV++] = uBuffer[bufferIndex];
}
}
}
return Uint8List.fromList(nv21);
}
}
@PudovkinSergey Good work! How does your inputImageFromCameraImage function look like?
This issue is stale because it has been open for 30 days with no activity.
same issue here 😢
Maybe someone need a quick solution, this code helped me to convert yuv420_888 to nv21 manually: (source in java: https://blog.minhazav.dev/how-to-use-renderscript-to-convert-YUV_420_888-yuv-image-to-bitmap/#tonv21image-image-java-approach)
extension Nv21Converter on CameraImage { Uint8List getNv21Uint8List() { final width = this.width; final height = this.height; final yPlane = planes[0]; final uPlane = planes[1]; final vPlane = planes[2]; final yBuffer = yPlane.bytes; final uBuffer = uPlane.bytes; final vBuffer = vPlane.bytes; final numPixels = (width * height * 1.5).toInt(); final nv21 = List<int>.filled(numPixels, 0); // Full size Y channel and quarter size U+V channels. int idY = 0; int idUV = width * height; final uvWidth = width ~/ 2; final uvHeight = height ~/ 2; // Copy Y & UV channel. // NV21 format is expected to have YYYYVU packaging. // The U/V planes are guaranteed to have the same row stride and pixel stride. // getRowStride analogue?? final uvRowStride = uPlane.bytesPerRow; // getPixelStride analogue final uvPixelStride = uPlane.bytesPerPixel ?? 0; final yRowStride = yPlane.bytesPerRow; final yPixelStride = yPlane.bytesPerPixel ?? 0; for (int y = 0; y < height; ++y) { final uvOffset = y * uvRowStride; final yOffset = y * yRowStride; for (int x = 0; x < width; ++x) { nv21[idY++] = yBuffer[yOffset + x * yPixelStride]; if (y < uvHeight && x < uvWidth) { final bufferIndex = uvOffset + (x * uvPixelStride); //V channel nv21[idUV++] = vBuffer[bufferIndex]; //V channel nv21[idUV++] = uBuffer[bufferIndex]; } } } return Uint8List.fromList(nv21); } }
how to use it?
Have the extension code in the separate dart file
In the _inputImageFromCameraImage method ........ final format = InputImageFormatValue.fromRawValue(image.format.raw); if (format != null && (Platform.isAndroid && format == InputImageFormat.yuv_420_888)) { return InputImage.fromBytes( bytes: image.getNv21Uint8List(), metadata: InputImageMetadata( size: Size(image.width.toDouble(), image.height.toDouble()), rotation: rotation, // used only in Android format: format, // used only in iOS bytesPerRow: image.planes.first.bytesPerRow, // used only in iOS )); } .........
Have the extension code in the separate dart file
In the _inputImageFromCameraImage method ........ final format = InputImageFormatValue.fromRawValue(image.format.raw); if (format != null && (Platform.isAndroid && format == InputImageFormat.yuv_420_888)) { return InputImage.fromBytes( bytes: image.getNv21Uint8List(), metadata: InputImageMetadata( size: Size(image.width.toDouble(), image.height.toDouble()), rotation: rotation, // used only in Android format: format, // used only in iOS bytesPerRow: image.planes.first.bytesPerRow, // used only in iOS )); } .........
thank u so much sir now i can use the newset camera package
The Flutter team discusses support for nv21 with CameraX. Upvote the topic to get more support for it 😁.
This issue is stale because it has been open for 30 days with no activity.
This issue was closed because it has been inactive for 14 days since being marked as stale.
Title: Process Camera Image Issue
Describe the bug Process Camera Image Issue when using Face Detection & Pose Detection,etc with camera_android_camerax: any
To Reproduce Steps to reproduce the behavior:
Expected behavior It should work same as camera_android: ^any so it will process and return processed data according to mlkit plugin Expected InputImageFormat is nv21 but when using camera_android_camerax: any then its returning yuv_420_888 InputImageFormat
Need support for yuv_420_888 InputImageFormat when using camera_android_camerax:any
Platform (please complete the following information):