Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QImage from raw array of RGBA32floats ?



  • Hey

    I'm lost, I want to create an image from an array of pixels but they are in RGBA32float format.

    In openGL I just pass it as :

            mFunctions->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, mCurrentImage.first.mWidth, mCurrentImage.first.mHeight, 0,GL_RGBA , GL_FLOAT, mCurrentImage.first.mImage
    

    But in Qt I'm a tad lost.. I tried this >

            QImage m(reinterpret_cast<const uchar *>(mCurrentImage.first.mImage), mCurrentImage.first.mWidth, mCurrentImage.first.mHeight, QImage::Format_RGBA64); // tried ARGB32/etc etc. No luck :- (
    mCurrentImage.first.mImage =  void* mImage.
    

    But I keep on getting jibberish... halp..

    TIA



  • @Dariusz said in QImage from raw array of RGBA32floats ?:

    Format_ARGB32

    Yup, that's 32 total bits per pixel, not 32 bits per channel like the GL_RGBA32F notation in OpenGL. And even then, there are also 32 bits per channel integer pixel formats that still aren't floating point. So even if you do see a 32 bit per channel format, you can't assume it's floating point if it doesn't say it explicitly. (Admittedly those aren't especially common, but formats like OpenEXR support them, and you'll sometimes see them used for things like Object-ID channels in 3D renders)

    Basically, every image handling API covers more or less the same basic functionality, but just different enough to make you want to rip your hair out when you try to use them together.

    It's not even like nothing in Qt can deal with floating point. QOpenGLFrameBufferObject supports OpenGL format names: https://doc.qt.io/qt-5/qopenglframebufferobjectformat.html#internalTextureFormat and can be FP internally. Then if you try to get a QImage from an FBO using toImage https://doc.qt.io/qt-5/qopenglframebufferobject.html#toImage-1 it will know how to do the pixel format conversion to 8bpc. You just can't get the raw FP data in a QImage.

    shrug. This stuff is always more work than you expect, mostly for no good reason.


  • Lifetime Qt Champion

    @Dariusz said in QImage from raw array of RGBA32floats ?:

    GL_RGBA32F

    Hi
    I recall something about GL_RGBA32F openGL having mirrored Y-axis or something like that so
    im not sure a direct copy is possible.
    https://www.khronos.org/opengl/wiki/Common_Mistakes
    y-axis section



  • @mrjj I dont actually have any problem with passing data to openGL as it has RGBA32Float format, but QImage does not which puzzles me as to how should I approach it. Should I manually flip the Alpha from RGBA to ARGB ?? I'm lost.


    Alternatively I recon I need this :

            float *k = static_cast<float *>(b.mImage);
            QVector<float> newData(b.mHeight * b.mWidth);
            for (int a = 0; a < b.mWidth * b.mHeight; a = a + 4) {
                newData[a] = k[a + 3]; // A
                newData[a + 1] = k[a];  // R
                newData[a + 2] = k[a + 1]; // G
                newData[a + 3] = k[a + 2]; // B
            }
    

  • Lifetime Qt Champion

    @Dariusz
    Hi
    It seems you need to flip the y axis as far as i understand the link but not sure
    what the best approach would be.

    Give it a day or two. There must be other user here that had this issue.


  • Lifetime Qt Champion

    @Dariusz
    Did it display image ok then ?



  • @mrjj Nope, still broken :D I have no idea how to bite it now, I will look in to it over next few days :- ) Thanks for help ^^



  • I don't think QImage has any floating point pixel formats. A quick skim of https://doc.qt.io/qt-5/qimage.html#Format-enum seems to confirm it. The only thing to do would be to make a new buffer with the data converted to one of the pixel formats that QImage does support. It's something I would have liked a loooong time ago, but most 2D GUI API's still treat fp32 as exotic, despite being well supported on normal GPU's for ages, and extremely useful for a lot of things.

    You may find a library like OpenImageIO useful if you want to deal with floating point images - it also supports convenient format conversion to something like 8 bpc for display.



  • @wrosecrans Hmmm so the Format_ARGB32 does not mean the QImage remains at floating accuracy? o.O Oh snap!

    In any case I had some success with :

        QVector<uchar> newData(b.mHeight * b.mWidth * 4);
        for (int a = 0; a < b.mWidth * b.mHeight; ++a) {
            newData[a * 4] = (unsigned char) (k[a].alpha * 255);//[a + 3]; // A
            newData[a * 4 + 1] = (unsigned char) (k[a].color.r * 255);//k[a];  // R
            newData[a * 4 + 2] = (unsigned char) (k[a].color.g * 255);//k[a + 1]; // G
            newData[a * 4 + 3] = (unsigned char) (k[a].color.b * 255);//k[a + 2]; // B
        }
    

    From what I can see its yeah no 32 bit support inside QImage :- (((


  • Lifetime Qt Champion

    Hi,

    ARGB32 is 4 bytes hence the 32. So in your case it would rather be ARGB128.



  • @Dariusz said in QImage from raw array of RGBA32floats ?:

    Format_ARGB32

    Yup, that's 32 total bits per pixel, not 32 bits per channel like the GL_RGBA32F notation in OpenGL. And even then, there are also 32 bits per channel integer pixel formats that still aren't floating point. So even if you do see a 32 bit per channel format, you can't assume it's floating point if it doesn't say it explicitly. (Admittedly those aren't especially common, but formats like OpenEXR support them, and you'll sometimes see them used for things like Object-ID channels in 3D renders)

    Basically, every image handling API covers more or less the same basic functionality, but just different enough to make you want to rip your hair out when you try to use them together.

    It's not even like nothing in Qt can deal with floating point. QOpenGLFrameBufferObject supports OpenGL format names: https://doc.qt.io/qt-5/qopenglframebufferobjectformat.html#internalTextureFormat and can be FP internally. Then if you try to get a QImage from an FBO using toImage https://doc.qt.io/qt-5/qopenglframebufferobject.html#toImage-1 it will know how to do the pixel format conversion to 8bpc. You just can't get the raw FP data in a QImage.

    shrug. This stuff is always more work than you expect, mostly for no good reason.



  • @SGaist said in QImage from raw array of RGBA32floats ?:

    Hi,

    ARGB32 is 4 bytes hence the 32. So in your case it would rather be ARGB128.

    Argh this explains my confustion! Yep thats it thanks!


    @wrosecrans said in QImage from raw array of RGBA32floats ?:

    @Dariusz said in QImage from raw array of RGBA32floats ?:

    Format_ARGB32

    Yup, that's 32 total bits per pixel, not 32 bits per channel like the GL_RGBA32F notation in OpenGL. And even then, there are also 32 bits per channel integer pixel formats that still aren't floating point. So even if you do see a 32 bit per channel format, you can't assume it's floating point if it doesn't say it explicitly. (Admittedly those aren't especially common, but formats like OpenEXR support them, and you'll sometimes see them used for things like Object-ID channels in 3D renders)

    Basically, every image handling API covers more or less the same basic functionality, but just different enough to make you want to rip your hair out when you try to use them together.

    It's not even like nothing in Qt can deal with floating point. QOpenGLFrameBufferObject supports OpenGL format names: https://doc.qt.io/qt-5/qopenglframebufferobjectformat.html#internalTextureFormat and can be FP internally. Then if you try to get a QImage from an FBO using toImage https://doc.qt.io/qt-5/qopenglframebufferobject.html#toImage-1 it will know how to do the pixel format conversion to 8bpc. You just can't get the raw FP data in a QImage.

    shrug. This stuff is always more work than you expect, mostly for no good reason.

    Argh too sounds about right! Looks like I will either have to build my own image library for format/data handling or perhaps use freeImage as my base... are there any other libraries u could recommend perhaps?

    I think I'll mark this issue as solved now as its Qt Limitation and me misunderstanding Qt format.

    Thank you all for help.

    Regards
    Dariusz


Log in to reply