summaryrefslogtreecommitdiff
path: root/Bitmap.cs
blob: 7f7b9d614b849d8aa5c858fc3b90b70f92ca6031 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
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??")
    };

    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)
    {
        byte* ptr = Raylib.ExportImageToMemory(img, ImageTypeToString(imageType), out int 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(ImageTypeToString(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();
}