Предисловие:
Я считаю
data1.append(reinterpret_cast<const char *>(img1.constBits()));
неправильным способом заполнения QByteArray
данными, в которых не хранится строка C.
QByteArray::append(const char*)
хорошо для копирования строк C в QByteArray
. Он копирует данные до тех пор, пока не будет найден байт 0 (терминатор 0). 0 байт могут быть где угодно в необработанных данных изображения или нигде. В первом случае копируется слишком мало данных, во втором случае рассматриваются данные вне диапазона. Оба непреднамеренно.
Кстати. даже нет необходимости копировать данные изображения (которые могут иметь значительный размер).
Я сделал образец для сравнения необработанных данных двух QImage
напрямую, включая предварительную проверку размера и формата
Мой образец testQImageRawCmp.cc
#include <QtWidgets>
bool equalImgData(const QImage &qImg1, const QImage &qImg2, int eps = 0)
{
// test properties
#define TEST_PROP(PROP) \
do if (qImg1.PROP != qImg2.PROP) { \
qDebug() << "qImg1."#PROP" != qImg2."#PROP; \
return false; \
} while(false)
TEST_PROP(width());
TEST_PROP(height());
TEST_PROP(format());
#undef TEST_PROP
// test raw data
const uchar *const data1 = qImg1.bits();
const uchar *const data2 = qImg2.bits();
const int bytesPerLine1 = qImg1.bytesPerLine();
const int bytesPerLine2 = qImg2.bytesPerLine();
const int nBits = qImg1.depth() * qImg1.width();
const int nBytes = (nBits + 7) / 8;
assert(nBytes <= bytesPerLine1);
assert(nBytes <= bytesPerLine2);
for (int y = 0; y < qImg1.height(); ++y) {
const uchar *row1 = data1 + y * bytesPerLine1;
const uchar *row2 = data2 + y * bytesPerLine2;
for (int x = 0; x < nBytes; ++x) {
if (abs(row2[x] - row1[x]) > eps) {
qDebug() << "Row" << y << "byte" << x << "difference:" << (row2[x] - row1[x]);
return false;
}
}
}
return true;
}
int main(int argc, char **argv)
{
qDebug() << "Qt Version:" << QT_VERSION_STR;
// load sample data
QImage img1("Picture.jpg");
QImage img2("Picture.bmp");
#if 0 // U.B.
// Juttas test:
QByteArray data1; data1.append(reinterpret_cast<const char *>(img1.constBits()));
QByteArray data2; data2.append(reinterpret_cast<const char *>(img2.constBits()));
#endif // 0
// My test:
if (!equalImgData(img1, img2, 3)) {
qDebug() << "Images not equal!";
} else {
qDebug() << "Images equal.";
}
}
Я протестировал эту программу с данными образца, предоставленными OP:
и получил следующий вывод:
Qt Version: 5.13.0
Row 0 byte 60 difference: 1
Images not equal!
Должен признать, первая версияэтот код только что сообщил о неравенстве.
Затем я попытался создать свой собственный контрпример и преобразовал Picture.bmp
в Picture.bmp.jpg
в GIMP (со 100% настройкой качества, которую я бы посчитал потерей). -Меньше). Это привело к разнице в Row 0 byte 0
. Ой!
Затем мне стало любопытно, и я изменил код, чтобы увидеть насколько отличаются изображения.
Разница 1 в красном, зеленом или синемЗначение пикселя не так много. Я сомневаюсь, что это даже заметно для обычного человека.
Следовательно, я изменил код (в открытую версию), чтобы допустить некоторую разницу.
С eps
из 3:
if (equalImgData(img1, img2, 3)) {
изображения считались равными.