比较以Q Image :: Format_Indexed8格式加载的两个相同图像仅在以释放模式运行时才具有不同的像素数据. 以下代码显示在Release中运行时的差异,但在Debug中运行时则不然: int main(){ QImage _img1
以下代码显示在Release中运行时的差异,但在Debug中运行时则不然:
int main() { QImage _img1("C:\\tmp\\diff\\identicals\\file1.png"); QImage _img2("C:\\tmp\\diff\\identicals\\file2.png"); std::cout << QString("Format 1: %1").arg(_img1.format()).toStdString().c_str() << std::endl; std::cout << QString("Format 2: %2").arg(_img2.format()).toStdString().c_str() << std::endl; const unsigned char * _bits1 = _img1.bits(); const unsigned char * _bits2 = _img2.bits(); std::cout << QString("Byte count 1: %1 | Byte count 2: %2").arg(_img1.byteCount()). arg(_img2.byteCount()).toStdString().c_str() << std::endl; for (int _i = 0; _i < _img1.byteCount(); _i++) { if (_bits1[_i] != _bits2[_i]) { std::cout << "--DIFFERENCE--" << std::endl; std::cout << QString("i --> %1").arg(_i).toStdString().c_str() << std::endl; std::cout << QString("Bit1: %1 | Bit2: %2").arg(_bits1[_i]).arg(_bits2[_i]).toStdString().c_str() << std::endl << std::endl; } } std::cout << "BREAK" << std::endl; }
输出:
Format 1: 3 Format 2: 3 Byte count 1: 23424 | Byte count 2: 23424 --DIFFERENCE-- i --> 1535 Bit1: 0 | Bit2: 217 --DIFFERENCE-- i --> 1663 Bit1: 0 | Bit2: 35 --DIFFERENCE-- i --> 1791 Bit1: 0 | Bit2: 94 --DIFFERENCE-- i --> 1919 Bit1: 0 | Bit2: 166 --DIFFERENCE-- i --> 2047 Bit1: 0 | Bit2: 143 --DIFFERENCE-- i --> 2175 Bit1: 0 | Bit2: 104 --DIFFERENCE-- i --> 2303 Bit1: 0 | Bit2: 240 --DIFFERENCE-- i --> 2431 Bit1: 0 | Bit2: 190 --DIFFERENCE-- i --> 2559 Bit1: 0 | Bit2: 129 --DIFFERENCE-- i --> 2687 Bit1: 0 | Bit2: 11 --DIFFERENCE-- i --> 2815 Bit1: 0 | Bit2: 30 --DIFFERENCE-- i --> 2943 Bit1: 0 | Bit2: 163 --DIFFERENCE-- i --> 3071 Bit1: 0 | Bit2: 206 --DIFFERENCE-- i --> 3199 Bit1: 0 | Bit2: 232 --DIFFERENCE-- i --> 3327 Bit1: 0 | Bit2: 124 --DIFFERENCE-- i --> 3455 Bit1: 0 | Bit2: 225 --DIFFERENCE-- i --> 12287 Bit1: 0 | Bit2: 240 --DIFFERENCE-- i --> 12415 Bit1: 0 | Bit2: 224 --DIFFERENCE-- i --> 12543 Bit1: 0 | Bit2: 240
几点说明:
>当使用convertToFormat将图像的格式更改为例如QImage :: Format_ARGB32时,这不再可再现
>使用pixelIndex比较每个像素时,这不再可重现
>总是失败的索引相同
>在其他计算机上运行时失败的索引会发生变化.
我目前的猜测是,当以这种格式加载图像时,Qt会做一些优化.我无法解释为什么这不会导致两个相同图像的相同数据.
如果您想重现问题,这是我的输入图像:
我想我可以看到这里发生了什么.您的图像是8位灰度,宽度为127像素.所有出现差异的索引都是128的倍数(减1,即128字节行中的最后一列).由于您已获得原始图像位,因此图像中的行数据最有可能对齐(通常为2或4个字节).
Qt可能没有在这些填充字节中写入任何内容,因为它们不被视为图像的一部分.所以你真的看到了未定义的行为,因为你的程序无法保证可重复的结果(从未初始化的内存位置加载数据).
要正确比较图像数据,您需要跳过任何填充字节.这意味着你需要知道填充量.鉴于Qt库的丰富性,我确信会有一些方法来访问或推断该信息.
[编辑]我很快查找了QImage的参考,实际上我可以看到扫描线是32位对齐的.实现比较的最简单方法是调用QImage :: bytesPerLine()来确定每个扫描线要比较的字节数,然后通过QImage :: scanLine(int)单独获取每个扫描线