2013-08-23 26 views
0

QImage的CacheKey方法返回的不是真正的圖像的簡單散列。有誰知道,高32位是什麼意思?比較兩幅圖像時,我真的可以忽略它們嗎? (比較只有較低的32位?)基於緩存鍵的QImage比較


僅爲了說明,該代碼讀取同一圖像多次(但將它們存儲在不同的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 

or this? (看起來像高32位取決於當前內存位置)

140800000002 
140900000002 
140a00000002 

回答

2

不,您不能使用cacheKey的任何部分來比較圖片內容,它只是爲了確保自從上次拍攝cacheKey值以來圖片沒有發生變化。它標識緩衝區並在調用QImage的任何非const函數時進行更改。

但是正如cacheKey屬性意味着,你可以使用它作爲一個重要的QCache<qint64, QByteArray>,你將存儲圖像的實際哈希值,只有當圖像被改變,你會只與QCryptographicHash重新計算(=只有名稱如果它不在緩存中)。

QImage而且不使用高速緩存等QPixmap用於讀取圖像,所以讀3次相同的圖像文件將分配3個不同的緩衝器,每次用不同的cacheKey。爲避免每次計算哈希,您應該查看QPixmap::load函數的源代碼。

+0

正如我所理解的,只有比較兩個QImages的方法是將它們保存到QByteArray,通過QCryptographicHash計算散列,然後比較這些散列。我不確定是否逐像素比較它們不會更快...... – petrpulc

+0

這不是唯一的方法(你可以通過將'QImage :: constBits'的結果傳遞給''QByteArray''來保存'QByteArray', QCryptographicHash :: addData'),這取決於你需要多久比較一次'QImage'。如果你只需要比較兩張圖片,你可以使用'=='運算符,如果你需要比較1張圖片和另外10張圖片,哈希可能會更快,但無論如何,你必須對每種方法進行基準測試(但不要'使用'QImage :: pixel()',因爲它非常慢)。 – alexisdm

2

上面的32位依賴於什麼,只是32位的前一個圖像。它是一個序列號,隨着每個新的QImage的增加。

1

在源尋找QImage

qint64 QImage::cacheKey() const 
{ 
    if (!d) 
     return 0; 
    else 
     return (((qint64) d->ser_no) << 32) | ((qint64) d->detach_no); 
} 

看起來像高32位被D-> 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位,除非您複製它而不是重新創建它。