using ZeroElectric.Vinculum; using System.Runtime.InteropServices; using System.Numerics; namespace SarahEngine; public unsafe class Bitmap { Image img; Texture tex; public Vector2 Origin = Vector2.Zero; bool imgChanged = false; private Bitmap(Image image) { img = image; tex = Raylib.LoadTextureFromImage(img); } void ReloadTexture() { Raylib.UnloadTexture(tex); tex = Raylib.LoadTextureFromImage(img); } public enum ImageType { PNG,GIF,JPG,TGA,BMP } static string ImageTypeToString(ImageType type) => type switch { ImageType.PNG => ".png", ImageType.GIF => ".gif", ImageType.JPG => ".jpg", ImageType.TGA => ".tga", ImageType.BMP => ".bmp", _ => throw new Exception("Image type not supported... How did you get this error??") }; static readonly IntPtr PngPtr = Marshal.StringToHGlobalAnsi(".png"); static readonly IntPtr GifPtr = Marshal.StringToHGlobalAnsi(".gif"); static readonly IntPtr JpgPtr = Marshal.StringToHGlobalAnsi(".jpg"); static readonly IntPtr TgaPtr = Marshal.StringToHGlobalAnsi(".tga"); static readonly IntPtr BmpPtr = Marshal.StringToHGlobalAnsi(".bmp"); static IntPtr ImageTypeToPointer(ImageType type) => type switch { ImageType.PNG => PngPtr, ImageType.GIF => GifPtr, ImageType.JPG => JpgPtr, ImageType.TGA => TgaPtr, ImageType.BMP => BmpPtr, _ => throw new Exception("Image type not supported... How did you get this error??") }; public int Width { get => img.width; set => ResizeCanvas(value, Height); } public int Height { get => img.height; set => ResizeCanvas(Width, value); } public void CenterOrigin() { Origin = new(Width/2f, Height/2f); } public byte[] ToMemory(ImageType imageType = ImageType.PNG) { int length; byte* ptr = Raylib.ExportImageToMemory(img, (sbyte*)ImageTypeToPointer(imageType), &length); byte[] mem = new byte[length]; Marshal.Copy((nint)ptr, mem, 0, length); return mem; } public static Bitmap FromMemory(byte[] ImageMemory, ImageType imageType) { Image img; fixed (byte* ptr = &ImageMemory[0]) img = Raylib.LoadImageFromMemory((sbyte*)ImageTypeToPointer(imageType), ptr, ImageMemory.Length); return new Bitmap(img); } public static Bitmap FromFile(string filePath) { Image img = Raylib.LoadImage(filePath); return new Bitmap(img); } public void Crop(Rectangle crop) { fixed (Image* imgptr = &img) Raylib.ImageCrop(imgptr, crop); imgChanged = true; } public void ResizeCanvas(int newWidth, int newHeight, int offsetX = 0, int offsetY = 0, Color fill = new()) { fixed (Image* imgptr = &img) Raylib.ImageResizeCanvas(imgptr, newWidth, newHeight, offsetX, offsetY, fill); imgChanged = true; } public void Resize(int newWidth, int newHeight) { fixed (Image* imgptr = &img) Raylib.ImageResize(imgptr, newWidth, newHeight); imgChanged = true; } public void Draw(Vector2 Position, float Rotation, Vector2 Scale) { if (imgChanged) { ReloadTexture(); imgChanged = false; } Rectangle source = new(0f, 0f, Width, Height); Color tint = new(255,255,255,255); Position -= Origin*Scale; Rectangle dest = new(Position.X, Position.Y, Width*Scale.X, Height*Scale.Y); Raylib.DrawTexturePro(tex, source, dest, Origin, Rotation, tint); } void Unload() { Raylib.UnloadImage(img); Raylib.UnloadTexture(tex); } ~Bitmap() => Unload(); }