using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Text; using SkiaSharp; using UnityEngine; namespace BITKit.UX { public static class SkiaExtensions { public static Texture2D ToTexture2D(this SKImageInfo info,SKSurface surface) { // Okay, we're finished drawing. Now we create a Unity texture. TextureFormat format = (info.ColorType == SKColorType.Rgba8888) ? TextureFormat.RGBA32 : TextureFormat.BGRA32; var texture = new Texture2D(info.Width, info.Height, format, false, true); texture.wrapMode = TextureWrapMode.Clamp; // Pull a Skia image object out of the canvas... var pixmap = surface.PeekPixels(); // Copy it to the Unity texture... texture.LoadRawTextureData(pixmap.GetPixels(), pixmap.RowBytes * pixmap.Height); texture.Apply(false, true); // And drop it into the RawImage object. return texture; } public static SKColor ToSKColor(this Color color,byte? alpha=null) { return new SKColor((byte)(color.r * 255), (byte)(color.g * 255), (byte)(color.b * 255), alpha??(byte)(color.a * 255)); } public static SKColor ToSKColor(this Color32 color) { return new SKColor(color.r, color.g, color.b, color.a); } public static byte[] GetBytes(this SKSurface self) { try { using var image = self.Snapshot(); using var data = image.Encode(SKEncodedImageFormat.Png, 40); //using var stream = File.OpenWrite(exportPath.Value); var ms = new MemoryStream(); // save the data to a stream data.SaveTo(ms); var bytes = ms.ToArray(); var bitmap = OnFlipHorizontalClicked(bytes); using var rotatedData = bitmap.Encode(SKEncodedImageFormat.Png, 40); using var newMs = new MemoryStream(); rotatedData.SaveTo(newMs); return newMs.ToArray(); } catch (Exception e) { StringBuilder exceptionBuilder = new(); exceptionBuilder.AppendLine($"Surface:{self is not null}"); BIT4Log.LogException( new InGameException(exceptionBuilder.ToString(),e)); throw; } } public static string GetBase64(this SKSurface self) { try { var base64 = Convert.ToBase64String(self.GetBytes()); return "data:image/png;base64," + base64; } catch (Exception e) { StringBuilder exceptionBuilder = new(); exceptionBuilder.AppendLine($"Surface:{self is not null}"); BIT4Log.LogException( new InGameException(exceptionBuilder.ToString(),e)); throw; } } public static SKBitmap OnFlipHorizontalClicked(byte[] bytes) { var bitmap = SKBitmap.Decode(bytes); var flippedBitmap = SKBitmap.Decode(bytes); using var canvas = new SKCanvas(flippedBitmap); canvas.Clear(); canvas.Scale(1, -1, 0, bitmap.Height / 2); canvas.DrawBitmap(bitmap, new SKPoint()); return flippedBitmap; } public static SKBitmap Rotate(SKBitmap bitmap, double angle) { double radians = Math.PI * angle / 180; float sine = (float)Math.Abs(Math.Sin(radians)); float cosine = (float)Math.Abs(Math.Cos(radians)); int originalWidth = bitmap.Width; int originalHeight = bitmap.Height; int rotatedWidth = (int)(cosine * originalWidth + sine * originalHeight); int rotatedHeight = (int)(cosine * originalHeight + sine * originalWidth); var rotatedBitmap = new SKBitmap(rotatedWidth, rotatedHeight); using (var surface = new SKCanvas(rotatedBitmap)) { surface.Translate(rotatedWidth / 2, rotatedHeight / 2); surface.RotateDegrees((float)angle); surface.Translate(-originalWidth / 2, -originalHeight / 2); surface.DrawBitmap(bitmap, new SKPoint()); } return rotatedBitmap; } } }