如何用Raylib从数组显示28×28灰度图像?问题排查
问题
想要用Raylib显示MNIST数据集中28×28的灰度数字图像,通过数组实现而非加载预格式化图片,但代码运行后图像呈现彩色而非预期的灰度效果,文本显示正常。
问题分析与解决方案
出现彩色像素的核心原因是像素格式不匹配,同时存在两个次要问题影响显示效果:
- 像素格式错误:你创建的是
Color类型的像素数组(每个像素占4字节,对应RGBA8888格式),但图像格式指定为PIXELFORMAT_UNCOMPRESSED_R32G32B32(每个通道32位,共12字节),格式不匹配导致解析混乱,出现彩色噪点。应改为PIXELFORMAT_UNCOMPRESSED_R8G8B8A8。 - Alpha通道缺失:初始化
Color时只设置了RGB值,Alpha通道默认是0,会导致像素透明。需要将Alpha设为255(完全不透明)。 - 纹理着色错误:
DrawTexture的最后一个参数是色调滤镜,用GRAY会改变图像颜色,应改为WHITE以保留原始像素颜色。
此外,28×28的原图尺寸过小,建议通过缩放放大显示,同时注意Raylib会接管Image.data的内存管理,UnloadImage会自动释放用户传入的像素数组,无需手动free。
修改后的完整代码
#include <stdlib.h> #include <stdio.h> #include "raylib.h" typedef struct Sample { int name; int *data; } sample; void show_sample(sample *smp) { int scW = 800; int scH = 450; InitWindow(scW, scH, "MNIST Sample: 5"); Color *pixels = (Color*)malloc(28 * 28 * sizeof(Color)); for (int i = 0; i < 28 * 28; i++) { int c = smp->data[i]; // 补充Alpha通道为255,确保像素不透明 pixels[i] = (Color){c, c, c, 255}; } Image img = { .data = pixels, .width = 28, .height = 28, // 使用与Color结构体匹配的像素格式 .format = PIXELFORMAT_UNCOMPRESSED_R8G8B8A8, .mipmaps = 1 }; Texture2D texture = LoadTextureFromImage(img); UnloadImage(img); // Raylib自动释放pixels内存 // 设置缩放比例,方便看清小图 float scale = 10.0f; SetTargetFPS(60); while (!WindowShouldClose()) { BeginDrawing(); ClearBackground(GRAY); // 计算居中位置,放大显示图像 Vector2 pos = { (scW - texture.width * scale) / 2, (scH - texture.height * scale) / 2 }; DrawTextureEx(texture, pos, 0.0f, scale, WHITE); DrawText("MNIST数字5(从数组加载的灰度图)", 200, 370, 16, BLACK); EndDrawing(); } UnloadTexture(texture); // 释放纹理资源 CloseWindow(); } int main(int argc, char* argv[]){ int data[]= {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,3,18,18,18,126,136,175,26,166,255,247,127,0,0,0,0, 0,0,0,0,0,0,0,0,30,36,94,154,170,253,253,253,253,253,225,172,253,242,195,64,0,0,0,0, 0,0,0,0,0,0,0,49,238,253,253,253,253,253,253,253,253,251,93,82,82,56,39,0,0,0,0,0, 0,0,0,0,0,0,0,18,219,253,253,253,253,253,198,182,247,241,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,80,156,107,253,253,205,11,0,43,154,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,14,1,154,253,90,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,139,253,190,2,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,11,190,253,70,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,35,241,225,160,108,1,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,81,240,253,253,119,25,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,45,186,253,253,150,27,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,93,252,253,187,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,249,253,249,64,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,46,130,183,253,253,207,2,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,39,148,229,253,253,253,250,182,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,24,114,221,253,253,253,253,201,78,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,23,66,213,253,253,253,253,198,81,2,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,18,171,219,253,253,253,253,195,80,9,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,55,172,226,253,253,253,253,244,133,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,136,253,253,253,212,135,132,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; sample smp; smp.name= 5; smp.data = data; show_sample(&smp); }
优化方案(单通道灰度)
如果想降低内存占用,可以使用单通道灰度格式,每个像素仅占1字节:
// 替换像素数组创建与图像初始化部分 unsigned char *pixels = (unsigned char*)malloc(28 * 28 * sizeof(unsigned char)); for (int i = 0; i < 28 * 28; i++) { pixels[i] = smp->data[i]; } Image img = { .data = pixels, .width = 28, .height = 28, .format = PIXELFORMAT_UNCOMPRESSED_GRAYSCALE, .mipmaps = 1 };
内容的提问来源于stack exchange,提问作者Hackerman
相关产品推荐
相关产品推荐

