PDA

View Full Version : Generate image checksum



bunjee
22nd May 2008, 15:15
Here is what I'm doing to calculate an Image checksum :


quint16 ZePicturePool::generateChecksum(const QPixmap & pixmap)
{
QImage image = pixmap.toImage();
quint16 checksum = qChecksum((char *) (image.bits()), image.numBytes());

return checksum;
}

Is it the good approach ?

jacek
22nd May 2008, 16:00
What do you need that checksum for?

bunjee
22nd May 2008, 16:37
To check wether a Pixmap is already in my cache or not.

jacek
22nd May 2008, 16:55
How many pixmaps are you going to operate on? Also take a look at QPixmapCache.

bunjee
22nd May 2008, 18:41
I just want to validate if my checksum calculation is good :).

And yes I'm using pixmap cache, in my case pixmap's path is not enough to define a pixmap.

jacek
22nd May 2008, 19:39
I just want to validate if my checksum calculation is good :).
It's OK, if you won't have a lot of pixmaps.

bunjee
8th June 2008, 17:33
Unfortunately I get some glitches using that approach.

Since I'm using a huge number of pixmap, sometimes it picks the same one.

How can I refine this ?

spud
8th June 2008, 19:59
How about a combination of file path and creation date?

bunjee
8th June 2008, 21:16
Not good in my case I want to rely on QImage's data and that's all.

I've seen there is a 32bit checksum in Zlib, has anyone ever used that ? I don't want to add one dependency just for a checksum.

jacek
8th June 2008, 23:20
Since I'm using a huge number of pixmap, sometimes it picks the same one.

How can I refine this ?
You need a longer checksum, like MD5 hash. Of course it will take more time to calculate it and still there is some probability of a collision.

Maybe there is some other way to assign an unique identifier to those pixmaps? Where do they come from?

bunjee
8th June 2008, 23:46
Well I'm developping an instant messenging app.

Basically this is all the contact avatars.

BUT cached and displayed in various size, so I can have the same base pixmap but resized AND cached.

I think I might use a combination of checksum and pixmap size to match them.

jacek
9th June 2008, 01:02
Basically this is all the contact avatars.
What is the maximum size of such pixmap?


BUT cached and displayed in various size, so I can have the same base pixmap but resized AND cached.
Is the checksum valid only during a single session or you want to keep it after user closes the application? Is it important for you that two exactly the same pixmaps that come from two different sources have the same checksum?

bunjee
9th June 2008, 02:01
What is the maximum size of such pixmap?

No maximum size.


Is the checksum valid only during a single session or you want to keep it after user closes the application?

Valid during a given session.


Is it important for you that two exactly the same pixmaps that come from two different sources have the same checksum?

Yes it is, it speeds up the display that I don't regenerate the pixmap.

patrik08
9th June 2008, 14:18
I use md5 to check image stream or to stop connection param if the same as last..




static inline QByteArray fastmd5( const QString xml )
{
QCryptographicHash formats( QCryptographicHash::Md5 );
formats.addData(xml.toUtf8());
return formats.result();
}

static inline QByteArray fastmd5( const QByteArray xml )
{
QCryptographicHash formats( QCryptographicHash::Md5 );
formats.addData(xml);
return formats.result();
}





/* fill params */
/* take qmenu from other layer edit or same as last? */
void PageWindow::PlayOn()
{
TextLayer *iter = CurrentView->LayerModel();
const int LayID = iter->data(ObjectNameEditor).toInt();
const QString editable = LayID == 0 ? "no" : "yes";
bool canedit = LayID == 0 ? false : true;
const QString Pmyhash = QString("%1-%2-%3-%4-%5").arg(editable) /* can edit area */
.arg(Clang) /* language */
.arg(wdoc->ID()) /* document nr .*/
.arg(LayID) /* layer nummer*/
.arg(iter->textCursor().position()); /* cursor position */
emit menupage(canedit,fastmd5(Pmyhash));
}


void Gui_Main::editor( bool e , const QByteArray hashpage )
{
if (LastHash == hashpage) {
/* not make job ist the same edit status as last! */
return;
} else {
LastHash = hashpage;
}
/* continue ok*/





My QImage cache work in this way to compose Multiple Animated Portable Network Graphics APNG... and all frame is unique...

http://www.qt-apps.org/content/show.php/Apng+Video+Frame+Label?content=82221




class StreamFile
{
public:
StreamFile()
:d(new QBuffer())
{
d->open(QIODevice::ReadWrite);
start();
}
~StreamFile()
{
d->close();
}
bool clear()
{
d->write(QByteArray());
return d->bytesAvailable() == 0 ? true : false;
}
void start() {
d->seek(0);
}
bool LoadFile( const QString file ) {
if (clear()) {
QFile f(file);
if (f.exists()) {
if (f.open(QFile::ReadOnly)) {
d->write(f.readAll());
f.close();
start();
return true;
}
}
}
return false;
}
bool PutOnFile( const QString file ) {
QFile f(file);
if (f.open(QFile::WriteOnly)) {
uint bi = f.write(d->readAll());
start();
return bi > 0 ? true : false;
}
return false;
}
QBuffer *device() { return d; }
bool isValid() { return img.loadFromData(stream()); }
QByteArray stream() { return d->data(); }
QImage img;
QBuffer *d;
};

jacek
10th June 2008, 02:16
Valid during a given session.
Ok, so this reduces the chance of a collision.


No maximum size.
[...]
Yes it is, it speeds up the display that I don't regenerate the pixmap.
But unfortunately these two make things worse.

MD5 hashes have 128 bits, so a chance for a collision is quite low and they're of better quality than simple CRCs. The only problem is that they take more time to compute, but I don't think that it will be noticeable for the user if you compute them once per image.