Storage and View -> imageViewer
Hi,
I'm developing an Qt4 (ATM 4.4) app that will be started from a CD on Windows Hosts. It contains an image viewer and some other stuff.
Now, i use a QLabel to display the image via QPixmap (exactly like in the examples). A SQLite3-DB is attached storing some information to the images.
Is a QLabel already the best way for displaying images? I saw the use of QGraphicsScene and QGraphicsView in an other post in this forum.
ATM, the images are JPG-files laying in an directory (using subfolders as albums). Do I have to take care of anything if i want to store the images completly in the DB? Images are in an binary format, SQLite only offers text and some numerical types, so do i have to use base64-algorythms for that?
C167
Re: Storage and View -> imageViewer
Quote:
Originally Posted by
C167
Is a QLabel already the best way for displaying images?
It depends on what you need. QLabel is perfect if you just want to display an image, but if you need more features, QGV might be better.
Quote:
Originally Posted by
C167
Do I have to take care of anything if i want to store the images completly in the DB?
Qt should handle this for you. Just try passing images as QVariants to QSqlQuery.
You can also consider using Qt's binary resource files and put every album in a separate .rcc file. See: http://doc.trolltech.com/4.3/resources.html
Re: Storage and View -> imageViewer
hm... the app has a minimal size, but no maximum. so the image should be scaled. AFAIR the example does that.
I haven't used QVariant so far...
Code:
QFile *file("./image1.jpg");
map->save(&buffer, "JPG");
and then put it via "INSERT INTO ....." into the DB?
If i put some hundrets of Images in the rcc's, i'll have a binary which is about 500MBs at size, am i right?
Edit: Oh, i forgot, another guy wants to write a single imageviewer in Java, so he should at least know if there is an easy way to read the data in a Qt-Free Java environment
Re: Storage and View -> imageViewer
Quote:
Originally Posted by
C167
hm... the app has a minimal size, but no maximum. so the image should be scaled.
If all you need is an ability to show a single, scaled image, then QLabel will be enough.
Quote:
Originally Posted by
C167
I haven't used QVariant so far...
Code:
QFile *file("./image1.jpg");
map->save(&buffer, "JPG");
All you need is:
Quote:
Originally Posted by
C167
and then put it via "INSERT INTO ....." into the DB?
Yes, but you have to use placeholder and QSqlQuery::bindValue().
Quote:
Originally Posted by
C167
If i put some hundrets of Images in the rcc's, i'll have a binary which is about 500MBs at size, am i right?
Yes, but you can have several rcc files. If you store all of the images in the database, you'll get even bigger file.
Re: Storage and View -> imageViewer
Quote:
Originally Posted by
jacek
If all you need is an ability to show a single, scaled image, then QLabel will be enough.
Hm, one after another, so yes, single file. But for a newbee in Qt it sounds a bit strange to use a Label for that...
Quote:
Originally Posted by
jacek
Oh, thx very much! :)
Quote:
Originally Posted by
jacek
Yea, thats clear
Quote:
Originally Posted by
jacek
Yes, but you can have several rcc files. If you store all of the images in the database, you'll get even bigger file.
Why that? I have 5 JPGs in my rcc, and several SVG-Graphics. I get an 23MB file storing the content in array-format. So that would mean that a QVariant will store much more information than the actual picture? That would mean that only Qt-based programms would be able to read that pictures
Re: Storage and View -> imageViewer
Quote:
Originally Posted by
C167
Why that? I have 5 JPGs in my rcc, and several SVG-Graphics. I get an 23MB file storing the content in array-format.
Are talking here about binary .rcc file or a .cpp file generated by rcc? Anyway, you can ask Qt to compress the resource file --- it should reduce the size of SVG files.
Quote:
Originally Posted by
C167
So that would mean that a QVariant will store much more information than the actual picture?
Not QVariant, but SQLite. It supports only text, so Qt will have to encode the data somehow. Try adding the same files to the database and compare the size of .rcc file and the database.
Quote:
Originally Posted by
C167
That would mean that only Qt-based programms would be able to read that pictures
Yes, only Qt knows how to read .rcc files. Another solution is to use some 3rd party library for storing those files or you can keep them as regular files.
Re: Storage and View -> imageViewer
Quote:
Originally Posted by
jacek
Are talking here about binary .rcc file or a .cpp file generated by rcc? Anyway, you can ask Qt to compress the resource file --- it should reduce the size of SVG files.
hm... i looked at the cpp, sry, the binary that comes out is much smaller.
Quote:
Originally Posted by
jacek
Not QVariant, but SQLite. It supports only text, so Qt will have to encode the data somehow. Try adding the same files to the database and compare the size of .rcc file and the database.
So, is there a documentation about that? AFAIR, base64 would make the files 1.33 times larger
Quote:
Originally Posted by
jacek
Yes, only Qt knows how to read .rcc files. Another solution is to use some 3rd party library for storing those files or you can keep them as regular files.
no, i mean the data in the database... but that would be no big deal to write a simple program that reads one file and outputs the original jpg.
Re: Storage and View -> imageViewer
Quote:
Originally Posted by
C167
So, is there a documentation about that?
I don't think so. I've just made a simple test program and it seems that Qt cheats when it comes to QPixmaps stored as QVariants. You will have to convert images to strings yourself.
Re: Storage and View -> imageViewer
Perhaps I am missing something here, but why shall the application contain the images but not load them dynamically?
At program start up I would rather browse through the image directory/directories, load them and store them into SQLite as BLOBs. BLOBs will be stored "as is" so neither a conversion is necessary nor will this result in an inflated data size.
Pros:
- All images will be automatically be stored in the DB after start up.
- If the CD image changes with respect to new images, no recompilation is necessary.
- A default DB could be created and put on the CD, containing already stored images which are common to all future versions.
Cons:
- Depending on the amount of images to be stored on start up, the time until the application is "ready" could increase significantly.
Re: Storage and View -> imageViewer
[QUOTE=Thomas;59052]Perhaps I am missing something here, but why shall the application contain the images but not load them dynamically?[QUOTE]Oh, maybe i was a bit unclear: the program+database gets copied to the cd, and the program should show the images, either from db directly or with the help of the db, from files. the discussion about containing them was about rcc's, which i use to store the button icons etc.
Quote:
Originally Posted by
Thomas
At program start up I would rather browse through the image directory/directories, load them and store them into SQLite as BLOBs. BLOBs will be stored "as is" so neither a conversion is necessary nor will this result in an inflated data size.
Pros:
- All images will be automatically be stored in the DB after start up.
- If the CD image changes with respect to new images, no recompilation is necessary.
- A default DB could be created and put on the CD, containing already stored images which are common to all future versions.
Cons:
- Depending on the amount of images to be stored on start up, the time until the application is "ready" could increase significantly.
yea, I was unclear :)
we create a CD, that contains:- the cdlauncher
- a pictureDB
- some programms
- pictures, that should be displayed
so, thats similar to digikam: we store information about the pics in the db right now.
ATM, the DB contains some tables containing author-, album- and picture-information. The application loads the db and if you select an image, it gets pulled from the contruct pics/{albumname}/{filename}
Scanning through the images at startup is problematically, because they are on the cd, which is quite slow. it would mean that we would have to browse through nearly 500MBs of images, so the program would need up to several minutes to start. impossible!
But writing a simple two-liner, that uses the db (which already stores everything neccessary, except the pic) to collect every image and writes it into the db, that would be a good method, as we have to run it once, put everything together in an iso and mount it in the windows-vm.
Thanks so far, i'll write a little test-prg to test how we have to deal with images in DBs :)
C167
Re: Storage and View -> imageViewer
okay, i wrote a little testapp that stores an image (or every file you give it) into a BLOB-field. the db-file grows to the size of the given image, so it should be in it, although the chars i get if i do a select to qDebug() are only 8, all unprintable. So, here's my app:
Code:
int main( int argc, char *argv[] )
{
db.setDatabaseName( "/home/stefan/source/qt4/cdlauncher/pictures.db" );
if ( !db.open() )
{
qDebug() << "Opening failed";
return 1;
}
qDebug() << "Opening successfull, using database " << db.databaseName();
qDebug() << "filling an image into the DB...";
QFile file( "/home/stefan/pic/space/191853main_image_feature_929_full.jpg" );
if ( file.exists() )
{
{
fileData = file.readAll();
file.close();
}
}
else
{
qDebug() << "File " << file.fileName() << " could not be located";
}
QSqlQuery query
("UPDATE pictures SET data=? WHERE rowid=1;");
query.addBindValue(fileData);
query.exec();
qDebug() << query.lastError();
return 0;
}
that works :) everything is hardcoded, i know, but its only a test to see how it works.
So, now i want to retrieve the data. the normal way to display an image isAfter some testing, reading and coffee-ing, i found the following way:
Code:
int main( int argc, char *argv[] )
{
Q_INIT_RESOURCE( application );
db.setDatabaseName( "/home/stefan/source/qt4/cdlauncher/pictures.db" );
if ( !db.open() )
{
qDebug() << "Opening failed";
return 1;
}
QSqlQuery query
( "SELECT data FROM pictures WHERE rowid=1;" );
query.next();
qDebug() << query.lastError();
pic->loadFromData( query.value( record.indexOf( "data" ) ).toByteArray() );
imgLabel->setPixmap( *pic );
wid->show();
return app.exec();
}
it successfully reads out the image and displays it...
a SELECT-query seems not to like the QSqlQuery::exec () method. So i used a single next() for that...
So far, everything is fantastic, thank you very much Thomas and jacek :)
Re: Storage and View -> imageViewer
One last issue. :p
Make sure you delete stuff which you created with new. :D
Re: Storage and View -> imageViewer
Quote:
Originally Posted by
C167
If you pass a string to QSqlQuery constructor, it will execute it immediately. It should be:
Code:
query.prepare("UPDATE pictures SET data=? WHERE rowid=1;");
query.addBindValue(fileData);
query.exec();
And the select should be:
Code:
QSqlQuery query
( "SELECT data FROM pictures WHERE rowid=1;" );
query.next(); // <- positions the query on the first row
Re: Storage and View -> imageViewer
Quote:
Originally Posted by
jacek
If you pass a string to QSqlQuery constructor, it will execute it immediately. It should be:
Code:
query.prepare("UPDATE pictures SET data=? WHERE rowid=1;");
query.addBindValue(fileData);
query.exec();
And the select should be:
Code:
QSqlQuery query
( "SELECT data FROM pictures WHERE rowid=1;" );
query.next(); // <- positions the query on the first row
Okay, thank you :)
Quote:
Originally Posted by
Thomas
One last issue. :p
Make sure you delete stuff which you created with new. :D
I thought Qt is handling such things for all the classes that inherit QObject, at least their own stuff? Okay, thx :) I'll add everything to my destructors
Re: Storage and View -> imageViewer
Quote:
Originally Posted by
C167
I thought Qt is handling such things for all the classes that inherit QObject, at least their own stuff?
Yes, it does, but only for objects that have a parent.
Re: Storage and View -> imageViewer