|
|
@ -26,6 +26,7 @@ namespace Emgu.CV.Platform.Maui.UI |
|
|
|
class OnYuvImageAvailableListener : Java.Lang.Object, ImageReader.IOnImageAvailableListener |
|
|
|
{ |
|
|
|
private byte[] _data = null; |
|
|
|
private byte[] _data_buffer = null; |
|
|
|
private Mat _bgrMat = null; |
|
|
|
private Mat _rotatedMat = new Mat(); |
|
|
|
|
|
|
@ -64,27 +65,93 @@ namespace Emgu.CV.Platform.Maui.UI |
|
|
|
|
|
|
|
var planes = image.GetPlanes(); |
|
|
|
int totalLength = 0; |
|
|
|
int pixelCounts = image.Width * image.Height; |
|
|
|
for (int i = 0; i < planes.Length; i++) |
|
|
|
{ |
|
|
|
Java.Nio.ByteBuffer buffer = planes[i].Buffer; |
|
|
|
totalLength += buffer.Remaining(); |
|
|
|
if (i == 0) |
|
|
|
{ |
|
|
|
//Y plane
|
|
|
|
totalLength += pixelCounts; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
//U, V plane
|
|
|
|
totalLength += pixelCounts / 4; |
|
|
|
} |
|
|
|
//Java.Nio.ByteBuffer buffer = planes[i].Buffer;
|
|
|
|
//totalLength += buffer.Remaining();
|
|
|
|
} |
|
|
|
|
|
|
|
if (_data == null || _data.Length != totalLength) |
|
|
|
{ |
|
|
|
_data = new byte[totalLength]; |
|
|
|
_data_buffer = new byte[(image.Height / 2) * planes[1].RowStride]; |
|
|
|
} |
|
|
|
|
|
|
|
int offset = 0; |
|
|
|
for (int i = 0; i < planes.Length; i++) |
|
|
|
{ |
|
|
|
Java.Nio.ByteBuffer buffer = planes[i].Buffer; |
|
|
|
int length = buffer.Remaining(); |
|
|
|
if (i == 0) |
|
|
|
{ |
|
|
|
Java.Nio.ByteBuffer buffer = planes[i].Buffer; |
|
|
|
int length = buffer.Remaining(); |
|
|
|
|
|
|
|
buffer.Get(_data, offset, length); |
|
|
|
offset += pixelCounts; |
|
|
|
} |
|
|
|
else if (planes[i].PixelStride == 1) |
|
|
|
{ |
|
|
|
Java.Nio.ByteBuffer buffer = planes[i].Buffer; |
|
|
|
int length = buffer.Remaining(); |
|
|
|
|
|
|
|
buffer.Get(_data, offset, length); |
|
|
|
offset += length; |
|
|
|
buffer.Get(_data, offset, length); |
|
|
|
offset += pixelCounts / 4; |
|
|
|
} |
|
|
|
else if (planes[i].PixelStride <= 4) // && pixel Stride > 1
|
|
|
|
{ |
|
|
|
Java.Nio.ByteBuffer buffer = planes[i].Buffer; |
|
|
|
int length = buffer.Remaining(); |
|
|
|
buffer.Get(_data_buffer, 0, length); |
|
|
|
// Need to handle data stride
|
|
|
|
GCHandle bufferHandler = GCHandle.Alloc(_data_buffer, GCHandleType.Pinned); |
|
|
|
GCHandle dataHandler = GCHandle.Alloc(_data, GCHandleType.Pinned); |
|
|
|
try |
|
|
|
{ |
|
|
|
using (Mat bufferMat = new Mat( |
|
|
|
image.Height / 2, |
|
|
|
image.Width / 2, |
|
|
|
DepthType.Cv8U, |
|
|
|
planes[i].PixelStride, |
|
|
|
bufferHandler.AddrOfPinnedObject(), |
|
|
|
planes[i].RowStride)) |
|
|
|
using (Mat dataMat = new Mat( |
|
|
|
image.Height / 2, |
|
|
|
image.Width / 2, |
|
|
|
DepthType.Cv8U, |
|
|
|
1, |
|
|
|
new IntPtr(dataHandler.AddrOfPinnedObject().ToInt64() + offset), |
|
|
|
image.Width / 2)) |
|
|
|
{ |
|
|
|
CvInvoke.ExtractChannel(bufferMat, dataMat, 0); |
|
|
|
} |
|
|
|
} |
|
|
|
finally |
|
|
|
{ |
|
|
|
bufferHandler.Free(); |
|
|
|
dataHandler.Free(); |
|
|
|
} |
|
|
|
|
|
|
|
offset += pixelCounts / 4; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
throw new NotImplementedException("Pixel stride larger than 4 is not supported."); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
//System.Diagnostics.Debug.Assert(offset == _data.Length, "Offset != _data.Length");
|
|
|
|
System.Diagnostics.Debug.Assert(image.Width * (image.Height + image.Height / 2) == _data.Length, "_data.Length != image pixel count"); |
|
|
|
|
|
|
|
GCHandle handle = GCHandle.Alloc(_data, GCHandleType.Pinned); |
|
|
|
using (Mat m = new Mat( |
|
|
|
new System.Drawing.Size(image.Width, image.Height + image.Height / 2), |
|
|
|