Camera capture image rotate to portrait - Xamarin android

天大地大妈咪最大 提交于 2021-02-11 16:44:44

问题


I have a xamarin.android project which have a custom camera Preview. Whenever I initialize the camera , it will open as landscape default. So I changed the orientation from SurfaceChanged method like this.

private int setCameraDisplayOrientation(Activity mContext, int v)
        {
            var degrees = 0;
            var orientation =0;

            Display display = mContext.GetSystemService(Context.WindowService).JavaCast<IWindowManager>().DefaultDisplay;

            Camera.CameraInfo info = new Camera.CameraInfo();
            Camera.GetCameraInfo(v, info);
            var rotation = windowManager.DefaultDisplay.Rotation;

            DisplayMetrics dm = new DisplayMetrics();
            display.GetMetrics(dm);
            int width = dm.WidthPixels;
            int height = dm.HeightPixels;

            //Natural orientation is portrait
            if ((rotation == SurfaceOrientation.Rotation0 || rotation == SurfaceOrientation.Rotation180) && height > width ||
                (rotation == SurfaceOrientation.Rotation90 || rotation == SurfaceOrientation.Rotation270) && width > height)
            {
                switch (rotation)
                {
                    case SurfaceOrientation.Rotation0:
                        degrees = 90;
                        break;
                    case SurfaceOrientation.Rotation90:
                        degrees = 0;
                        break;
                    case SurfaceOrientation.Rotation180:
                        degrees = 270;
                        break;
                    case SurfaceOrientation.Rotation270:
                        degrees = 180;
                        break;
                }
            }
            
            return (degrees);
        }

It works fine. It will arrange both front and back camera in portrait.

The problem

When I capture photo, in some devices, it will store in landscape mode in some devices it will store portrait. I want the image to be in portrait mode no matter what. In order do that I tried to get the Exif data of image and rotate it to portrait mode accordingly. But in some devices like samsung, VIVO the orientation value gets as "0". I don't know what to do with that value. If I PreRotate 90 , then some devices will solve this issue, while other will save the photo upwards.

**Managing Rotation**

 Android.Graphics.Bitmap loadAndResizeBitmap(string filePath)
    {

        Android.Graphics.Bitmap resizedBitmap = Android.Graphics.BitmapFactory.DecodeFile(filePath);
        ExifInterface exif = null;
        try
        {
            exif = new ExifInterface(filePath);
            string orientation = exif.GetAttribute(ExifInterface.TagOrientation);

            Android.Graphics.Matrix matrix = new Android.Graphics.Matrix();
            switch (orientation)
            {
                case "1":
                    matrix.PreRotate(-90);
                    resizedBitmap = Android.Graphics.Bitmap.CreateBitmap(resizedBitmap, 0, 0, resizedBitmap.Width, resizedBitmap.Height, matrix, false);
                    matrix.Dispose();
                    matrix = null;
                    break;
                case "3":
                    matrix.PreRotate(180);
                    resizedBitmap = Android.Graphics.Bitmap.CreateBitmap(resizedBitmap, 0, 0, resizedBitmap.Width, resizedBitmap.Height, matrix, false);
                    matrix.Dispose();
                    matrix = null;
                    break;
                case "4":
                    matrix.PreRotate(180);
                    resizedBitmap = Android.Graphics.Bitmap.CreateBitmap(resizedBitmap, 0, 0, resizedBitmap.Width, resizedBitmap.Height, matrix, false);
                    matrix.Dispose();
                    matrix = null;
                    break;
                case "5":
                    matrix.PreRotate(90);
                    resizedBitmap = Android.Graphics.Bitmap.CreateBitmap(resizedBitmap, 0, 0, resizedBitmap.Width, resizedBitmap.Height, matrix, false);
                    matrix.Dispose();
                    matrix = null;
                    break;
                case "6": // portrait
                    matrix.PreRotate(90);
                    resizedBitmap = Android.Graphics.Bitmap.CreateBitmap(resizedBitmap, 0, 0, resizedBitmap.Width, resizedBitmap.Height, matrix, false);
                    matrix.Dispose();
                    matrix = null;
                    break;
                case "7":
                    matrix.PreRotate(-90);
                    resizedBitmap = Android.Graphics.Bitmap.CreateBitmap(resizedBitmap, 0, 0, resizedBitmap.Width, resizedBitmap.Height, matrix, false);
                    matrix.Dispose();
                    matrix = null;
                    break;
                case "8":
                    matrix.PreRotate(-90);
                    resizedBitmap = Android.Graphics.Bitmap.CreateBitmap(resizedBitmap, 0, 0, resizedBitmap.Width, resizedBitmap.Height, matrix, false);
                    matrix.Dispose();
                    matrix = null;
                    break;
                case "0":
                    matrix.PreRotate(-90);
                    resizedBitmap = Android.Graphics.Bitmap.CreateBitmap(resizedBitmap, 0, 0, resizedBitmap.Width, resizedBitmap.Height, matrix, false);
                    matrix.Dispose();
                    matrix = null;
                    break;
            }

            return resizedBitmap;

        }

        catch (IOException ex)
        {
            return null;
        }

    }

I got this Idea from Xamarin.Andoid Image rotation. But somehow I cant relay on it. What will be the problem? Should I pass Stream instead of file path? Does it due to the surfaceview rotation? How can I make the captured image portrait no matter what on any device? Any help is appreciated.


回答1:


Only for Xamarin.Android, call it in shared project using dependency service

Get the Angle of rotation of image by this.

public int GetImageRotation(string filePath)
        {
            try
            {
                ExifInterface ei = new ExifInterface(filePath);
                Orientation orientation = (Orientation)ei.GetAttributeInt(ExifInterface.TagOrientation, (int)Orientation.Undefined);
                switch (orientation)
                {
                    case Orientation.Rotate90:
                        return 90;
                    case Orientation.Rotate180:
                        return 180;
                    case Orientation.Rotate270:
                        return 270;
                    default:
                        return 0;
                }
            }
            catch(Exception ex)
            {
                return 0;
            }
        }

Now Rotate the image according to the angle value you get.

I perform operation on stream rather than the actual file & return in the form of Byte array.

public byte[] RotateImage(System.IO.Stream imageStream, string filePath)
        {
            int rotationDegrees = GetImageRotation(filePath)
            byte[] byteArray = new byte[imageStream.Length];
            try
            {
                imageStream.Read(byteArray, 0, (int)imageStream.Length);

                Bitmap originalImage = BitmapFactory.DecodeByteArray(byteArray, 0, byteArray.Length);
                Matrix matrix = new Matrix();
                matrix.PostRotate((float)rotationDegrees);

                Bitmap rotatedBitmap = Bitmap.CreateBitmap(originalImage, 0, 0, originalImage.Width,
                    originalImage.Height, matrix, true);

                using (MemoryStream ms = new MemoryStream())
                {
                    rotatedBitmap.Compress(Bitmap.CompressFormat.Jpeg, 100, ms);
                    return ms.ToArray();
                }
            }
            catch(Exception ex)
            {
                return byteArray;
            }
        }

Let me know if it worked or not.



来源:https://stackoverflow.com/questions/64278491/camera-capture-image-rotate-to-portrait-xamarin-android

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!