About the QImage::bits() method



  • I was doing some tests using the QImage class, specifically the bits() method:
    http://qt-project.org/doc/qt-4.8/qimage.html#bits

    Here is a piece of my code:
    @
    QImage image("test.png", "PNG");
    QByteArray byteMe((char *) image.bits());
    int bitmap = byteMe.size();

    QFile file("bitmap.bin");
    if (!file.open(QIODevice::WriteOnly))
        return 0;
    file.write(byteMe);
    file.close();
    
    fprintf(stderr, "Buffer size: %d\n", bitmap);
    

    @

    This is the output I got:
    Buffer size: 81276

    This is the size of the file I created:
    $ ls -al bitmap.bin
    -rw-r--r-- 1 xtingray localhost 81276 2012-04-20 13:43 bitmap.bin

    And these are the specs of the image file I'm using:
    $ file test.png
    test.png: PNG image data, 520 x 380, 8-bit/color RGB, non-interlaced

    Now, my question is about this:

    If I have a RGB image of size 520 x 380, it means that I have 197600 pixels to play with. Now, if we are talking of a RGB image, then every pixel must be formed of three compounds (Red, Green and Blue) so, we are talking of 197600 x 3 (592800) units of color data (in my case).

    Nevertheless, the method QImage::bits() is returning a size of 81276 bytes. Understanding that 592800 > 81276 I wonder how the pixel data is stored with too few bytes to save all that information? (or maybe my math is just wrong?)

    I appreciate any hint about how the image data is mapped by the method QImage::bits() ?



  • On the other hand, I was testing the method QImage::byteCount():
    http://qt-project.org/doc/qt-4.8/qimage.html#byteCount

    @
    fprintf(stderr, "Byte count: %d\n", image.byteCount());
    @

    And I got this:
    Byte count: 790400

    I still can't find a logical relationship between this number and the others :S


  • Moderators

    I'd guess that the first time that
    @
    QByteArray byteMe((char *) image.bits());
    @
    hits an 0x00 in the "string" pointed to by image.bits() it see it as a terminator and isn't filling the QByteArray with the full contents of the file.

    Try using:
    @
    QByteArray byteMe((char *) image.bits(), image.byteCount());
    @



  • Thank you! Your comment lead me to the right way.

    After your suggestion:
    @
    QImage image("test.png", "PNG");
    QByteArray byteMe((char *) image.bits(), image.byteCount());
    fprintf(stderr, "Byte count: %d\n", image.byteCount());
    @

    This is the output I got:
    Byte count: 790400

    Now, if I do: 790400 / 4 = 197600 then everything starts to make sense. The format used by the method bits() is this: every pixel of the image is defined with 4 bytes. To verify this, I tried this code:
    @
    for(int i=0; i < 8; i++) {
    fprintf(stderr, "Color[%d]: %X\n", i, byteMe.at(i));
    }
    @

    And this was the output:

    Color [ 0 ]: FFFFFFFF
    Color [ 1 ]: 0
    Color [ 2 ]: 0
    Color [ 3 ]: FFFFFFFF <- Alpha value
    Color [ 4 ]: 0
    Color [ 5 ]: 0
    Color [ 6 ]: FFFFFFFF
    Color [ 7 ]: FFFFFFFF <- Alpha value

    The first pixel of my image is blue and the second is red, so, the output is telling me that the order of the colors is not RGB but BGR and it seems that the fourth byte is the alpha value.

    Now, with this info I can keep working on my code.

    Thanks again! :)


  • Moderators

    bq. ... the output is telling me that the order of the colors is not RGB but BGR and it seems that the fourth byte is the alpha value.

    You can also call "QImage::format()":/doc/qt-4.8/qimage.html#format to query the QImage's format.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.