Files
2022-06-21 19:14:58 -04:00

86 lines
2.8 KiB
Dart

import 'dart:io';
import 'package:camera/camera.dart';
import 'package:image/image.dart' as image_lib;
import 'package:path_provider/path_provider.dart';
import 'package:tensordex_mobile/utils/logger.dart';
/// ImageUtils
class ImageUtils {
/// Converts a [CameraImage] in YUV420 format to [image_lib.Image] in RGB format
static image_lib.Image? convertCameraImage(CameraImage cameraImage) {
if (cameraImage.format.group == ImageFormatGroup.yuv420) {
return convertYUV420ToImage(cameraImage);
} else if (cameraImage.format.group == ImageFormatGroup.bgra8888) {
return convertBGRA8888ToImage(cameraImage);
} else {
return null;
}
}
/// Converts a [CameraImage] in BGRA888 format to [image_lib.Image] in RGB format
static image_lib.Image convertBGRA8888ToImage(CameraImage cameraImage) {
image_lib.Image img = image_lib.Image.fromBytes(
cameraImage.planes[0].width ?? 0,
cameraImage.planes[0].height ?? 0,
cameraImage.planes[0].bytes,
format: image_lib.Format.bgra
);
return img;
}
/// Converts a [CameraImage] in YUV420 format to [image_lib.Image] in RGB format
static image_lib.Image convertYUV420ToImage(CameraImage cameraImage) {
final int width = cameraImage.width;
final int height = cameraImage.height;
final int uvRowStride = cameraImage.planes[1].bytesPerRow;
final int uvPixelStride = cameraImage.planes[1].bytesPerPixel?? 0;
final image = image_lib.Image(width, height);
for (int w = 0; w < width; w++) {
for (int h = 0; h < height; h++) {
final int uvIndex =
uvPixelStride * (w / 2).floor() + uvRowStride * (h / 2).floor();
final int index = h * width + w;
final y = cameraImage.planes[0].bytes[index];
final u = cameraImage.planes[1].bytes[uvIndex];
final v = cameraImage.planes[2].bytes[uvIndex];
image.data[index] = ImageUtils.yuv2rgb(y, u, v);
}
}
return image;
}
/// Convert a single YUV pixel to RGB
static int yuv2rgb(int y, int u, int v) {
// Convert yuv pixel to rgb
int r = (y + v * 1436 / 1024 - 179).round();
int g = (y - u * 46549 / 131072 + 44 - v * 93604 / 131072 + 91).round();
int b = (y + u * 1814 / 1024 - 227).round();
// Clipping RGB values to be inside boundaries [ 0 , 255 ]
r = r.clamp(0, 255);
g = g.clamp(0, 255);
b = b.clamp(0, 255);
return 0xff000000 |
((b << 16) & 0xff0000) |
((g << 8) & 0xff00) |
(r & 0xff);
}
static void saveImage(image_lib.Image image, [int i = 0]) async {
List<int> jpeg = image_lib.JpegEncoder().encodeImage(image);
final appDir = await getTemporaryDirectory();
final appPath = appDir.path;
final fileOnDevice = File('$appPath/out$i.jpg');
await fileOnDevice.writeAsBytes(jpeg, flush: true);
logger.i('Saved $appPath/out$i.jpg');
}
}