寻求可用的C/C++ DDS图像加载库,现有库加载图像异常
DDS图像加载异常问题排查与解决方案
问题描述
我正在寻找一款可用的、基于C/C++编写的DDS图像加载库,目前已尝试raylib、DevIL及专用DDS图像库,但这些库均无法正常工作,加载后的图像完全错乱。Gimp等图像编辑软件打开该图像也存在问题,但通过Visual Studio 2022却能正常显示该图像,这是为什么?
目标DDS文件头十六进制数据
00000000 44 44 53 20 7C 00 00 00 07 10 0A 00 00 02 00 00 DDS |........... 00000010 00 02 00 00 00 00 04 00 01 00 00 00 0A 00 00 00 ................ 00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000040 00 00 00 00 00 00 00 00 00 00 00 00 20 00 00 00 ............ ... 00000050 04 00 00 00 44 58 31 30 00 00 00 00 00 00 00 00 ....DX10........ 00000060 00 00 00 00 00 00 00 00 00 00 00 00 08 10 40 00 ..............@. 00000070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000080 62 00 00 00 03 00 00 00 00 00 00 00 01 00 00 00 b............... 00000090 00 00 00 00 3A DE 48 82 22 59 86 5F 69 8A C0 FE ....:ÞH‚"Y†_iŠÀþ 000000A0 65 5E E6 A6 68 29 9B CA 24 F3 C9 5C 3A A1 4D 26 e^æ¦h)$óÉ\:¡M& 000000B0 C8 73 65 53 08 31 99 CC 65 D3 D9 6C 3E 9F 4F 27 ÈseS.1™ÌeÓÙl>ŸO' 000000C0 AD AB AC D4 88 31 9F 4E A7 13 0A 85 3E A5 51 29 «¬Ôˆ1ŸN§..…>¥Q) 000000D0 B2 B8 B8 B8 C0 E6 F0 59 8C 1A FF FF 31 F8 41 D7 ²¸¸¸ÀæðYŒ...1øA×
已尝试的raylib加载代码
std::vector<unsigned char> DDS = Utils::LoadBinary("00000@hunkago_01@.DDS"); Image image0 = { &DDS[0], Width, Height, 1, PIXELFORMAT_UNCOMPRESSED_R8G8B8A8 }; Image image1 = LoadImage("00000@hunkago_01@.DDS"); Texture2D texture0 = LoadTextureFromImage(image0); Texture2D texture1 = LoadTextureFromImage(image1); Texture2D texture2 = LoadTexture("00000@hunkago_01@.DDS");
问题原因分析
从文件头可看出,该DDS文件带有DX10扩展头,使用了DirectX 10+的BC7压缩格式(偏移0x60处的格式代码08 10 40 00对应DXGI_FORMAT_BC7_UNORM)。
多数旧版DDS加载库(包括部分raylib、DevIL版本)对DX10扩展DDS的支持不完善,尤其是BC7这类较新的压缩格式。而Visual Studio 2022内置图像查看器采用了DirectX SDK官方解析逻辑,能完整兼容DX10+的DDS格式,因此可以正常显示。
可用的C/C++ DDS加载库推荐
- DirectXTex:微软官方纹理处理库,完美支持所有DX10+ DDS格式(含BC7),API简洁,兼容性拉满。
- stb_image:轻量级单头文件库,最新版本已支持DX10扩展和BC7格式,集成成本极低,适合小型项目。
- FreeImage:更新至较新版本后,对DX10 DDS的支持完善,功能全面,适合多图像格式处理场景。
DirectXTex加载示例代码
#include <DirectXTex.h> #include <wrl/client.h> using namespace DirectX; using Microsoft::WRL::ComPtr; // 加载DDS文件并转为RGBA8格式(需提前初始化D3D11设备) HRESULT LoadDDS(const wchar_t* filePath, ComPtr<ID3D11Resource>& outResource, ComPtr<ID3D11ShaderResourceView>& outSRV, ID3D11Device* d3dDevice) { TexMetadata metadata; ScratchImage scratchImage; HRESULT hr = LoadFromDDSFile(filePath, DDS_FLAGS_NONE, &metadata, scratchImage); if (FAILED(hr)) return hr; // 若为压缩格式,转为RGBA8方便后续处理(可选) ScratchImage convertedImage; if (metadata.format != DXGI_FORMAT_R8G8B8A8_UNORM) { hr = Convert(scratchImage.GetImages(), scratchImage.GetImageCount(), metadata, DXGI_FORMAT_R8G8B8A8_UNORM, TEX_FILTER_DEFAULT, 0.5f, convertedImage); if (FAILED(hr)) return hr; scratchImage = std::move(convertedImage); } // 创建D3D11资源 hr = CreateTexture(d3dDevice, scratchImage.GetImages(), scratchImage.GetImageCount(), metadata, outResource.ReleaseAndGetAddressOf()); if (FAILED(hr)) return hr; // 创建着色器资源视图 hr = CreateShaderResourceView(d3dDevice, outResource.Get(), nullptr, outSRV.ReleaseAndGetAddressOf()); return hr; }
内容的提问来源于stack exchange,提问作者Michael
相关产品推荐
相关产品推荐

