使用GDI+读取图片尺寸:WinAPI获取路径时返回0的问题
问题:WinAPI遍历文件夹后GDI+获取图片尺寸始终返回0
你遇到的问题其实是一个很容易忽略的路径拼接错误,我来帮你拆解一下:
问题根源
当你用FindFirstFile/FindNextFile遍历文件夹时,data.cFileName只返回文件名(比如Untitled.gif),而不是完整路径。但你直接指定路径时用的是C:\\Test\\Untitled.gif这种完整路径,这就导致Image::FromFile调用时找不到对应文件。
更坑的是,GDI+的Image::FromFile在找不到文件时,不会返回nullptr,而是返回一个无效的Image对象。这时候调用GetWidth()和GetHeight()就会返回0,这就是你看到的现象。
解决方案
只需要在收集文件名时,把遍历的根路径和文件名拼接成完整路径即可:
修改遍历部分的代码:
#else // Failure std::list<std::wstring> fileNames; const std::wstring rootPath = L"C:\\Test\\"; // 定义根路径 WIN32_FIND_DATA data; HANDLE hFind = ::FindFirstFile((rootPath + L"*").c_str(), &data); if (INVALID_HANDLE_VALUE != hFind) { static const auto skipAttributes{ FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_TEMPORARY }; do { if (data.dwFileAttributes & skipAttributes) { continue; } // 拼接完整路径 fileNames.push_back(rootPath + std::wstring(data.cFileName)); } while (::FindNextFile(hFind, &data)); ::FindClose(hFind); } #endif
额外提示
如果你的实际项目中根路径是动态的,记得用PathCombine或者C++的字符串拼接来确保路径格式正确(比如避免重复的\\)。另外,也可以在创建Image对象后,用GetLastStatus()来检查是否加载成功,比如:
ImagePtr pImage{ Image::FromFile(fileName.c_str()) }; if (pImage.get() && pImage->GetLastStatus() == Gdiplus::Ok) { ::wprintf(L"%s width = %d height = %d\n", fileName.c_str(), pImage->GetWidth(), pImage->GetHeight()); } else { ::wprintf(L"Failed to load %s\n", fileName.c_str()); }
这样能更直观地排查加载失败的原因。
内容的提问来源于stack exchange,提问作者Alexander Stoimenov
相关产品推荐
相关产品推荐

