Results 1 to 7 of 7

Thread: A big problem with inserting image to BLOB field in MySQL Database...

  1. #1
    Join Date
    Mar 2016
    Posts
    3
    Thanks
    4
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: A big problem with inserting image to BLOB field in MySQL Database...

    Hello there. We were trying to get rid of this problem for 3 days now with no success.
    We have a code that writes an image to QByteArray and then stores it in the MEDIUMBLOB field in MySQL database.
    The problem is that we can't read that array back... AFTER we load the bytearray to the database, it's either corrupted or I don't know what else happens there, but we cannot read it correctly anymore. If we upload an image directly from mysql/phpmyadmin, everything is ok and the program reads the blob fine with the help of QPixmap::loadFromData(). But if we store the array to the blob by our program (not directly from phpmyadmin) - we cannot read it for some reason. We just get "QPixmap(null)". We tried a loooot of ways, reinstalling the program, the database, recompiling the MySQL drivers, a lot of different ways of reading the image (QImage, File, with buffer and without, etc) and no success. Looks like it doesn't store the array into blob properly... Would be very thankful for help! Code snippets in attachment.

    QT version: 5.6.28 (also tried 5.5)
    MySQL version:5.7
    OS : Windows 10


    Added after 1 45 minutes:


    Take a look at the screenshot please.
    To the left you can see the image that we tried to upload through our program, to the right - through the DB.
    As you can see, the database doesn't also recognize our array as an image. What might be the problem? Encoding? Qt?..
    This were two exact the same images.

    NK2Z47FNCYs.jpg
    Attached Files Attached Files
    Last edited by zheleznov; 18th March 2016 at 18:30.

  2. #2
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: A big problem with inserting image to BLOB field in MySQL Database...

    Is the QIODevice::Text flag set on your QBuffer?

  3. The following user says thank you to d_stranz for this useful post:

    zheleznov (19th March 2016)

  4. #3
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: A big problem with inserting image to BLOB field in MySQL Database...

    The problem might be that you are trying to insert binary data into a text string. IMO you should encode it in e.g. base64 and decode it back when inserting into the database.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  5. The following user says thank you to wysota for this useful post:

    zheleznov (19th March 2016)

  6. #4
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: A big problem with inserting image to BLOB field in MySQL Database...

    Going via QPixmap may result in the image being stored with different metadata or compressed differently when saved to the buffer... leading to a binary but not visible difference. Given that you already have the image in a file and you only wish to store it there really is no need to go via QPixmap and QBuffer at all.

    This code works with a Mysql mediumblob. The in.png file and out.png file are bit-for-bit equal:
    Qt Code:
    1. #include <QCoreApplication>
    2. #include <QFile>
    3. #include <QByteArray>
    4. #include <QVariant>
    5. #include <QSqlDatabase>
    6. #include <QSqlQuery>
    7.  
    8. int main(int argc, char **argv)
    9. {
    10. QCoreApplication app(argc, argv);
    11.  
    12. QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
    13. db.setHostName("localhost");
    14. db.setDatabaseName("test");
    15. db.setUserName("test");
    16. db.setPassword("test");
    17. if (db.open()) {
    18. QSqlQuery qry("delete from testdata");
    19.  
    20. QFile in("in.png");
    21. if (in.open(QIODevice::ReadOnly)) {
    22. QByteArray data = in.readAll();
    23. qry.prepare("INSERT INTO testdata (firstname , secondname , userfoto) VALUES (?,?,?)");
    24. qry.bindValue(0, QVariant("Dummy"));
    25. qry.bindValue(1, QVariant("Dummy"));
    26. qry.bindValue(2, data);
    27. qry.exec();
    28. }
    29.  
    30. QFile out("out.png");
    31. if (out.open(QIODevice::WriteOnly)) {
    32. qry.prepare("SELECT userfoto from testdata");
    33. qry.exec();
    34. qry.next();
    35. QByteArray data = qry.value(0).toByteArray();
    36. out.write(data);
    37. }
    38. }
    39. return 0;
    40. }
    To copy to clipboard, switch view to plain text mode 
    Qt Code:
    1. CREATE TABLE `testdata` (
    2. `firstname` varchar(50) DEFAULT NULL,
    3. `secondname` varchar(50) DEFAULT NULL,
    4. `userfoto` mediumblob
    5. )
    To copy to clipboard, switch view to plain text mode 
    Qt 5.5.1, Mysql 5.6.28, Linux

  7. The following user says thank you to ChrisW67 for this useful post:

    zheleznov (19th March 2016)

  8. #5
    Join Date
    Mar 2016
    Posts
    3
    Thanks
    4
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: A big problem with inserting image to BLOB field in MySQL Database...

    Quote Originally Posted by ChrisW67 View Post
    Going via QPixmap may result in the image being stored with different metadata or compressed differently when saved to the buffer... leading to a binary but not visible difference. Given that you already have the image in a file and you only wish to store it there really is no need to go via QPixmap and QBuffer at all.

    This code works with a Mysql mediumblob. The in.png file and out.png file are bit-for-bit equal:
    Qt Code:
    1. #include <QCoreApplication>
    2. #include <QFile>
    3. #include <QByteArray>
    4. #include <QVariant>
    5. #include <QSqlDatabase>
    6. #include <QSqlQuery>
    7.  
    8. int main(int argc, char **argv)
    9. {
    10. QCoreApplication app(argc, argv);
    11.  
    12. QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
    13. db.setHostName("localhost");
    14. db.setDatabaseName("test");
    15. db.setUserName("test");
    16. db.setPassword("test");
    17. if (db.open()) {
    18. QSqlQuery qry("delete from testdata");
    19.  
    20. QFile in("in.png");
    21. if (in.open(QIODevice::ReadOnly)) {
    22. QByteArray data = in.readAll();
    23. qry.prepare("INSERT INTO testdata (firstname , secondname , userfoto) VALUES (?,?,?)");
    24. qry.bindValue(0, QVariant("Dummy"));
    25. qry.bindValue(1, QVariant("Dummy"));
    26. qry.bindValue(2, data);
    27. qry.exec();
    28. }
    29.  
    30. QFile out("out.png");
    31. if (out.open(QIODevice::WriteOnly)) {
    32. qry.prepare("SELECT userfoto from testdata");
    33. qry.exec();
    34. qry.next();
    35. QByteArray data = qry.value(0).toByteArray();
    36. out.write(data);
    37. }
    38. }
    39. return 0;
    40. }
    To copy to clipboard, switch view to plain text mode 
    Qt Code:
    1. CREATE TABLE `testdata` (
    2. `firstname` varchar(50) DEFAULT NULL,
    3. `secondname` varchar(50) DEFAULT NULL,
    4. `userfoto` mediumblob
    5. )
    To copy to clipboard, switch view to plain text mode 
    Qt 5.5.1, Mysql 5.6.28, Linux
    No way! This code worked out for us , though we have already tried working through the file, but I guess we didn't read it through the file! Will try implementing this in our program, Biggest Thanks to you! Will keep you informed...

    Best regards.


    Added after 32 minutes:


    Damn, for some reason it doesn't work in our program. The same problem occurs... I think the only way to understand what happens is to upload our project here so you can see the whole process.


    Added after 34 minutes:


    https://dropmefiles.com/4lBK5
    Here is the project. Would be VERY thankful if someone could take a look and say what is the problem...
    Last edited by zheleznov; 19th March 2016 at 12:25.

  9. #6
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: A big problem with inserting image to BLOB field in MySQL Database...

    I ran your code in my environment using Qt 5.4.1 and (with minor mods) Qt 4.8.6. Both produced the issue you complain of: the stored binary data is not the same as the loaded binary data. As wysota suggested, it appears the binary data has been treated as character data at some point: but not obviously in your code.
    The original PNG file starts with the standard 8 byte header:
    Qt Code:
    1. .. .. 89 50 4e 47 0d 0a 1a 0a
    To copy to clipboard, switch view to plain text mode 
    The output "PNG" has been mangled to start:
    Qt Code:
    1. ef bf bd 50 4e 47 0d 0a 1a 0a
    To copy to clipboard, switch view to plain text mode 
    The first three bytes of the output; "ef bf bd" is the UTF-8 encoding of the Unicode U+FFFD code point. That code point is used to substitute for a part of string that is invalid in the encoding being used to interpret it. If the original binary was interpreted (incorrectly) as UTF-8 then the "89" byte would be stored as U+FFFD in a UTF-16 string which would become the bytes we see if output as UTF-8.

    Your insert and select statement strings are compounds of a Mysql "USE test;" and the SQL. The database you are connected to is set by the QSqlDatabase connection you use and need not be specified again. Removing the "USE test;" from both statements makes the code behave. I can only think that the switch of connection caused by "USE", or the compound statement itself confused the Qt bindValue() or Mysql, or both.

  10. The following user says thank you to ChrisW67 for this useful post:

    zheleznov (20th March 2016)

  11. #7
    Join Date
    Mar 2016
    Posts
    3
    Thanks
    4
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: A big problem with inserting image to BLOB field in MySQL Database...

    Quote Originally Posted by ChrisW67 View Post
    I ran your code in my environment using Qt 5.4.1 and (with minor mods) Qt 4.8.6. Both produced the issue you complain of: the stored binary data is not the same as the loaded binary data. As wysota suggested, it appears the binary data has been treated as character data at some point: but not obviously in your code.
    The original PNG file starts with the standard 8 byte header:
    Qt Code:
    1. .. .. 89 50 4e 47 0d 0a 1a 0a
    To copy to clipboard, switch view to plain text mode 
    The output "PNG" has been mangled to start:
    Qt Code:
    1. ef bf bd 50 4e 47 0d 0a 1a 0a
    To copy to clipboard, switch view to plain text mode 
    The first three bytes of the output; "ef bf bd" is the UTF-8 encoding of the Unicode U+FFFD code point. That code point is used to substitute for a part of string that is invalid in the encoding being used to interpret it. If the original binary was interpreted (incorrectly) as UTF-8 then the "89" byte would be stored as U+FFFD in a UTF-16 string which would become the bytes we see if output as UTF-8.

    Your insert and select statement strings are compounds of a Mysql "USE test;" and the SQL. The database you are connected to is set by the QSqlDatabase connection you use and need not be specified again. Removing the "USE test;" from both statements makes the code behave. I can only think that the switch of connection caused by "USE", or the compound statement itself confused the Qt bindValue() or Mysql, or both.
    Thank you, this is what fixed our problem now... You are a Man among men

Similar Threads

  1. Replies: 24
    Last Post: 3rd September 2015, 13:36
  2. Replies: 4
    Last Post: 16th June 2011, 14:49
  3. Inserting blob into mysql using QT?
    By maverick_pol in forum Qt Programming
    Replies: 4
    Last Post: 31st August 2010, 04:37
  4. Replies: 2
    Last Post: 17th February 2010, 14:32
  5. Replies: 1
    Last Post: 14th September 2009, 08:48

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.