Skip to content

Commit

Permalink
fix: upgrade packages and fix broken image lib (#5)
Browse files Browse the repository at this point in the history
* Update packages to latest versions

* Fix compilation issues (WIP)


* Fix broken image lib issue

* upgrade more packages

---------

Co-authored-by: Johannes Haubold <[email protected]>
  • Loading branch information
matt-hh and jhmegorei authored May 21, 2024
1 parent 746594b commit c350670
Show file tree
Hide file tree
Showing 4 changed files with 213 additions and 186 deletions.
21 changes: 6 additions & 15 deletions lib/components/ocr_camera.dart
Original file line number Diff line number Diff line change
Expand Up @@ -92,24 +92,15 @@ class _OcrCameraState extends State<OcrCamera> {
final inputImageFormat =
InputImageFormatValue.fromRawValue(image.format.raw) ?? InputImageFormat.nv21;

final planeData = image.planes.map(
(Plane plane) {
return InputImagePlaneMetadata(
bytesPerRow: plane.bytesPerRow,
height: plane.height,
width: plane.width,
);
},
).toList();

final inputImageData = InputImageData(

final inputImageMetadata = InputImageMetadata(
size: imageSize,
imageRotation: imageRotation,
inputImageFormat: inputImageFormat,
planeData: planeData,
rotation: imageRotation,
format: inputImageFormat,
bytesPerRow: image.planes.first.bytesPerRow,
);

final inputImage = InputImage.fromBytes(bytes: bytes, inputImageData: inputImageData);
final inputImage = InputImage.fromBytes(bytes: bytes, metadata: inputImageMetadata);

widget.onImage(inputImage, image);
}
Expand Down
104 changes: 54 additions & 50 deletions lib/helpers/image_converter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,20 @@ import 'package:camera/camera.dart';
Future<Uint8List> convertCameraImageToPng(CameraImage image) async {
try {
imglib.Image img;
if (image.format.group == ImageFormatGroup.yuv420) {
img = _convertYUV420toImageColor(image);
} else if (image.format.group == ImageFormatGroup.bgra8888) {
if (image.format.group == ImageFormatGroup.bgra8888) {
img = _convertBGRA8888(image);
} else {
img = _convertYUV420(image);
}

if (img.height < img.width) {
img = imglib.copyRotate(img, 90);
img = imglib.copyRotate(img, angle: 90);
}

imglib.PngEncoder pngEncoder = imglib.PngEncoder();

// Convert to png
List<int> png = pngEncoder.encodeImage(img);
List<int> png = pngEncoder.encode(img);

return Uint8List.fromList(png);
} catch (e, stacktrace) {
Expand All @@ -37,58 +35,64 @@ Future<Uint8List> convertCameraImageToPng(CameraImage image) async {
// Color
imglib.Image _convertBGRA8888(CameraImage image) {
return imglib.Image.fromBytes(
image.width,
image.height,
image.planes[0].bytes,
format: imglib.Format.bgra,
width: image.width,
height: image.height,
bytes: image.planes[0].bytes.buffer,
format: imglib.Format.uint8,
);
}

// 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;
}
}
imglib.Image _convertYUV420(CameraImage cameraImage) {
final imageWidth = cameraImage.width;
final imageHeight = cameraImage.height;

return img;
}
final yBuffer = cameraImage.planes[0].bytes;
final uBuffer = cameraImage.planes[1].bytes;
final vBuffer = cameraImage.planes[2].bytes;

final int yRowStride = cameraImage.planes[0].bytesPerRow;
final int yPixelStride = cameraImage.planes[0].bytesPerPixel!;

final int uvRowStride = cameraImage.planes[1].bytesPerRow;
final int uvPixelStride = cameraImage.planes[1].bytesPerPixel!;

final image = imglib.Image(width: imageWidth, height: imageHeight);

for (int h = 0; h < imageHeight; h++) {
int uvh = (h / 2).floor();

for (int w = 0; w < imageWidth; w++) {
int uvw = (w / 2).floor();

imglib.Image _convertYUV420toImageColor(CameraImage image) {
final int width = image.width;
final int height = image.height;
final int uvRowStride = image.planes[1].bytesPerRow;
final int uvPixelStride = image.planes[1].bytesPerPixel!;
var img = imglib.Image(width, 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];
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);
img.data[index] = (0xFF << 24) | (b << 16) | (g << 8) | r;
final yIndex = (h * yRowStride) + (w * yPixelStride);

// Y plane should have positive values belonging to [0...255]
final int y = yBuffer[yIndex];

// U/V Values are subsampled i.e. each pixel in U/V chanel in a
// YUV_420 image act as chroma value for 4 neighbouring pixels
final int uvIndex = (uvh * uvRowStride) + (uvw * uvPixelStride);

// U/V values ideally fall under [-0.5, 0.5] range. To fit them into
// [0, 255] range they are scaled up and centered to 128.
// Operation below brings U/V values to [-128, 127].
final int u = uBuffer[uvIndex];
final int v = vBuffer[uvIndex];

// Compute RGB values per formula above.
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();

r = r.clamp(0, 255);
g = g.clamp(0, 255);
b = b.clamp(0, 255);

image.setPixelRgb(w, h, r, g, b);
}
}
return img;

return image;
}
Loading

0 comments on commit c350670

Please sign in to comment.