Cxxdroid 中文文档 下载 App

SDL2 图片加载 —— PNG/JPG/BMP 怎么画到屏幕上

两个层次

SDL2 加载图片分两步:

  1. SDL_image 库:把磁盘上的 PNG、JPG、BMP 读进内存,转成 SDL_Surface(CPU 端的像素数组)
  2. SDL_Texture:把 Surface 上传到 GPU,才能在渲染器上高效绘制

如果只用 SDL2 核心库,只能加载 BMP 格式(SDL_LoadBMP)。要加载 PNG/JPG 需要额外的 SDL_image 扩展库。

安装 SDL_image

包管理器搜索「SDL_image」或「sdl2-image」。部分版本的 Cxxdroid 会把 SDL_image 作为 SDL2 的依赖自动装上。

CMake 链接:

find_package(SDL2_image REQUIRED)
target_link_libraries(mygame PRIVATE SDL2::SDL2 SDL2_image::SDL2_image)

加载流程

#include <SDL2/SDL.h>
#include <SDL2_image/SDL_image.h>

int main() {
    SDL_Init(SDL_INIT_VIDEO);
    IMG_Init(IMG_INIT_PNG);  // 初始化 PNG 支持

    SDL_Window *win = SDL_CreateWindow("Image",
        0, 0, 320, 480, SDL_WINDOW_SHOWN);
    SDL_Renderer *ren = SDL_CreateRenderer(win, -1, 0);

    // 1. 加载图片到 Surface
    SDL_Surface *surf = IMG_Load("test.png");
    if (!surf) {
        // 加载失败
    }

    // 2. Surface → Texture(上传到 GPU)
    SDL_Texture *tex = SDL_CreateTextureFromSurface(ren, surf);
    SDL_FreeSurface(surf);  // Surface 可以释放了

    // 3. 渲染 Texture
    SDL_RenderCopy(ren, tex, nullptr, nullptr);
    SDL_RenderPresent(ren);

    SDL_Delay(3000);

    SDL_DestroyTexture(tex);
    SDL_DestroyRenderer(ren);
    SDL_DestroyWindow(win);
    IMG_Quit();
    SDL_Quit();
    return 0;
}

文件路径问题(Cxxdroid 特有)

这是新手最容易踩的坑。图片文件放哪?程序运行时用什么路径访问?

默认工作目录:Cxxdroid 编译运行的可执行文件,默认工作目录是项目的 build 目录(应用内部存储)。

所以如果你的项目结构是:

项目名/
├── main.cpp
├── test.png          ← 图片在这里
└── build/            ← 可执行文件运行时在这里

代码里写 IMG_Load("test.png") 会找不到文件——因为运行目录是 build/,而图片在项目根目录。

解决方案:

  1. 把图片复制到 build/ 目录:最简单但每次重新编译可能会丢
  2. 用相对路径向上一级:IMG_Load("../test.png")
  3. 拷到 Android 公共目录:/sdcard/Pictures/ 然后绝对路径加载:IMG_Load("/sdcard/Pictures/test.png")
  4. 2026 新版 SAF:支持 Storage Access Framework,可以选择外部存储目录授权,路径处理更灵活

渲染 Texture 时的参数

SDL_RenderCopy(ren, tex, srcRect, dstRect) 有两个矩形参数:

SDL_Rect src = {0, 0, 64, 64};      // 从源图截取左上角 64×64
SDL_Rect dst = {100, 200, 128, 128}; // 渲染到屏幕 (100,200) 位置,放大到 128×128
SDL_RenderCopy(ren, tex, &src, &dst);

旋转与翻转

SDL_RenderCopyEx 增加了旋转角度、翻转标志:

SDL_RenderCopyEx(ren, tex, nullptr, &dst,
    45.0,         // 旋转 45 度
    nullptr,      // 旋转中心(nullptr = 矩形中心)
    SDL_FLIP_NONE);  // SDL_FLIP_HORIZONTAL / SDL_FLIP_VERTICAL / SDL_FLIP_NONE

内存管理

加载的 Texture 用完记得释放:

SDL_DestroyTexture(tex);

Texture 是 GPU 内存,不及时释放会导致显存不足(Android 设备的 GPU 显存很有限)。