summaryrefslogtreecommitdiff
path: root/Bitmap.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Bitmap.cs')
-rw-r--r--Bitmap.cs113
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