diff options
| author | Sarah Bradley <git@sarahduck.ca> | 2023-12-01 20:33:42 -0800 |
|---|---|---|
| committer | Sarah Bradley <git@sarahduck.ca> | 2023-12-01 20:33:42 -0800 |
| commit | 2793b94040a473538f01723d5ca5f53c4535e2af (patch) | |
| tree | cb30f0dae20bda6ef9d1c005325bfd9c986b3c8f /Bitmap.cs | |
What I've got so far
Diffstat (limited to 'Bitmap.cs')
| -rw-r--r-- | Bitmap.cs | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/Bitmap.cs b/Bitmap.cs new file mode 100644 index 0000000..e508d3d --- /dev/null +++ b/Bitmap.cs @@ -0,0 +1,113 @@ +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<byte> 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); + } +}
\ No newline at end of file |
