How can convert image byte array to sdlsurface?

I’m Ko.

I am currently studying to display images on the screen using SDL. Outputting an image using SDL_Image.IMG_LOAD() was successful.

But what I want is to print an image using the byte[] or byte array of bitmap received through TCP communication.

I don’t know how to output a structure composed of byte arrangements.

I looked for many ways, but all of them failed. I’d really appreciate your help.

void GetSDLImage(byte[] buffer)
{
SDL_Texture* imagetexture ;

SDL_RenderCopy(renderer, imagetexture, null, null)
SDL_RenderPresent(renderer);
}

SDL_RWFromMem and IMG_Load_RW should work fine.

I looked for many ways, but all of them failed

also, what did you actually try doing?

I’m one of the many attempts.

I used C#.

    private bool GetImageToRender(byte[] _BackgroundImage, int width, int height)
    {
        unsafe
        {
            fixed (byte* pdata = _BackgroundImage)
            {
                IntPtr DataPtr = new IntPtr(pdata);

                SDL.SDL_Rect sdl_rect = new SDL.SDL_Rect() { x = 0, y = 0, w = width, h = height };
                if (SDL.SDL_UpdateTexture(_BackgroundTexture, ref sdl_rect, DataPtr, sdl_rect.w) != 0)
                {
                    return false;
                }
            }
        }

        if (SDL.SDL_RenderCopy(_Renderer, _BackgroundTexture, IntPtr.Zero, IntPtr.Zero) != 0)
        {
            return false;
        }

        return true;
    }

I think the way I received the packet was wrong, so I tried it myself.

        Bitmap bb = new Bitmap(@"D:\2.jpg");
        int w = bb.Width;
        int h = bb.Height;
        bb.Dispose();

        FileStream ff = File.Open(@"D:\2.jpg", FileMode.Open);
        MemoryStream ms = new MemoryStream();
        ff.CopyTo(ms, (int)ff.Length);

        IntPtr pxls;
        unsafe
        {
            fixed (byte* ptr = ms.ToArray())
            {
                pxls = new IntPtr(ptr);
                SDL.SDL_Rect sdl_rect = new SDL.SDL_Rect() { x = 0, y = 0, w = w, h = h };
                SDL.SDL_UpdateTexture(_BackgroundTexture, ref sdl_rect, pxls, w);
            }
        }
        SDL.SDL_RenderCopy(_Renderer, _BackgroundTexture, IntPtr.Zero, IntPtr.Zero);
        SDL.SDL_RenderPresent(_Renderer);

Note: I have no experience with c# so I might be wrong on some of these things.

You’re probably dealing with jpeg and not the raw pixels that’s required for SDL_UpdateTexture, which is why you use the SDL_image library to deal with the formats.

SDL_Surface has a width and height field so there’s no reason to use Bitmap.

I found a way, but I don’t think this is the answer.

It seems that the method of saving an image using a bitmap as a receiving buffer and bringing it back is not the correct answer.

If there is an example used in C++, I would appreciate it if you could upload it.
I can refer to it and use it in C#.

It’s not the correct answer. It’s working.
{
Bitmap bb = new Bitmap(ms); //ms = jpg image buffer
bb.Save(“D:\1.jpg”);
bb.Dispose();
SDL_image.IMG_Load(@“D:\1.jpg”);

}

and I tried
SDL_CreateRGBSurface()…
But not work…

You’re just trying to display an image which is somewhere in memory that you
can access right?

So just get the buffer containing the raw bytes of the image (in formats
supported by SDL_image), and then create the SDL abstraction for IO which is
SDL_RWops which in turn is used by
SDL_image through the functions that end in RW (e.g
IMG_Load_RW).
Then you can just use the texture or surface however you like.

Note: I’m only not handling errors here to keep it small.

	SDL_Renderer *r;
	// do things like initializing SDL...
	int bufsize;
	char *buf = getBuffer(&size);

	SDL_Texture *t = IMG_LoadTexture_RW(r, SDL_RWFromConstMem(buf, bufsize), 1);

	freeBuffer(buf, bufsize);

	SDL_RenderCopy(r, t, NULL, NULL);
	SDL_RenderPresent(r);

and if you want the size of the image replace IMG_LoadTexture_RW with:

	SDL_Surface *s = IMG_Load_RW(SDL_RWFromConstMem(buf, bufsize), 1);
	int width = s->w;
	int height = s->h;
	SDL_Texture *t = SDL_CreateTextureFromSurface(r, s);

the 1 in IMG_Load*RW is to free the SDL_RWops otherwise you’ll have to
free it yourself with SDL_RWclose

1 Like

Oh!!
I solved it with your advice.
SDL_RWFromConstMem()
I learned this function for the first time.

Thank you very much.
I wouldn’t have solved this problem without your help.

1 Like