-1

i get an base64 encoded image from the cpprestsdk and try to show it in an sdl window.

I cant create a surface from the base64 string, but it works well from a file on disk.

I have tried multiple conversions of the string to char arrays and vectors but the SDL_Surface is always null at the end.

These two posts guided me in the direction of SDL_RWops:

SDL_Surface* base64ToSurface(std::string *image)
{
    SDL_RWops *rw = SDL_RWFromConstMem(image, sizeof(image));
    SDL_Surface *img = SDL_LoadBMP_RW(rw, 1);        
    if (img == nullptr)
    {
        logSDLError(std::cout, "base64ToSurface");
    }
    return img;
}

void convertBase64ToTexture()
{
    //base64 image string trimmed for a better readability
    std::string aImage = "R0lGODlhPQB...";

    SDL_Window *aWindow = SDL_CreateWindow("Lesson 2", 100, 100, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
    SDL_Renderer *aRenderer = SDL_CreateRenderer(aWindow, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
    SDL_Surface *aSurface = base64ToSurface(&aImage);
    SDL_Texture *texture = nullptr;
    texture = SDL_CreateTextureFromSurface(aRenderer, aSurface);
    //Make sure converting went ok too
    if (texture == nullptr) 
    {
        logSDLError(std::cout, "CreateTextureFromSurface");
    }
}
genpfault
  • 51,148
  • 11
  • 85
  • 139
Simon
  • 87
  • 5
  • So...where's your base64 decode routine? Right now it looks like you're just passing in base64 bytes to `SDL_LoadBMP_RW()` and hoping for the best. – genpfault Feb 01 '19 at 22:23
  • Not even that, you're asking SDL to interpret the first 4/8 bytes of a `std::string` object (not the string it holds, the object itself) as an image. That...won't work. – genpfault Feb 01 '19 at 22:26
  • Im new to c++ and SDL and tried multiple ways of decoding the string. This example was to simplify the setup. I did not find help by extensive google research. Im not even sure if it is possible to display a image in sdl from a base64 string. – Simon Feb 01 '19 at 22:35
  • 1
    @Simon you need to [decode base64](https://stackoverflow.com/a/13935718/744720) into byte array and pass that array (along with its length! your `sizeof(image)` gives you size of a pointer, which have nothing to do with size of image data) to `SDL_RWFromConstMem`. E.g. with decode from linked example (which I don't think is the best way to do things) `std::vector img_vec = base64_decode(aImage); SDL_RWops *rw = SDL_RWFromConstMem(&img_vec[0], img_vec.size());`. – keltar Feb 02 '19 at 08:38

1 Answers1

1

Thank you for your help keltar that helped me a immediately. If you add your comment as an answear i will vote it.

Following the code that is loading a base64 jpg into a sdl window.

void LoadImageJpeg(std::wstring theImage, int x, int y)
{
    //Clear the window
    //SDL_RenderClear(renderer);
    std::vector<unsigned char> img_vec = base64_decode(theImage);
    SDL_RWops *rw = SDL_RWFromConstMem(&img_vec[0], img_vec.size());
    SDL_Surface *aSurface = IMG_LoadTyped_RW(rw, 1, "JPG");
    if (aSurface == nullptr) {
        logSDLError(std::cout, "base64ToSurface");
    }
    SDL_Texture *texture = nullptr;
    texture = SDL_CreateTextureFromSurface(renderer, aSurface);
    //Make sure converting went ok too
    if (texture == nullptr) {
        logSDLError(std::cout, "CreateTextureFromSurface");
    }
    renderTexture(texture, renderer, 0, 0);
    SDL_RenderPresent(renderer);
    //SDL_Delay(500);
}

Thank you.

Simon
  • 87
  • 5