Camera Preview (Android)
Получение трансляции изображения с камеры устройства Android, с конвертацией кадров в JPEG.
using Android.Hardware.Camera2;
using Android.Views;
using YuvImage = Android.Graphics.YuvImage;
internal class AndroidCameraProvider
{
public VideoCaptureContainer CaptureVideo(
Action<byte[]> onFrameReceive
)
{
var capture = new VideoCaptureContainer(onFrameReceive);
return capture;
}
#region Types
public class VideoCaptureContainer
: CameraDal.IVideoCaptureContainer
{
//private readonly Action<byte[]> OnFrameReceive;
private readonly Camera Camera;
private readonly Handler Handler;
internal VideoCaptureContainer(
Action<byte[]> onFrameReceive
)
{
if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.Lollipop)
{
throw new NotSupportedException();
}
var numberOfCameras = Camera.NumberOfCameras;
var info = Enumerable.Range(0, numberOfCameras)
.Select(
e =>
{
var info = new CameraInfo();
Camera.GetCameraInfo(e, info);
return (Id: e, Info: info);
}
)
.ToDictionary(e => e.Id, e => e);
var cameraId = info.Values
.First(e => e.Info.Facing == CameraFacing.Back);
//OnFrameReceive = onFrameReceive;
Camera = Camera.Open(cameraId.Id);
var cameraParams = Camera.GetParameters();
//Format
var defaultFormat = cameraParams.PreviewFormat;
var supportedFormats = cameraParams.SupportedPreviewFormats
.Select(e => (Android.Graphics.ImageFormatType)(int)e)
.ToHashSet();
if (!supportedFormats.Contains(Android.Graphics.ImageFormatType.Nv21))
{
throw new Exception($"Application Format not supported on device. {Android.Graphics.ImageFormatType.Nv21}");
}
cameraParams.PreviewFormat = Android.Graphics.ImageFormatType.Nv21;
//FrameRate
var defaultRate = cameraParams.PreviewFrameRate;
var supportedRates = cameraParams.SupportedPreviewFrameRates
.Select(e => (int)e)
.ToHashSet();
//cameraParams.PreviewFrameRate = supportedRates.Min();
//cameraParams.PreviewFrameRate = 5;
//Size
var defaultSize = cameraParams.PreviewSize;
Handler = new Handler(
size: (Width: defaultSize.Width, Height: defaultSize.Height),
sourceFormat: cameraParams.PreviewFormat,
onReceive: onFrameReceive
);
Camera.SetPreviewCallback(Handler);
Camera.SetParameters(cameraParams);
Camera.StartPreview();
}
#region Dispose
private bool disposed = false;
// реализация интерфейса IDisposable.
public void Dispose()
{
Dispose(true);
// подавляем финализацию
GC.SuppressFinalize(this);
}
protected void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
// Освобождаем управляемые ресурсы
}
// освобождаем неуправляемые объекты
//Handler.OnReceive -= OnFrameReceive;
Camera.StopPreview();
//Camera.Release();
Camera.Dispose();
//Handler.Dispose();
disposed = true;
}
}
// Деструктор
~VideoCaptureContainer()
{
Dispose(false);
}
#endregion
}
private class Handler
: Java.Lang.Object,
Camera.IPreviewCallback
{
private readonly Rect rectangle;
private readonly Android.Graphics.ImageFormatType SourceFormat;
private readonly Action<byte[]> OnReceive;
public Handler(
(int Width, int Height) size,
Android.Graphics.ImageFormatType sourceFormat,
Action<byte[]> onReceive
)
{
rectangle = new Rect()
{
Bottom = size.Height,
Top = 0,
Left = 0,
Right = size.Width
};
SourceFormat = sourceFormat;
OnReceive = onReceive;
}
public void OnPreviewFrame(
byte[] data,
Camera camera
)
{
if (OnReceive == null)
{
return;
}
//Конвертация в нужный формат
YuvImage image = new YuvImage(
yuv: data,
format: SourceFormat,
width: (int)rectangle.Right,
height: (int)rectangle.Bottom,
strides: null
);
using (var stream = new MemoryStream())
{
image.CompressToJpeg(rectangle, 100, stream);
data = stream.ToArray();
}
OnReceive(data);
}
}
#endregion
}
How get permission for camera in android.(Specifically Marshmallow)
https://stackoverflow.com/questions/38552144/how-get-permission-for-camera-in-android-specifically-marshmallow
What is the image format in the Preview Screen when Camera is enable
https://stackoverflow.com/questions/23557520/what-is-the-image-format-in-the-preview-screen-when-camera-is-enable
Android: How to save a preview frame as jpeg image?
https://stackoverflow.com/questions/1032258/android-how-to-save-a-preview-frame-as-jpeg-image
jamesathey/FastAndroidCamera
https://github.com/jamesathey/FastAndroidCamera
How To Display A Stream From The Camera Using A TextureView In Xamarin Android App Using Visual Studio 2015
https://www.c-sharpcorner.com/article/how-to-display-a-stream-from-the-camera-using-a-textureview-in-xamarin-android-a/