You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 13:06:30