This article was originally posted as “SDL2: Loading Images with SDL_image” on 25th November 2013 at Programmer’s Ranch, and has been updated before being reposted here. The source code for this article is available at the Gigi Labs BitBucket repository.
In “SDL2: Displaying an Image in the Window“, we saw how we could load bitmaps using the SDL_LoadBMP() function. Unfortunately, working with bitmaps is very limiting, and the core SDL2 library does not provide the means to work with other image formats. However, such functionality is provided by an extension library called SDL_image. In this article, we will learn how to set up SDL_image and also how to use it to load other image formats.
Setting up SDL_image is not very different from setting up SDL 2.0 itself. You need to go to the SDL_image homepage and download the development libraries:
Extract the include and lib folders inside the zip file over the ones you have in your sdl2 folder. You should get an SDL_image.h file in your include folder, and in your lib\x86 and lib\x64 folders you should get SDL2_image.lib and a whole bunch of DLLs including SDL2_image.dll.
We’ll start off with the same code we had in “Displaying an Image in an SDL2 Window” (you can just grab the source code if you’re lazy). I’ve modified the code so that the image fills the window:
#include <SDL.h> int main(int argc, char ** argv) { bool quit = false; SDL_Event event; SDL_Init(SDL_INIT_VIDEO); SDL_Window * window = SDL_CreateWindow("SDL2 Displaying Image", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, 0); SDL_Renderer * renderer = SDL_CreateRenderer(window, -1, 0); SDL_Surface * image = SDL_LoadBMP("image.bmp"); SDL_Texture * texture = SDL_CreateTextureFromSurface(renderer, image); while (!quit) { SDL_WaitEvent(&event); switch (event.type) { case SDL_QUIT: quit = true; break; } //SDL_Rect dstrect = { 5, 5, 320, 240 }; //SDL_RenderCopy(renderer, texture, NULL, &dstrect); SDL_RenderCopy(renderer, texture, NULL, NULL); SDL_RenderPresent(renderer); } SDL_DestroyTexture(texture); SDL_FreeSurface(image); SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); SDL_Quit(); return 0; }
Now since we’ve introduced a new statically-linked library (i.e. SDL2_image.lib), the first thing we need to do is add it to the Linker -> Input in the project properties:
The entry there should now look like this:
SDL2.lib;SDL2main.lib;SDL2_image.lib
Now, we’re going to load this nice photo (.jpg format) taken in Gardaland in 2006:
Doing this is quite simple. First, we need to include the appropriate header:
#include <SDL_image.h>
Then, we initialise SDL_image by calling IMG_Init() right after the call to SDL_Init()
:
IMG_Init(IMG_INIT_JPG);
…and before the call to SDL_Quit(), we shut down SDL_Image using IMG_Quit():
IMG_Quit();
All we have left to do now is replace the line calling SDL_LoadBMP()
with one that uses IMG_Load() instead:
SDL_Surface * image = IMG_Load("PICT3159.JPG");
You should now be able to build this program (Ctrl+Shift+B). Before you run it, though, make sure that SDL2.dll is in the same folder as your executable. You’ll also need to toss in all the DLLs from the appropriate lib folder (most likely the x86 one is what you’ll be using by default) – that includes SDL2_image.dll along with format-specific files such as libjpeg-9.dll, libpng16-16.dll, etc. And your image file will need to be there too.
And voilà:
Isn’t that sweet? The SDL_image library allows you to load a large variety of image formats, by just replacing SDL_LoadBMP()
with IMG_Load()
. You’ll need to initialise and cleanup the library (although it seems to work even without this) and remember to link the library and include the appropriate header file. But as you can see, it’s pretty straightforward.
I am trying to load images in c++ using SDL2 and SDL_image in Xcode. I copy and pasted your example code, but to no avail: the window was severely tearing and flashing parts of my code and desktop instead of my simple image I was trying to load. This happened using .jpg, .png, and .bmp files. I’m confused why this won’t work for me. And yes I did initialize IMG_Init(…) with the respected file type. Any suggestions?
After debugging, I found that the *image == nullptr, which is strange because my file name is correct. The file name is Test.png, and I tried using “\\Test.png”, “/Test.png”, “[the absolute location on my computer]/Test.png”, and “[the project file]/Test.png”. This is a very frustrating issue
I am trying to load images in c++ using SDL2 and SDL_image in Xcode. I copy and pasted your example code, but to no avail: the window was severely tearing and flashing parts of my code and desktop instead of my simple image I was trying to load. This happened using .jpg, .png, and .bmp files. I’m confused why this won’t work for me. And yes I did initialize IMG_Init(…) with the respected file type. Any suggestions?
While debugging, I noticed that image == nullptr, which may be a reason for the image not loading. I also tried lots of variations of the pathName, including “Test.png”, “\\Test.png”, “/Test.png”, [absolutePath]/Test.png, and [project file path]/Test.png
When I called SDL_RenderClear(renderer) the tearing went away, but I was left with just a black screen.
I suggest you use SDL_GetError() right after the function call that gave you a NULL image pointer, combined with SDL_ShowSimpleMessageBox() to show you what the problem is. There’s an example how to do this in an my old SDL2 Displaying Image article.