-
Notifications
You must be signed in to change notification settings - Fork 0
/
camera_image.dart
53 lines (45 loc) · 1.6 KB
/
camera_image.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
import 'package:camera/camera.dart';
import 'package:flutter/services.dart';
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);
}
}