Results 1 to 13 of 13

Thread: Loading a custom image into a QPixmap

  1. #1
    Join Date
    Feb 2006
    Location
    USA
    Posts
    142
    Thanks
    24
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows Android

    Question Loading a custom image into a QPixmap

    Hello all...

    I have an application that loads all its images into a headerless-format in memory (I store width, height, and bpp... and that's enough for OGL textures), but I'm having some difficulty in writing up a "texture manager" using Qt. Whenever I attempt to load in an image from memory, it pops up an QPixmap::convertFromImage: Cannot convert a null image... here's a snippet of what I'm doing:
    Qt Code:
    1. const Texture * t = myTextures->at(index.row());
    2. QPixmap p(t->GetWidth(), t->GetHeight());
    3. bool OK = p.loadFromData((const uchar *) t->GetData(), t->GetSize());
    4. assert(OK);
    5. return QIcon(p.scaled(60, 60, Qt::KeepAspectRatio, Qt::SmoothTransformation));
    To copy to clipboard, switch view to plain text mode 
    The p.loadFromData() line returns false, which means that it failed to load the image. I've checked with my debugger, and it appears that all my internal texture data is there... is there something else I should be doing?

    A breakdown of what's going on: Texture is a class that holds the image. I have a QList of Texture pointers called myTextures. I grab the texture being pointed at by a QModelIndex, initialize a QPixmap with the width and height from the texture, and load from data (memory) the actual texture into the QPixmap.
    Life without passion is death in disguise

  2. #2
    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: Loading a custom image into a QPixmap

    Maybe the pixmap or the data is not valid?

  3. #3
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: Loading a custom image into a QPixmap

    QPixmap::loadFromData() requires the data to contain a header (at least when not passing the format). I think you could construct a QImage of appropriate size and then set the data by hand through uchar* QImage::bits() or uchar* QImage::scanLine().

    Qt Code:
    1. const int bpl = image.bytesPerLine();
    2. uchar* data = image.bits();
    3.  
    4. for (int y = 0; y < height; y++)
    5. {
    6. quint32* line = reinterpret_cast<quint32*>(data);
    7. for (int x = 0; x < width; x++)
    8. line[x] = qRgb(...);
    9. data += bpl;
    10. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by jpn; 19th July 2006 at 13:41. Reason: Fixed a bug in the code
    J-P Nurmi

  4. #4
    Join Date
    Feb 2006
    Location
    USA
    Posts
    142
    Thanks
    24
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows Android

    Red face Re: Loading a custom image into a QPixmap

    Yeah... I had thought that may be the case, that it wasn't able to auto-detect the image due to the lack of header... I'd noted the format parameter, but there didn't seem to be any documentation at all on what the different options were for it (though there was some for the QImage... but they're different types of parameters and don't look compatible).

    I'd like to avoid (if at all possible) having to manually re-create the image (though if it comes to that, I'll find some way of optimizing it). As you may have been able to guess (with the QModelIndex), I'm trying to have Qt do this on the fly in my model's data() function... and the less it does for each element, the better.

    EDIT: I found the format docs in QPixmap... it just wasn't obvious what it was. I thought it was simply describing the formats it was capable of, but was missing how to use each format - until I saw an example. QPixmap takes in a const char * for its format. The example I saw simply used "PNG" for a .png type file.

    Anyways, that turned into a dead end. I declared the source as a "BMP" as a test, loaded in a texture from a .bmp file as a test (this won't work for my .tga files), and it came up with the same error.

    OpenGL takes that same texture and pastes it in 3D over my models, so I'm pretty sure it's valid data. I guess my next step is to try to start from a QImage and manually define each byte, then convert to a QPixmap and scale to something usable as a thumbnail, then convert to a QIcon . Surely this shouldn't be this hard to deal with...

    EDIT2: OK, I've found that I can let it load something via one of QImage's constructors (QImage ( uchar * data, int width, int height, Format format )), with format being (for the bitmap) QImage::Format_RGB32, and QImage::Format_ARGB32 for the targa.

    Unfortunately, while this does give a good chunk of the texture, most of the texture is corrupted (not sure what I'm viewing). Attached is an example (1st pic), and a thumbnail of what it should be (2nd pic, under "real deal").

    EDIT3: I should also note that when I load in .BMP files, I do byte-swap them so they are RGB instead of BGR.
    Attached Images Attached Images
    Last edited by KShots; 19th July 2006 at 18:54.
    Life without passion is death in disguise

  5. #5
    Join Date
    Feb 2006
    Location
    USA
    Posts
    142
    Thanks
    24
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows Android

    Default Re: Loading a custom image into a QPixmap

    New data... I just tried loading in one of my .tga files, and it has a slightly different problem... looks like a byte-swapping issue. It's also rotated 90 degrees counter-clockwise (how did it manage that?)

    Take a look at the two thumbnails below - the first shows what it comes up as when I load it all the way to the QIcon, the 2nd shows what they are supposed to be (in the same order - the brown first, then the blue).

    Looks like I'm dealing with incompatible formats. Any ideas?
    Attached Images Attached Images
    Life without passion is death in disguise

  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: Loading a custom image into a QPixmap

    Quote Originally Posted by KShots
    It's also rotated 90 degrees counter-clockwise (how did it manage that?)
    They're not rotated by 90 degrees --- they're upside-down.

    Also .tga files are not .bmp files. Maybe you should create a QImageIOPlugin plugin that loads .tga files?

  7. #7
    Join Date
    Feb 2006
    Location
    USA
    Posts
    142
    Thanks
    24
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows Android

    Default Re: Loading a custom image into a QPixmap

    They look like they're rotated to me... and I'm well aware that a .tga is not a .bmp - my texture loader handles them both in different ways. If it's a 24-bit image, it looks like RRGGBB. If it's a 32-bit image, it looks like AARRGGBB. This is not the case with either .bmp nor .tga files, so I have to byte swap them.

    It looks like blue and red are swapped in the above two snapshots (the red one looks blue, and the blue one looks brown)
    Life without passion is death in disguise

  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: Loading a custom image into a QPixmap

    Quote Originally Posted by KShots
    They look like they're rotated to me...
    AFAIR .bmp numbers rows bottom to top, while .tga --- the other way around. That's why those images are flipped.

  9. #9
    Join Date
    Feb 2006
    Location
    USA
    Posts
    142
    Thanks
    24
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows Android

    Wink Re: Loading a custom image into a QPixmap

    Ah, I think I see what's going on, then... though I'm still confused why OGL handles it correctly.

    Yeah, it looks like you're right, it's not rotated 90 degrees counter-clockwise, it's upside down. It's really hard to tell with the size of the icons, but I think you're right. It also seems that the red and the blue bytes are swapped.

    I'll probably have to have a function that goes in and adjusts that inside a QImage in the case of targa files. I'm not entirely sure what writing a QImageIOPlugin gives me if I'm reading the data from memory rather than a file (with the header stripped out).

    I'm still not sure what's going on with the BMP stuff above, either... that corruption really bothers me.

    EDIT: Fixing the targa was... well... easy enough. I had to do an image = image.rgbSwapped(); and an image = image.mirrored() to get it to show up correctly... but it did. I guess that'll have to do for the targas.

    Still mystified with the .bmp corruption

    EDIT2: I think I've figured out what's going on with the bitmaps... by definition, as bitmaps, they're 24-bits per pixel. QImage only seems to take 32-bits per pixel (unless I'm missing something important). Therefore, when QImage reads in a pixel, it's expecting 0xFFRRGGBB... and I'm giving it 0xRRGGBB... so the 1st pixel is 0xRRGGBBRR, then 2nd pixel is 0xGGBBRRGG, and so on. No wonder it looks corrupted. Any ideas on how to force QImage to read in 24-bits rather than 32?
    Last edited by KShots; 20th July 2006 at 05:02.
    Life without passion is death in disguise

  10. #10
    Join Date
    May 2006
    Location
    Germany
    Posts
    108
    Thanks
    2
    Thanked 14 Times in 12 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Loading a custom image into a QPixmap

    You are looking for QImage::Format_ARGB32 to read in 0xAARRGGBB. However, it won't work for targa since targa is 0xBBGGRRAA (AA = alpha-channel) - if I remember correctly (should be, wrote my own targa reader two days ago... but left it at work).

    If you are loading targa images keep in mind that the targa header is 18 bytes so if you read it as a struct the sizeof(tgaheaderstruct) will still be 20 (unless #pragma pack(1) was specified). That reading 20 instead of 18 bytes also explains wrong colours as the pointer onto the datastream starts with the wrong color code.

  11. #11
    Join Date
    Feb 2006
    Location
    USA
    Posts
    142
    Thanks
    24
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows Android

    Default Re: Loading a custom image into a QPixmap

    Quote Originally Posted by Methedrine
    You are looking for QImage::Format_ARGB32 to read in 0xAARRGGBB. However, it won't work for targa since targa is 0xBBGGRRAA (AA = alpha-channel) - if I remember correctly (should be, wrote my own targa reader two days ago... but left it at work).
    Yeah, I got my targas working a while ago, I used the functions mentioned in my last post to correct it - my problem now is with my bitmaps
    Quote Originally Posted by Methedrine
    If you are loading targa images keep in mind that the targa header is 18 bytes so if you read it as a struct the sizeof(tgaheaderstruct) will still be 20 (unless #pragma pack(1) was specified). That reading 20 instead of 18 bytes also explains wrong colours as the pointer onto the datastream starts with the wrong color code.
    Hmm... that explains why I recently had to rebuild my texture loader recently - it just suddenly refused to load the header correctly. I ended up having to read it in variable by variable to get it to read the right sized chunk.

    Anyways... the targa's been behaving well... any ideas on the bitmaps?
    Life without passion is death in disguise

  12. #12
    Join Date
    Feb 2006
    Location
    USA
    Posts
    142
    Thanks
    24
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows Android

    Default Re: Loading a custom image into a QPixmap

    Alright... I think I solved my problem(s). It appears Qt does not support loading in bitmaps from raw data - I had to convert my (already loaded) bitmap into a 32-bit image through opengl, then pass it over to Qt, like so:
    Qt Code:
    1. //I start with a 24-bit bitmap raw-loaded into OpenGL
    2. unsigned char * pixelData = new unsigned char * [4 * texture->GetWidth() * texture->GetHeight()];
    3. glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixelData);
    4. //Now I have a 32-bit texture loaded into memory...
    5. QImage image((uchar *) pixelData, texture->GetWidth(), texture->GetHeight(), QImage::Format_ARGB32);
    6. delete [] pixelData;
    7. image = image.rgbSwapped();
    8. image = image.mirrored();
    9. QPixmap pixmap(QPixmap::fromImage(image));
    10. return QIcon(pixmap.scaled(60, 60, Qt::KeepAspectRatio, Qt::SmoothTransformation));
    To copy to clipboard, switch view to plain text mode 
    On the one hand, I'm a little disappointed that Qt has no way of handling raw 24-bit images... but on the other hand, I found that I didn't need to store my textures in memory if I can retrieve them from OGL easily
    Life without passion is death in disguise

  13. #13
    Join Date
    May 2006
    Location
    Germany
    Posts
    108
    Thanks
    2
    Thanked 14 Times in 12 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Loading a custom image into a QPixmap

    I think I'd have used QFile to read the targa into a QByteArray (simply add the missing byte for a rgb32!) which in turn I'd then use to construct a QImage which would then be assigned to a QPixmap.

    But then again if you are writing something based upon OpenGL you're probably doing it correctly anyway.

Similar Threads

  1. QPixmap and HBITMAP
    By ToddAtWSU in forum Qt Programming
    Replies: 1
    Last Post: 21st June 2006, 16:24
  2. Fast image drawing/scaling in Qt 3.3
    By eriwik in forum Qt Programming
    Replies: 1
    Last Post: 21st June 2006, 10:45
  3. How and when to repaint a widget ?
    By yellowmat in forum Newbie
    Replies: 7
    Last Post: 3rd April 2006, 16:36
  4. Question about updating an image on screen
    By SkripT in forum Qt Programming
    Replies: 1
    Last Post: 24th February 2006, 19:01
  5. image for a custom menu Item.......
    By Naveen in forum Qt Programming
    Replies: 2
    Last Post: 23rd February 2006, 09:28

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.