基于缓存键的QImage比较

时间:2013-08-23 14:53:39

标签: c++ qt qimage

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

3 个答案:

答案 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位,除非你复制它而不是重新创建它。