Browse Source

Added Platform-Specific Image Resizing utility for Thumbnail Generation

Frank van den Bos 2 years ago
parent
commit
5e5669c8f1

+ 2 - 0
InABox.Core/Classes/Document/IEntityDocument.cs

@@ -7,5 +7,7 @@ namespace InABox.Core
         DocumentLink DocumentLink { get; set; }
 
         DateTime Superceded { get; set; }
+        
+        byte[]? Thumbnail { get; set; }
     }
 }

+ 45 - 0
InABox.Mobile/InABox.Mobile.Android/ImageToolsDroid.cs

@@ -0,0 +1,45 @@
+using System;
+using System.Drawing;
+using System.IO;
+using Android.Graphics;
+using Bitmap = Android.Graphics.Bitmap;
+
+[assembly: Xamarin.Forms.Dependency(typeof(InABox.Mobile.Android.ImageToolsDroid))]
+namespace InABox.Mobile.Android
+{
+    public class ImageToolsDroid: IImageTools
+    {
+        public byte[] CreateThumbnail(byte[] source, float maxwidth, float maxheight)
+        {
+            byte[] result = { };
+            using (var image = BitmapFactory.DecodeByteArray(source, 0, source.Length))
+            {  
+                if (image != null)
+                {
+                    var size = new Size((int)image.GetBitmapInfo().Height, (int)image.GetBitmapInfo().Width);
+                    if ((size.Width > 0) && (size.Height > 0))
+                    {
+                        var maxFactor = Math.Min(maxwidth / size.Width, maxheight / size.Height);
+                        var width = maxFactor * size.Width;
+                        var height = maxFactor * size.Height;
+                        using (var tgt = Bitmap.CreateScaledBitmap(image, (int)height, (int)width, true))
+                        {
+                            if (tgt != null)
+                            {
+                                using (var ms = new MemoryStream())
+                                {
+                                    tgt.Compress(Bitmap.CompressFormat.Jpeg, 95, ms);
+                                    result = ms.ToArray();
+                                }
+
+                                tgt.Recycle();
+                            }
+                        }
+                    }
+                    image.Recycle();
+                }
+            }
+            return result;
+        }
+    }
+}

+ 1 - 0
InABox.Mobile/InABox.Mobile.Android/InABox.Mobile.Android.projitems

@@ -10,6 +10,7 @@
   </PropertyGroup>
   <ItemGroup>
     <Compile Include="$(MSBuildThisFileDirectory)DeviceID_Android.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)ImageToolsDroid.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)Version_Android.cs" />
   </ItemGroup>
 </Project>

+ 7 - 0
InABox.Mobile/InABox.Mobile.Shared/IImageTools.cs

@@ -0,0 +1,7 @@
+namespace InABox.Mobile
+{
+    public interface IImageTools
+    {
+        byte[] CreateThumbnail(byte[] image, float maxwidth, float maxheight);
+    }
+}

+ 1 - 1
InABox.Mobile/InABox.Mobile.Shared/InABox.Mobile.Shared.csproj

@@ -10,7 +10,7 @@
         <PackageReference Include="Plugin.BLE" Version="2.1.3" />
         <PackageReference Include="Serilog" Version="3.0.1" />
         <PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
-        <PackageReference Include="Syncfusion.Licensing" Version="22.1.37" />
+        <PackageReference Include="Syncfusion.Licensing" Version="22.1.39" />
         <PackageReference Include="Xamarin.Essentials" Version="1.7.7" />
         <PackageReference Include="Xamarin.Forms" Version="5.0.0.2012" />
     </ItemGroup>

+ 2 - 0
InABox.Mobile/InABox.Mobile.Shared/MobileUtils.cs

@@ -24,6 +24,8 @@ namespace InABox.Mobile
         }
 
         public static IAppVersion AppVersion { get { return DependencyService.Get<IAppVersion>(); } }
+
+        public static IImageTools ImageTools => DependencyService.Get<IImageTools>();
         
         private static async Task<bool> Retry(Func<Task<bool>> action, int interval, int retryCount = 3)
         {

+ 44 - 0
InABox.Mobile/InABox.Mobile.iOS/ImageToolsiOS.cs

@@ -0,0 +1,44 @@
+
+using System;
+using System.IO;
+using CoreGraphics;
+using Foundation;
+using UIKit;
+
+[assembly: Xamarin.Forms.Dependency(typeof(InABox.Mobile.iOS.ImageToolsiOS))]
+namespace InABox.Mobile.iOS
+{
+    
+    public class ImageToolsiOS : IImageTools
+    {
+        
+        public byte[] CreateThumbnail(byte[] source, float maxwidth, float maxheight)
+        {
+            byte[] result = { };
+            using (UIImage src = UIImage.LoadFromData(NSData.FromArray(source)))
+            {
+                if (src != null)
+                {
+                    if ((src.Size.Width > 0.0F) && (src.Size.Height > 0.0F))
+                    {
+                        var maxFactor = Math.Min(maxwidth / src.Size.Width, maxheight / src.Size.Height);
+                        var width = maxFactor * src.Size.Width;
+                        var height = maxFactor * src.Size.Height;
+                        UIGraphics.BeginImageContextWithOptions(new CGSize((float)width, (float)height), true, 1.0f);
+                        src.Draw(new CGRect(0, 0, (float)width, (float)height));
+                        var tgt = UIGraphics.GetImageFromCurrentImageContext();
+                        UIGraphics.EndImageContext();
+
+                        using (NSData imageData = tgt.AsJPEG())
+                        {
+                            result = new byte[imageData.Length];
+                            System.Runtime.InteropServices.Marshal.Copy(imageData.Bytes, result, 0,
+                                Convert.ToInt32(imageData.Length));
+                        }
+                    }
+                }
+            }
+            return result;
+        }
+    }
+}

+ 1 - 0
InABox.Mobile/InABox.Mobile.iOS/InABox.Mobile.iOS.projitems

@@ -12,6 +12,7 @@
     <Compile Include="$(MSBuildThisFileDirectory)DeviceID_iOS.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)DropDownMenuRenderer.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)DropDownMenuSource.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)ImageToolsiOS.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)Version_iOS.cs" />
   </ItemGroup>
   <ItemGroup>