Results 1 to 16 of 16

Thread: Storage and View -> imageViewer

  1. #1
    Join Date
    Jan 2008
    Posts
    40
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default 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

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Storage and View -> imageViewer

    Quote Originally Posted by C167 View Post
    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 View Post
    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

  3. #3
    Join Date
    Jan 2008
    Posts
    40
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default 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...
    Qt Code:
    1. QFile *file("./image1.jpg");
    2. QPixmap *map(QPixmap::fromImage(file));
    3. QByteArray bytes;
    4. QBuffer buffer(&bytes);
    5. buffer.open(QIODevice::WriteOnly);
    6. map->save(&buffer, "JPG");
    7. QVariant variant(bytes);
    To copy to clipboard, switch view to plain text mode 
    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
    Last edited by C167; 5th January 2008 at 16:54.

  4. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Storage and View -> imageViewer

    Quote Originally Posted by C167 View Post
    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 View Post
    I haven't used QVariant so far...
    Qt Code:
    1. QFile *file("./image1.jpg");
    2. QPixmap *map(QPixmap::fromImage(file));
    3. QByteArray bytes;
    4. QBuffer buffer(&bytes);
    5. buffer.open(QIODevice::WriteOnly);
    6. map->save(&buffer, "JPG");
    7. QVariant variant(bytes);
    To copy to clipboard, switch view to plain text mode 
    All you need is:
    Qt Code:
    1. QVariant variant = QPixmap( "./image1.jpg" );
    To copy to clipboard, switch view to plain text mode 

    Quote Originally Posted by C167 View Post
    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 View Post
    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.

  5. #5
    Join Date
    Jan 2008
    Posts
    40
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Storage and View -> imageViewer

    Quote Originally Posted by jacek View Post
    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 View Post
    All you need is:
    Qt Code:
    1. QVariant variant = QPixmap( "./image1.jpg" );
    To copy to clipboard, switch view to plain text mode 
    Oh, thx very much!
    Quote Originally Posted by jacek View Post
    Yes, but you have to use placeholder and QSqlQuery::bindValue().
    Yea, thats clear
    Quote Originally Posted by jacek View Post
    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

  6. #6
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Storage and View -> imageViewer

    Quote Originally Posted by C167 View Post
    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 View Post
    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 View Post
    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.

  7. #7
    Join Date
    Jan 2008
    Posts
    40
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Storage and View -> imageViewer

    Quote Originally Posted by jacek View Post
    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 View Post
    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 View Post
    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.

  8. #8
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Storage and View -> imageViewer

    Quote Originally Posted by C167 View Post
    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.

  9. #9
    Join Date
    Jan 2006
    Location
    Socorro, NM, USA
    Posts
    29
    Thanked 3 Times in 3 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default 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.
    There are 10 people in the world. Those who understand binary and those who don't.

  10. #10
    Join Date
    Jan 2008
    Posts
    40
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default 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 View Post
    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

  11. #11
    Join Date
    Jan 2008
    Posts
    40
    Qt products
    Qt4
    Platforms
    Unix/X11

    Exclamation 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:
    Qt Code:
    1. int main( int argc, char *argv[] )
    2. {
    3. QCoreApplication app( argc, argv );
    4. QSqlDatabase db = QSqlDatabase::addDatabase( "QSQLITE" );
    5. db.setDatabaseName( "/home/stefan/source/qt4/cdlauncher/pictures.db" );
    6. if ( !db.open() )
    7. {
    8. qDebug() << "Opening failed";
    9. return 1;
    10. }
    11. qDebug() << "Opening successfull, using database " << db.databaseName();
    12. qDebug() << "filling an image into the DB...";
    13. QFile file( "/home/stefan/pic/space/191853main_image_feature_929_full.jpg" );
    14. QByteArray fileData;
    15. if ( file.exists() )
    16. {
    17. if ( file.open( QIODevice::ReadOnly ) )
    18. {
    19. fileData = file.readAll();
    20. file.close();
    21. }
    22. }
    23. else
    24. {
    25. qDebug() << "File " << file.fileName() << " could not be located";
    26. }
    27. QSqlQuery query("UPDATE pictures SET data=? WHERE rowid=1;");
    28. query.addBindValue(fileData);
    29. query.exec();
    30. qDebug() << query.lastError();
    31. return 0;
    32. }
    To copy to clipboard, switch view to plain text mode 
    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 is
    Qt Code:
    1. imgLabel->setPixmap(QPixmap::fromImage(QImage("filename")));
    To copy to clipboard, switch view to plain text mode 
    After some testing, reading and coffee-ing, i found the following way:
    Qt Code:
    1. int main( int argc, char *argv[] )
    2. {
    3. Q_INIT_RESOURCE( application );
    4. QApplication app( argc, argv );
    5. QSqlDatabase db = QSqlDatabase::addDatabase( "QSQLITE" );
    6. db.setDatabaseName( "/home/stefan/source/qt4/cdlauncher/pictures.db" );
    7. if ( !db.open() )
    8. {
    9. qDebug() << "Opening failed";
    10. return 1;
    11. }
    12. QSqlQuery query( "SELECT data FROM pictures WHERE rowid=1;" );
    13. QSqlRecord record = query.record();
    14. query.next();
    15. qDebug() << query.lastError();
    16. QByteArray ba = query.value(0).toByteArray();
    17. QWidget *wid = new QWidget();
    18. QLabel *imgLabel = new QLabel( wid );
    19. QPixmap *pic = new QPixmap();
    20. pic->loadFromData( query.value( record.indexOf( "data" ) ).toByteArray() );
    21. imgLabel->setPixmap( *pic );
    22. wid->show();
    23. return app.exec();
    24. }
    To copy to clipboard, switch view to plain text mode 
    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

  12. #12
    Join Date
    Jan 2006
    Location
    Socorro, NM, USA
    Posts
    29
    Thanked 3 Times in 3 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: Storage and View -> imageViewer

    One last issue.

    Make sure you delete stuff which you created with new.
    There are 10 people in the world. Those who understand binary and those who don't.

  13. #13
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Storage and View -> imageViewer

    Quote Originally Posted by C167 View Post
    a SELECT-query seems not to like the QSqlQuery::exec () method.
    If you pass a string to QSqlQuery constructor, it will execute it immediately. It should be:
    Qt Code:
    1. QSqlQuery query;
    2. query.prepare("UPDATE pictures SET data=? WHERE rowid=1;");
    3. query.addBindValue(fileData);
    4. query.exec();
    To copy to clipboard, switch view to plain text mode 

    And the select should be:
    Qt Code:
    1. QSqlQuery query( "SELECT data FROM pictures WHERE rowid=1;" );
    2. query.next(); // <- positions the query on the first row
    3. QSqlRecord record = query.record();
    To copy to clipboard, switch view to plain text mode 

  14. #14
    Join Date
    Jan 2008
    Posts
    40
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Storage and View -> imageViewer

    Quote Originally Posted by jacek View Post
    If you pass a string to QSqlQuery constructor, it will execute it immediately. It should be:
    Qt Code:
    1. QSqlQuery query;
    2. query.prepare("UPDATE pictures SET data=? WHERE rowid=1;");
    3. query.addBindValue(fileData);
    4. query.exec();
    To copy to clipboard, switch view to plain text mode 

    And the select should be:
    Qt Code:
    1. QSqlQuery query( "SELECT data FROM pictures WHERE rowid=1;" );
    2. query.next(); // <- positions the query on the first row
    3. QSqlRecord record = query.record();
    To copy to clipboard, switch view to plain text mode 
    Okay, thank you
    Quote Originally Posted by Thomas View Post
    One last issue.
    Make sure you delete stuff which you created with new.
    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

  15. #15
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Storage and View -> imageViewer

    Quote Originally Posted by C167 View Post
    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.

  16. #16
    Join Date
    Jan 2008
    Posts
    40
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Storage and View -> imageViewer

    okay, thx

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.