123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246 |
- using System.Drawing;
- using Android.Graphics;
- using Android.Media;
- using Avalonia.Controls;
- using InABox.Core;
- using Java.IO;
- using Microsoft.Maui.Media;
- using Bitmap = Android.Graphics.Bitmap;
- using File = System.IO.File;
- using Path = System.IO.Path;
- using Stream = System.IO.Stream;
- namespace InABox.Avalonia.Platform.Android
- {
- public class Android_ImageTools : IImageTools
- {
-
- public Logger? Logger { get; set; }
- 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<ImageFile?> PickPhotoAsync(TopLevel window, int? compression, Size? constraints)
- {
- var fileResult = await MediaPicker.PickPhotoAsync();
- if (fileResult == null)
- return null;
- await using var stream = await fileResult.OpenReadAsync();
- return await ProcessFile(stream, compression, constraints);
- }
-
- public async Task<ImageFile?> CapturePhotoAsync(TopLevel window, int? compression, Size? constraints)
- {
- var fileResult = await MediaPicker.CapturePhotoAsync();
- if (fileResult == null)
- return null;
- await using var stream = await fileResult.OpenReadAsync();
- return await ProcessFile(stream, compression, constraints);
- }
-
- public async Task<ImageFile?> PickVideoAsync(TopLevel window)
- {
- var fileResult = await MediaPicker.PickPhotoAsync();
- if (fileResult == null)
- return null;
- await using var stream = await fileResult.OpenReadAsync();
- return await ProcessFile(stream, null, null);
- }
-
- public async Task<ImageFile?> CaptureVideoAsync(TopLevel window)
- {
- var fileResult = await MediaPicker.CapturePhotoAsync();
- if (fileResult == null)
- return null;
- await using var stream = await fileResult.OpenReadAsync();
- return await ProcessFile(stream, null, null);
- }
- private async Task<ImageFile> ProcessFile(Stream stream, 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(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), $"{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 ImageFile(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;
- }
- }
- }
|