Load image from EmbeddedResource
Before submitting a new issue, please verify and check:
- [x] The issue is specific to Raylib-cs and not raylib
- [x] I checked there is no similar issue already reported
- [x] My code has no errors or misuse of Raylib-cs
Issue description
I would like to be able to load an image file using embedded resources and convert this to a Raylib_cs.Image/Texture
Environment
Code example
My current code:
var myStream = Program.game.GetType().Assembly.GetManifestResourceStream(path);
var image = System.Drawing.Image.FromStream(myStream);
return Raylib.LoadTextureFromImage(image);
Throws the error:
error CS1503: Argument 1: cannot convert from 'System.Drawing.Image' to 'Raylib_cs.Image'
There may already be a way to do this, but I couldn't find one in the examples or looking at the lib's code. The Go raylib library provides a NewImageFromImage function that converts a native go Image into a Raylib one, so something like that would probably do
Thanks
would #113 fix your issue, or would you require the use of embedded resources?
That does look interesting thanks, but I ideally want to be able to embed all my resources into a single stand-alone executable and deploy that way
You could always combine the files after building (e.g. copy /b Game.exe + Resources.rres GameWithResources.exe) and then split them up again at runtime by looking for the rres Magic Bytes (HEX: 72 72 65 73).
I am currently developing an rres parser for use with Raylib-cs, so I will take this use-case under consideration
It might be possible to convert it to a raylib Image by creating it directly. You need to check the pixel format matches and make sure the data is unmanaged. Not sure how to get the raw data from a System.Drawing.Image though.
@ChrisDill the System.Drawing.Image wasn't for any particular reason, it was just the way I'm currently loading an image from disk. Any way where I can go from an embedded file to a raylib image would be top cheers
@drum445 Yes, there is a way:
using System;
using Raylib_cs;
using System.Reflection;
using System.Runtime.InteropServices;
static class Program
{
static void Main(string[] args)
{
Raylib.SetConfigFlags(ConfigFlags.FLAG_VSYNC_HINT);
Raylib.InitWindow(1280, 720, "Demo Game");
Texture2D texture;
using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("DemoGame.icon.png")!)
{
using (var memoryStream = new MemoryStream())
{
stream.CopyTo(memoryStream);
var image = LoadImageFromMemory(".png", memoryStream.ToArray(), (int)memoryStream.Length);
texture = Raylib.LoadTextureFromImage(image);
Raylib.UnloadImage(image);
}
}
while (!Raylib.WindowShouldClose())
{
Raylib.BeginDrawing();
Raylib.ClearBackground(Color.BEIGE);
Raylib.DrawTexture(texture, 0, 0, Color.WHITE);
Raylib.EndDrawing();
}
Raylib.UnloadTexture(texture);
Raylib.CloseWindow();
}
[DllImport("raylib", CallingConvention = CallingConvention.Cdecl)]
static extern Image LoadImageFromMemory(string fileType, byte[] fileData, int dataSize);
}
Once you have added your Image as embedded resource in your csproj ...
<ItemGroup>
<EmbeddedResource Include="icon.png" />
</ItemGroup>
... you can load it like above. The "original" LoadImageFromMemory takes a pointer. If you don't want to mess with them, you can write your own method:
[DllImport("raylib", CallingConvention = CallingConvention.Cdecl)]
static extern Image LoadImageFromMemory(string fileType, byte[] fileData, int dataSize);
@JupiterRider Thanks for sharing! Though your example shouldn't load the image with managed memory as the image data and functions around it assume the data to be unmanaged.
@JupiterRider cheers for that, it seems to be working well.
Many thanks 👍