public void OnImageAvailable(ImageReader reader) { Image image = reader.AcquireLatestImage(); if (image == null) { return; } Image.Plane[] planes = image.GetPlanes(); int totalLength = 0; for (int i = 0; i < planes.Length; i++) { Java.Nio.ByteBuffer buffer = planes[i].Buffer; totalLength += buffer.Remaining(); } if (_data == null || _data.Length != totalLength) { _data = new byte[totalLength]; } int offset = 0; for (int i = 0; i < planes.Length; i++) { Java.Nio.ByteBuffer buffer = planes[i].Buffer; int length = buffer.Remaining(); buffer.Get(_data, offset, length); offset += length; } if (_yuv420Converter == null) { _yuv420Converter = new YUV420Converter(_activity); } if (_bitmapSrcBuffer[_bitmapBufferIdx] == null || image.Width != (_bitmapSrcBuffer[_bitmapBufferIdx].Width) || (image.Height != _bitmapSrcBuffer[_bitmapBufferIdx].Height)) { _bitmapSrcBuffer[_bitmapBufferIdx] = Bitmap.CreateBitmap(image.Width, image.Height, Bitmap.Config.Argb8888); } Bitmap bmpSrc = _bitmapSrcBuffer[_bitmapBufferIdx]; _yuv420Converter.YUV_420_888_toRGBIntrinsics(image.Width, image.Height, _data, bmpSrc); using (Mat m = new Mat(bmpSrc.Height, bmpSrc.Width, DepthType.Cv8U, 4, bmpSrc.LockPixels(), bmpSrc.Width * 4)) { bmpSrc.UnlockPixels(); CvInvoke.CvtColor(m, _bgrMat, ColorConversion.Bgra2Bgr); //Rotate 90 degree by transpose and flip CvInvoke.Transpose(_bgrMat, _rotatedMat); CvInvoke.Flip(_rotatedMat, _rotatedMat, FlipType.Horizontal); //apply a simple invert filter CvInvoke.BitwiseNot(_rotatedMat, _rotatedMat); } _activity.SetImage(_rotatedMat); _bitmapBufferIdx = (_bitmapBufferIdx + 1) % _bitmapSrcBuffer.Length; /* * GCHandle dataHandle = GCHandle.Alloc(_data, GCHandleType.Pinned); * using (Mat m = new Mat((image.Height << 1) + (image.Height >> 1), image.Width, DepthType.Cv8U, 1, * dataHandle.AddrOfPinnedObject(), image.Width)) * { * CvInvoke.CvtColor(m, _bgrMat, ColorConversion.Yuv420Sp2Bgr); * * if (_activity != null) * _activity.SetImage(_bgrMat); * } * dataHandle.Free(); */ //int bytesPerPixel = ImageFormat.GetBitsPerPixel(Android.Graphics.ImageFormatType.Yuv420888) / 8; //int dataSize = width * height * bytesPerPixel; /* * byte[] rowData = new byte[planes[0].RowStride]; * * for (int i = 0; i < planes.Length; i++) * { * buffer = planes[i].Buffer; * rowStride = planes[i].RowStride; * pixelStride = planes[i].PixelStride; * int w = (i == 0) ? width : width / 2; * int h = (i == 0) ? height : height / 2; * for (int row = 0; row < h; row++) * { * if (pixelStride == bytesPerPixel) * { * int length = w * bytesPerPixel; * buffer.Get(_data, offset, length); * * // Advance buffer the remainder of the row stride, unless on the last row. * // Otherwise, this will throw an IllegalArgumentException because the buffer * // doesn't include the last padding. * if (h - row != 1) * { * buffer.Position(buffer.Position() + rowStride - length); * } * offset += length; * } * else * { * * // On the last row only read the width of the image minus the pixel stride * // plus one. Otherwise, this will throw a BufferUnderflowException because the * // buffer doesn't include the last padding. * if (h - row == 1) * { * buffer.Get(rowData, 0, width - pixelStride + 1); * } * else * { * buffer.Get(rowData, 0, rowStride); * } * * for (int col = 0; col < w; col++) * { * _data[offset++] = rowData[col * pixelStride]; * } * } * } * }*/ image.Close(); //image.Dispose(); }
public void OnImageAvailable(ImageReader reader) { Image image = reader.AcquireLatestImage(); if (image == null) { return; } Image.Plane[] planes = image.GetPlanes(); int totalLength = 0; for (int i = 0; i < planes.Length; i++) { Java.Nio.ByteBuffer buffer = planes[i].Buffer; totalLength += buffer.Remaining(); } if (_data == null || _data.Length != totalLength) { _data = new byte[totalLength]; } int offset = 0; for (int i = 0; i < planes.Length; i++) { Java.Nio.ByteBuffer buffer = planes[i].Buffer; int length = buffer.Remaining(); buffer.Get(_data, offset, length); offset += length; } if (_yuv420Converter == null) { _yuv420Converter = new YUV420Converter(Android.App.Application.Context); } if (_bitmapSrcBuffer[_bitmapBufferIdx] == null || image.Width != (_bitmapSrcBuffer[_bitmapBufferIdx].Width) || (image.Height != _bitmapSrcBuffer[_bitmapBufferIdx].Height)) { _bitmapSrcBuffer[_bitmapBufferIdx] = Bitmap.CreateBitmap(image.Width, image.Height, Bitmap.Config.Argb8888); } Bitmap bmpSrc = _bitmapSrcBuffer[_bitmapBufferIdx]; _yuv420Converter.YUV_420_888_toRGBIntrinsics(image.Width, image.Height, _data, bmpSrc); using (Mat m = new Mat(bmpSrc.Height, bmpSrc.Width, DepthType.Cv8U, 4, bmpSrc.LockPixels(), bmpSrc.Width * 4)) { bmpSrc.UnlockPixels(); CvInvoke.CvtColor(m, _bgrMat, ColorConversion.Bgra2Bgr); //Rotate 90 degree by transpose and flip CvInvoke.Transpose(_bgrMat, _rotatedMat); CvInvoke.Flip(_rotatedMat, _rotatedMat, FlipType.Horizontal); //apply a simple invert filter CvInvoke.BitwiseNot(_rotatedMat, _rotatedMat); } if (OnImageProcessed != null) { OnImageProcessed(reader, _rotatedMat); } _bitmapBufferIdx = (_bitmapBufferIdx + 1) % _bitmapSrcBuffer.Length; image.Close(); //image.Dispose(); }