using System.Buffers.Binary; using System.IO.Compression; using Raylib_cs; namespace OnekoOnline; class Bitmap : IDisposable { public readonly int Width; public readonly int Height; public readonly Texture2D Texture; readonly byte[] SerializedData; public Bitmap(Image img) { Width = img.Width; Height = img.Height; Texture = Raylib.LoadTextureFromImage(img); //Get Data for Serialization Color[] colors = new Color[Width*Height]; int i = 0; for (int x = 0; x < Width; x++) { for (int y = 0; y < Height; y++) { colors[i] = Raylib.GetImageColor(img, x, y); i++; } } byte[] data = new byte[(colors.Length*4) + (sizeof(short)*2)]; BinaryPrimitives.WriteInt16LittleEndian(data.AsSpan(0, sizeof(short)), (short)Width); BinaryPrimitives.WriteInt16LittleEndian(data.AsSpan(sizeof(short), sizeof(short)), (short)Height); int position = sizeof(short)*2; for (int c = 0; c < colors.Length; c++) { data[position] = colors[c].R; data[position+1] = colors[c].G; data[position+2] = colors[c].B; data[position+3] = colors[c].A; position += 4; } using MemoryStream stream = new(); using DeflateStream compressor = new(stream, CompressionLevel.Optimal); compressor.Write(data); compressor.Close(); SerializedData = stream.ToArray(); Raylib.UnloadImage(img); } Bitmap(Image img, byte[] serializedData) { Width = img.Width; Height = img.Height; SerializedData = serializedData; Texture = Raylib.LoadTextureFromImage(img); Raylib.UnloadImage(img); } public static Bitmap FromFile(string path) { if (!File.Exists(path) || new FileInfo(path).Length > 40000 || !path.Contains(".png")) return new Bitmap(Raylib.GenImageChecked(32, 32, 4, 4, Color.BLACK, Color.PINK)); byte[] memory = File.ReadAllBytes(path); return FromPNGMemory(memory); } public static Bitmap FromPNGMemory(byte[] memory) { return new Bitmap(Raylib.LoadImageFromMemory(".png", memory)); } public static Bitmap Deserialize(ReadOnlySpan span) { byte[] compressed = span.ToArray(); byte[] data; { using MemoryStream input = new(compressed); using MemoryStream output = new(); using DeflateStream decompressor = new(input, CompressionMode.Decompress); decompressor.CopyTo(output); data = output.ToArray(); } int width = BinaryPrimitives.ReadInt16LittleEndian(data.AsSpan(0, sizeof(short))); int height = BinaryPrimitives.ReadInt16LittleEndian(data.AsSpan(sizeof(short), sizeof(short))); Image img = Raylib.GenImageChecked(width, height, 4, 4, Color.PINK, Color.BLACK); int i = sizeof(short)*2; for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { Color color = new(data[i], data[i+1], data[i+2], data[i+3]); Raylib.ImageDrawPixel(ref img, x, y, color); i += 4; } } return new Bitmap(img, compressed); } public byte[] Serialize() { return SerializedData; } public void Dispose() { Raylib.UnloadTexture(Texture); } }