简体   繁体   中英

Camera2 preview and captured image looks different

By default I get a captured image that is rotated by -90deg and I need to rotate it back, but its height is different from the screen's height, so my image doesn't fill the screen.

In landscape mode after photo it only shows the captured image's top-right corner..

I tried all of the samples that are available, but couldn't find the solution.

private void SetUpCameraOutputs(int width, int height)
{
    _manager = (CameraManager)_context.GetSystemService(Context.CameraService);

    string[] cameraIds = _manager.GetCameraIdList();

    _cameraId = cameraIds[0];

    CameraCharacteristics chararc = _manager.GetCameraCharacteristics(cameraIds[i])
    var characteristics = _manager.GetCameraCharacteristics(_cameraId);
    var map = (StreamConfigurationMap)characteristics.Get(CameraCharacteristics.ScalerStreamConfigurationMap);

    if (_supportedJpegSizes == null && characteristics != null){
        _supportedJpegSizes = ((StreamConfigurationMap)characteristics.Get(CameraCharacteristics.ScalerStreamConfigurationMap)).GetOutputSizes((int)ImageFormatType.Jpeg);
    }

    if (_supportedJpegSizes != null && _supportedJpegSizes.Length > 0){
        _idealPhotoSize = GetOptimalSize(_supportedJpegSizes, 1050, 1400); 
    }

    _imageReader = ImageReader.NewInstance(_idealPhotoSize.Width, _idealPhotoSize.Height, ImageFormatType.Jpeg, 1);

    var readerListener = new ImageAvailableListener();

    readerListener.Photo += (sender, buffer) =>
    {
        Photo?.Invoke(this, buffer);
    };

    _flashSupported = HasFLash(characteristics);

    _imageReader.SetOnImageAvailableListener(readerListener, _backgroundHandler);
        
    _previewSize = GetOptimalSize(map.GetOutputSizes(Class.FromType(typeof(SurfaceTexture))), _idealPhotoSize.Height, _idealPhotoSize.Width);
}

TakePhoto method:

public void TakePhoto()
{
    if (_context == null || CameraDevice == null) return;

    if (_captureBuilder == null)
        _captureBuilder = CameraDevice.CreateCaptureRequest(CameraTemplate.StillCapture);

    _captureBuilder.AddTarget(_imageReader.Surface);

    _captureBuilder.Set(CaptureRequest.ControlAfMode, (int)ControlAFMode.ContinuousPicture);

    var windowManager = _context.GetSystemService(Context.WindowService).JavaCast<IWindowManager>();
    var rotation = windowManager.DefaultDisplay.Rotation;
    _captureBuilder.Set(CaptureRequest.JpegOrientation, new Integer(Orientations.Get((int)rotation)));

    _previewSession.StopRepeating();
    _previewSession.Capture(_captureBuilder.Build(),
        new CameraCaptureStillPictureSessionCallback
        {
            OnCaptureCompletedAction = session =>
            {
                UnlockFocus();
            }
        }, null);
}

And my OnPhoto method:

private void OnPhoto(object sender, byte[] imgSource)
{
    Android.Graphics.Bitmap bitmap = BitmapFactory.DecodeByteArray(imgSource, 0, imgSource.Length);
    var windowManager = _context.GetSystemService(Context.WindowService).JavaCast<IWindowManager>();
    var rotation = windowManager.DefaultDisplay.Rotation;
    if (rotation == SurfaceOrientation.Rotation0 || rotation == SurfaceOrientation.Rotation180)
    {
        bitmap = resizeAndRotate(bitmap, bitmap.Width, bitmap.Height); //rotate bitmap by 90
    }

    var SkBitmap = bitmap.ToSKBitmap();

    Application.Current.Properties["bitmap"] = SkBitmap;

    Device.BeginInvokeOnMainThread(() =>
    {
        _currentElement?.PictureTaken();
    });
}

while you create bitmap for portrait mode you have to change width and height of bitmap. so width become height and height become width for portrait image.


int newWidth = oldHeight;
int newHeight = oldWidth;

Bitmap newBitmap  =Bitmap.createScaledBitmap(oldbitmap,newWidth,newHeight,true);

and you are done now the newBitmap is in its real face without stretch.

According to your code just revert the bitmap width and height by using this :

bitmap = resizeAndRotate(bitmap, bitmap.height, bitmap.width);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM