DirectXTex Resize返回空ScratchImage,OpenCV方案遇断言错误求助
问题解决思路
一、DirectXTex返回空Image的排查与修复
1. 必须检查Resize的返回值
DirectXTex的Resize函数返回HRESULT,你完全忽略了错误检查,这是核心问题。如果Resize过程出现错误(比如格式不支持、参数非法),DSResizedImage会处于空状态,此时GetImage(0,0,0)返回空指针,解引用必然出问题。修改代码如下:
DirectX::ScratchImage DSResizedImage; HRESULT hr = DirectX::Resize( *tex->DSImage.GetImage(0, 0, 0), tex->scaleX, tex->scaleY, DirectX::TEX_FILTER_FLAGS::TEX_FILTER_DEFAULT, DSResizedImage ); if (FAILED(hr)) { printf("Resize failed: 0x%08X\n", hr); // 这里添加错误处理逻辑,比如返回或终止流程 return; } DirectX::Image* pResized1 = DSResizedImage.GetImage(0, 0, 0); if (!pResized1) { // 极端情况兜底检查 return; } DirectX::Image Resized1 = *pResized1;
2. 处理压缩格式图像
如果输入是压缩DDS格式(比如BC1/BC2/BC3等),DirectXTex的Resize无法直接处理,需要先转换为非压缩格式,再执行Resize,按需转回压缩格式:
// 先转换为非压缩格式 DirectX::ScratchImage tempImage; hr = DirectX::Convert( *tex->DSImage.GetImage(0,0,0), DXGI_FORMAT_R8G8B8A8_UNORM, DirectX::TEX_FILTER_FLAGS::TEX_FILTER_DEFAULT, 0.5f, tempImage ); if (FAILED(hr)) { /* 错误处理 */ } // 对非压缩图像执行Resize hr = DirectX::Resize( *tempImage.GetImage(0,0,0), tex->scaleX, tex->scaleY, DirectX::TEX_FILTER_FLAGS::TEX_FILTER_DEFAULT, DSResizedImage ); if (FAILED(hr)) { /* 错误处理 */ }
3. 确认目标尺寸参数合法性
DirectX::Resize的第三、第四个参数是目标图像的宽度和高度,不是缩放比例。确保scaleX/scaleY不为0或负数,且是合理的尺寸值。
二、OpenCV断言错误的修复
断言错误的原因是cv::Rect(tex->offsetX, tex->offsetY, tex->scaleX, tex->scaleY)超出了目标矩阵res的边界,本地无法复现是因为你的测试环境res尺寸足够,但部分用户的res尺寸不足或offset参数计算错误。
修复方案:
- 增加边界检查:
int roiRight = tex->offsetX + tex->scaleX; int roiBottom = tex->offsetY + tex->scaleY; if (tex->offsetX < 0 || tex->offsetY < 0 || tex->scaleX <= 0 || tex->scaleY <= 0 || roiRight > res.cols || roiBottom > res.rows) { printf("ROI out of bounds! res size: %dx%d, ROI: %d,%d %dx%d\n", res.cols, res.rows, tex->offsetX, tex->offsetY, tex->scaleX, tex->scaleY); return; } cvIm.copyTo(res(cv::Rect(tex->offsetX, tex->offsetY, tex->scaleX, tex->scaleY)));
- 确保缩放后图像与ROI匹配:
如果cvIm的原始尺寸和目标ROI尺寸不一致,先缩放再复制,避免隐式缩放带来的边界问题:
cv::Mat scaledIm; cv::resize(cvIm, scaledIm, cv::Size(tex->scaleX, tex->scaleY)); cv::Rect roi(tex->offsetX, tex->offsetY, scaledIm.cols, scaledIm.rows); if (!roi.inside(cv::Rect(0,0,res.cols,res.rows))) { // 错误处理 return; } scaledIm.copyTo(res(roi));
内容的提问来源于stack exchange,提问作者nblock
相关产品推荐
相关产品推荐

