QImage的CacheKey方法返回的确不是图像的普通哈希。有谁知道,高32位是什么意思?在比较两张图片时,我真的可以忽略它们吗? (仅比较低32位?)
仅供说明,此代码多次读取同一图像(但将它们存储在不同的QImage对象中):
printf("%llx\n",QImage("image.png").cacheKey());
printf("%llx\n",QImage("image.png").cacheKey());
printf("%llx\n",QImage("image.png").cacheKey());
返回这个?
144300000002
144400000002
144500000002
还是这个? (好像高32位取决于当前的存储位置)
140800000002
140900000002
140a00000002
答案 0 :(得分:3)
不,您不能使用cacheKey
的任何部分来比较图片内容,它只是为了确保图片自上次cacheKey
值以来未发生变化。只要调用QImage
的任何非const函数,它就会识别缓冲区并进行更改。
但是,正如cacheKey
属性的名称所暗示的那样,您可以将其用作QCache<qint64, QByteArray>
的键,您可以在其中存储仅用{{1}重新计算的图像的实际哈希值仅当图像被更改时(=仅当它不在缓存中时)。
同样QCryptographicHash
不使用像QImage
这样的缓存来读取图像,因此读取相同图像文件3次将分配3个不同的缓冲区,每次使用不同的QPixmap
。为避免每次计算哈希值,您应该查看cacheKey
函数的源代码。
答案 1 :(得分:2)
高32位不依赖任何东西,而是前一图像的32位。它是一个序列号,随着每个新的QImage递增。
答案 2 :(得分:1)
查看QImage的来源:
qint64 QImage::cacheKey() const
{
if (!d)
return 0;
else
return (((qint64) d->ser_no) << 32) | ((qint64) d->detach_no);
}
看起来高32位是d-&gt; ser_no,用QImageData初始化:
QBasicAtomicInt qimage_serial_number = Q_BASIC_ATOMIC_INITIALIZER(1);
QImageData::QImageData()
: ref(0), width(0), height(0), depth(0), nbytes(0), data(0),
#ifdef QT3_SUPPORT
jumptable(0),
#endif
format(QImage::Format_ARGB32), bytes_per_line(0),
ser_no(qimage_serial_number.fetchAndAddRelaxed(1)),
detach_no(0),
dpmx(qt_defaultDpiX() * 100 / qreal(2.54)),
dpmy(qt_defaultDpiY() * 100 / qreal(2.54)),
offset(0, 0), own_data(true), ro_data(false), has_alpha_clut(false),
is_cached(false), paintEngine(0)
{
}
看起来QBasicAtomicInt是一个原子参考计数器(see here)。所以看起来每个新图像在cachekey值中都有不同的高32位,除非你复制它而不是重新创建它。