Skip to content

Instantly share code, notes, and snippets.

@niuniulla
Created March 12, 2024 21:09
Show Gist options
  • Save niuniulla/235c3db955ec36cf83fbad0071ebeb65 to your computer and use it in GitHub Desktop.
Save niuniulla/235c3db955ec36cf83fbad0071ebeb65 to your computer and use it in GitHub Desktop.
Example of image loading to pixels and display using SDL
/*
Example of image loading to pixels and display using SDL
The program is a minimal implementation of image loading
using SDL and display it on a window. It creates first a
surface and retrieves the pixels from the last. Then it
updates the texture using the pixels and area of the image.
*/
#include <stdlib.h>
#include <iostream>
#include <memory>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
int main() {
// variables
SDL_Renderer *renderer = nullptr;
SDL_Texture *texture = nullptr;
SDL_Window *window = nullptr;
SDL_Surface *surface = nullptr;
SDL_Event event;
// init sdl
SDL_Init(SDL_INIT_EVERYTHING);
IMG_Init(IMG_INIT_PNG);
// create window
SDL_CreateWindowAndRenderer( 500, 500, 0, &window, &renderer);
// load custom image
surface = IMG_Load("dino.png");
// the format of the surface should be the same as the pixels and the textures
// here the format is Uint32, so for simplicity, I hard coded this format hereafter.
// but this is not a general case. Although there is an example code to check the format
// automatically according to SDL wiki where we can check the read format and set the
// following format accordingly.
// an example can be found here: https://discourse.libsdl.org/t/reading-a-bunch-of-pixelss-alpha-from-a-png-file-using-sdl-image-opengl-sdl-linux/14506/2
std::cout << "DEBUG1: " << (int) surface->format->BytesPerPixel << std::endl;
// get the pixels from surface
// the pixels contain the whole image, we can choose part of it to display after
Uint32* pixels = (Uint32*)(surface->pixels);
Uint32* bgPixels[surface->w*surface->h];
memset(bgPixels, 0, surface->w*surface->h*sizeof(Uint32));
// for convience I create the texture from the surface,
// but I reset it by black color after
texture = SDL_CreateTextureFromSurface(renderer, surface);
// reset background color to bblack
SDL_UpdateTexture(texture, NULL, bgPixels, 425*sizeof(Uint32));
// the area to choose on the image to display
SDL_Rect rect;
rect.w = 80; // to be changed accordingly
rect.h = 100;
// update the texture (back as I set it before) area set by the rect
// by the corresponding pixels
// Be careful that the pitch value represents the length of the row of the loaded image
SDL_UpdateTexture(texture, &rect, pixels, 425*sizeof(Uint32));
// if no pixels infos were involved in the maniplation, we can just load the image directly
// to the texture without all above steps.
//texture = IMG_LoadTexture(renderer, "dino.png");
while (1) {
SDL_RenderCopy(renderer, texture, NULL,NULL);
SDL_RenderPresent(renderer);
if (SDL_PollEvent(&event) && event.type == SDL_QUIT)
break;
}
SDL_FreeSurface(surface);
SDL_DestroyTexture(texture);
IMG_Quit();
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment