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

C++创建图像Bitmap返回null,如何正确构造实现像素扫描

C++ GDI+ Bitmap对象创建失败及逐像素扫描解决方案

问题核心原因排查

  • 未初始化GDI+运行环境:GDI+ 接口使用前必须完成初始化操作,这是最常见的创建返回null的原因
  • 字符串编码转换错误:直接通过迭代器转换std::string到std::wstring仅支持纯ASCII路径,包含中文、特殊符号的路径会出现乱码,导致找不到文件
  • 路径本身无效:文件不存在、无读取权限、格式不被GDI+支持也会返回空对象

正确实现代码

第一步:GDI+ 初始化(程序启动时执行一次即可)

#include <gdiplus.h>
#pragma comment(lib, "gdiplus.lib")

// 全局变量,用于GDI+关闭时使用
ULONG_PTR gdiplusToken;

// 初始化代码放在main函数最开始或者窗口初始化逻辑中
Gdiplus::GdiplusStartupInput startupInput;
Gdiplus::GdiplusStartup(&gdiplusToken, &startupInput, NULL);

// 程序退出前执行关闭逻辑
Gdiplus::GdiplusShutdown(gdiplusToken);

第二步:正确的string转wstring编码转换(适配中文路径)

#include <windows.h>
#include <string>

std::wstring StringToWString(const std::string& str) {
    int len = MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, NULL, 0);
    wchar_t* wstr = new wchar_t[len];
    MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, wstr, len);
    std::wstring result(wstr);
    delete[] wstr;
    return result;
}

第三步:创建Bitmap对象并校验状态

std::string path = currImg.path;
std::wstring pathWstr = StringToWString(path);
Gdiplus::Bitmap* img = new Gdiplus::Bitmap(pathWstr.c_str());

// 校验创建结果
if (img->GetLastStatus() != Gdiplus::Ok) {
    // 创建失败,可根据状态码排查问题:FileNotFound代表文件不存在,InvalidParameter代表参数错误
    delete img;
    img = nullptr;
    // 自行补充错误处理逻辑
}

第四步:高效逐像素扫描获取颜色(优先用LockBits,比逐次调用GetPixel效率高10倍以上)

if (img != nullptr) {
    int width = img->GetWidth();
    int height = img->GetHeight();
    
    Gdiplus::Rect rect(0, 0, width, height);
    Gdiplus::BitmapData bmpData;
    // 锁定像素区域,可读可写
    img->LockBits(&rect, Gdiplus::ImageLockModeRead, PixelFormat32bppARGB, &bmpData);
    
    // 获取像素数据首地址
    BYTE* ptr = (BYTE*)bmpData.Scan0;
    int stride = bmpData.Stride;
    
    for (int y = 0; y < height; y++) {
        for (int x = 0; x < width; x++) {
            // 每个像素占4字节,存储顺序为B、G、R、A
            BYTE b = ptr[y * stride + x * 4 + 0];
            BYTE g = ptr[y * stride + x * 4 + 1];
            BYTE r = ptr[y * stride + x * 4 + 2];
            BYTE a = ptr[y * stride + x * 4 + 3];
            // 此处可对r/g/b/a值进行颜色判断逻辑
        }
    }
    
    // 解锁像素区域,必须调用否则会内存泄漏
    img->UnlockBits(&bmpData);
    // 用完释放Bitmap对象
    delete img;
}

内容的提问来源于stack exchange,提问作者vytaute

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 18:15:03