| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227 | using System;using System.Drawing;using System.IO;using System.Threading.Tasks;using Android.Graphics;using Android.Media;using Java.IO;using Xamarin.Essentials;using Bitmap = Android.Graphics.Bitmap;using File = System.IO.File;using Path = System.IO.Path;using Stream = System.IO.Stream;[assembly: Xamarin.Forms.Dependency(typeof(InABox.Mobile.Android.ImageToolsDroid))]namespace InABox.Mobile.Android{    public class ImageToolsDroid: IImageTools    {        public byte[] CreateVideoThumbnail(byte[] video, int maxwidth, int maxheight)        {            byte[] result = null;            var filename = Path.Combine(                Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),                $"{Guid.NewGuid().ToString()}.tmp"            );            File.WriteAllBytes(filename,video);            using (FileInputStream fs = new FileInputStream(filename))            {                FileDescriptor fd = fs.FD;                MediaMetadataRetriever retriever = new MediaMetadataRetriever();                retriever.SetDataSource(fd);                Bitmap bitmap = retriever.GetFrameAtTime(0);                if (bitmap != null)                {                    bitmap = ScaleImage(bitmap, new Size(maxwidth, maxheight));                    MemoryStream stream = new MemoryStream();                    bitmap.Compress(Bitmap.CompressFormat.Png, 60, stream);                    result = stream.ToArray();                }            }            File.Delete(filename);            return result;        }                public byte[] CreateThumbnail(byte[] source, int maxwidth, int maxheight)        {            return ScaleImage(source, new Size(maxwidth, maxheight), 60);        }                public enum ImageOrientation        {            Undefined = 0,            Normal = 1,            FlipHorizontal = 2,            Rotate180 = 3,            FlipVertical = 4,            Transpose = 5,            Rotate90 = 6,            Transverse = 7,            Rotate270 = 8        }                public async Task<FileResult> PickPhotoAsync(int? compression, Size? constraints)        {            var fileResult = await MediaPicker.PickPhotoAsync();            if (fileResult == null)                return null;            return await ProcessFile(fileResult, compression, constraints);        }                public async Task<FileResult> CapturePhotoAsync(int? compression, Size? constraints)        {            var fileResult = await MediaPicker.CapturePhotoAsync();            if (fileResult == null)                return null;            return await ProcessFile(fileResult, compression, constraints);        }        private async Task<FileResult> ProcessFile(FileResult fileResult, int? compression, Size? constraints)        {            await using var stream = await fileResult.OpenReadAsync();            var orientation = GetImageOrientation(stream);            var source = await BitmapFactory.DecodeStreamAsync(stream);            var rotated = RotateImage(source, orientation);            var scaled = ScaleImage(rotated, constraints);            var jpegFilename = Path.Combine(FileSystem.CacheDirectory, $"{Guid.NewGuid()}.jpg");            using (var outStream = new MemoryStream())            {                await scaled.CompressAsync(Bitmap.CompressFormat.Jpeg, compression ?? 100, outStream);                outStream.Position = 0;                await File.WriteAllBytesAsync(jpegFilename, outStream.ToArray());            }            return new FileResult(jpegFilename);        }        private static Bitmap RotateImage(Bitmap source, ImageOrientation orientation)        {            var matrix = new Matrix();            switch (orientation)            {                case ImageOrientation.Normal:                    break;                case ImageOrientation.FlipHorizontal:                    break;                case ImageOrientation.Rotate180:                    break;                case ImageOrientation.FlipVertical:                    matrix.PreRotate(180);                    break;                case ImageOrientation.Transpose:                    matrix.PreRotate(90);                    break;                case ImageOrientation.Rotate90:                    matrix.PreRotate(90);                    break;                case ImageOrientation.Transverse:                    matrix.PreRotate(-90);                    break;                case ImageOrientation.Rotate270:                    matrix.PreRotate(-90);                    break;            }            return Bitmap.CreateBitmap(                source,                0,                0,                source.Width,                source.Height,                matrix,                true);        }        private ImageOrientation GetImageOrientation(Stream stream)        {            var exif = new ExifInterface(stream);            var tag = exif.GetAttribute(ExifInterface.TagOrientation);            var orientation = string.IsNullOrEmpty(tag) ?                ImageOrientation.Undefined :                (ImageOrientation)Enum.Parse(typeof(ImageOrientation), tag);            exif.Dispose();            stream.Position = 0;            return orientation;        }        private static Bitmap ScaleImage(Bitmap source, Size? constraints)        {            var maxwidth = constraints?.Width ?? source.Width;            var maxheight = constraints?.Height ?? source.Height;            var wRatio = maxwidth < source.Width                ? maxwidth / (double)source.Width                : 1.0F;            var hRatio = maxheight < source.Height                ? maxheight / (double)source.Height                : 1.0F;            var ratio = Math.Min(hRatio, wRatio);            var result = (ratio < 1.0F)                ? Bitmap.CreateScaledBitmap(                    source,                    (int)(source.Width * ratio),                    (int)(source.Height * ratio),                    true)                : source;            return result;        }        public byte[] RotateImage(byte[] source, float angle, int compression = 100)        {            if (angle % 360 == 0)                return source;            byte[] result = { };            using (var image = BitmapFactory.DecodeByteArray(source, 0, source.Length))            {                if (image != null)                {                                        var matrix = new Matrix();                    matrix.PreRotate(angle);                                        var rotated = Bitmap.CreateBitmap(                        image,                        0,                        0,                        image.Width,                        image.Height,                        matrix,                        true);                                        if (rotated != null)                    {                        using (var ms = new MemoryStream())                        {                            rotated.Compress(Bitmap.CompressFormat.Jpeg, compression, ms);                            result = ms.ToArray();                        }                    }                }            }            return result;        }        public byte[] ScaleImage(byte[] source, Size? constraints, int compression = 100)        {            byte[] result = { };            using (var image = BitmapFactory.DecodeByteArray(source, 0, source.Length))            {                if (image != null)                {                    var scaled = ScaleImage(image, constraints);                    using (var ms = new MemoryStream())                    {                        scaled.Compress(Bitmap.CompressFormat.Jpeg, compression, ms);                        result = ms.ToArray();                    }                }            }            return result;        }    }}
 |