Xamarin: невозможно извлечь центральную площадь фотографии в Android / iOS - PullRequest
0 голосов
/ 09 ноября 2019

Я пытаюсь получить изображение с помощью камеры. Изображение должно быть 256х256, и я хочу, чтобы оно было из центра фотографии, сделанной с помощью камеры на телефоне. Я нашел этот код по адресу: https://forums.xamarin.com/discussion/37647/cross-platform-crop-image-view

Я использую этот код для Android ...

public byte[] CropPhoto(byte[] photoToCropBytes, Rectangle rectangleToCrop, double outputWidth, double outputHeight)
        {
            using (var photoOutputStream = new MemoryStream())
            {
                // Load the bitmap
                var inSampleSize = CalculateInSampleSize((int)rectangleToCrop.Width, (int)rectangleToCrop.Height, (int)outputWidth, (int)outputHeight);
                var options = new BitmapFactory.Options();
                options.InSampleSize = inSampleSize;
                //options.InPurgeable = true;   see http://developer.android.com/reference/android/graphics/BitmapFactory.Options.html
                using (var photoToCropBitmap = BitmapFactory.DecodeByteArray(photoToCropBytes, 0, photoToCropBytes.Length, options))
                {
                    var matrix = new Matrix();
                    var martixScale = outputWidth / rectangleToCrop.Width * inSampleSize;
                    matrix.PostScale((float)martixScale, (float)martixScale);
                    using (var photoCroppedBitmap = Bitmap.CreateBitmap(photoToCropBitmap, (int)(rectangleToCrop.X / inSampleSize), (int)(rectangleToCrop.Y / inSampleSize), (int)(rectangleToCrop.Width / inSampleSize), (int)(rectangleToCrop.Height / inSampleSize), matrix, true))
                    {
                        photoCroppedBitmap.Compress(Bitmap.CompressFormat.Jpeg, 100, photoOutputStream);
                    }
                }

                return photoOutputStream.ToArray();
            }
        }

        public static int CalculateInSampleSize(int inputWidth, int inputHeight, int outputWidth, int outputHeight) 
        {
            //see http://developer.android.com/training/displaying-bitmaps/load-bitmap.html

            int inSampleSize = 1;       //default

            if (inputHeight > outputHeight || inputWidth > outputWidth) {

                int halfHeight = inputHeight / 2;
                int halfWidth = inputWidth / 2;

                // Calculate the largest inSampleSize value that is a power of 2 and keeps both
                // height and width larger than the requested height and width.
                while ((halfHeight / inSampleSize) > outputHeight && (halfWidth / inSampleSize) > outputWidth) 
                {
                    inSampleSize *= 2;
                }
            }

            return inSampleSize;
        }

и этот код для iOS ...

    public byte[] CropPhoto(byte[] photoToCropBytes, Xamarin.Forms.Rectangle 

rectangleToCrop, double outputWidth, double outputHeight)
        {
            byte[] photoOutputBytes;

            using (var data = NSData.FromArray(photoToCropBytes))
            {
                using (var photoToCropCGImage = UIImage.LoadFromData(data).CGImage)
                {
                    //crop image
                    using (var photoCroppedCGImage = photoToCropCGImage.WithImageInRect(new CGRect((nfloat)rectangleToCrop.X, (nfloat)rectangleToCrop.Y, (nfloat)rectangleToCrop.Width, (nfloat)rectangleToCrop.Height)))
                    {
                        using (var photoCroppedUIImage = UIImage.FromImage(photoCroppedCGImage))
                        {
                            //create a 24bit RGB image to the output size
                            using (var cGBitmapContext = new CGBitmapContext(IntPtr.Zero, (int)outputWidth, (int)outputHeight, 8, (int)(4 * outputWidth), CGColorSpace.CreateDeviceRGB(), CGImageAlphaInfo.PremultipliedFirst))
                            {
                                var photoOutputRectangleF = new RectangleF(0f, 0f, (float)outputWidth, (float)outputHeight);

                                // draw the cropped photo resized 
                                cGBitmapContext.DrawImage(photoOutputRectangleF, photoCroppedUIImage.CGImage);

                                //get cropped resized photo
                                var photoOutputUIImage = UIKit.UIImage.FromImage(cGBitmapContext.ToImage());

                                //convert cropped resized photo to bytes and then stream
                                using (var photoOutputNsData = photoOutputUIImage.AsJPEG())
                                {
                                    photoOutputBytes = new Byte[photoOutputNsData.Length];
                                    System.Runtime.InteropServices.Marshal.Copy(photoOutputNsData.Bytes, photoOutputBytes, 0, Convert.ToInt32(photoOutputNsData.Length));
                                }
                            }
                        }
                    }
                }
            }

            return photoOutputBytes;
        }

Я изо всех сил пытаюсь понять, какие именно параметры должны вызывать функцию.

В настоящее время я делаю следующее:

        double cropSize = Math.Min(DeviceDisplay.MainDisplayInfo.Width, DeviceDisplay.MainDisplayInfo.Height);
        double left = (DeviceDisplay.MainDisplayInfo.Width - cropSize) / 2.0;
        double top = (DeviceDisplay.MainDisplayInfo.Height - cropSize) / 2.0;

        // Get a square resized and cropped from the top image as a byte[]
        _imageData = mediaService.CropPhoto(_imageData, new Rectangle(left, top, cropSize, cropSize), 256, 256);

Я ожидал, что это обрезает изображение доцентральный квадрат (в портретном режиме длина стороны будет шириной фотографии), а затем уменьшите его до 256x256 изображений. Но он никогда не выбирает центр изображения.

Кто-нибудь когда-либо использовал этот код и может сказать мне, что мне нужно передать для параметра 'rectangleToCrop'?

Примечание. И Android, иiOS выдает то же изображение, но не центральную часть, которую я ожидал.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...