1
votes

I'm trying to construct QImages from data saved as 16-bit integers in a binary file. I'm able to load the data in fine, but my program fails when I use the QImage::loadFromData(QBytearray ba) function (returning false) as follows:

QBytearray frame;
QImage pic = QImage(256, 256, QImage::Format_RGB888);

for(int i = 0; i < height; i++) {
    for(int j = 0; j < width; j++) {
        // Access value of pixel at each location
        datum = store[i][j];

        for(int c = 0; c < 3; c++) {
            // Calculate colour at given pixel
            col = (255.0f * ((float)datum - (float)min) / ((float)(max - min)));
            // Assign colour value to the pixel
            frame[c+3*j+3*i*width] = ((unsigned char)col);
        }
    }
}

pic.loadFromData(frame);

I repurposed this from Java code I had previously written which worked perfectly as intended (from the exact same data):

BufferedImage image = = new BufferedImage(256, 256, BufferedImage.TYPE_3BYTE_BGR);

byte[] data = image.getRaster().getDataBuffer();

for (j=0; j<height; j++) {
    for (i=0; i<width; i++) {
        //Find value of the pixels at the location
        datum=data[j][i];
        for (c=0; c<3; c++) {
            //Calculate the colour at the given pixel
            col=(255.0f*((float)datum-(float)min)/((float)(max-min)));
            //Assign the colour value to the pixel
            data[c+3*i+3*j*width] = (byte)col;
        } 
    }
}

Can anybody help me to see where I'm getting this wrong? I've been stumped for days and am all out of ideas.

1
Have you tried making store a hard-coded set of predetermined values? If so, what was the result? If not, could you do that and give us the result? What is frame when you finish building it?MirroredFate
@MirroredFate I can't really do that considering that the image is 256x256, so hard coding the values for that image is a bit time consuming. And what do you mean exactly by what frame is when I've finished building it? Size?Strongo
One thing that has baffled me though is that dumping the Bytearray from a separate image loaded in directly from file (which works fine) gives me a QByteArray 2562 elements long - whereas the one I'm constructing is 196609 elements long. I feel this (huge) size discrepancy is at least part of the problem, but I don't know what the difference in the data formatting might be between the two. I mean, the 196609 byte array worked fine in the Java implementation, so I don't really know why the C++ bytearray for a same-sized image would be so much smaller.Strongo
Also, using the dumped QByteArray in the QImage::loadFromData(QByteArray ba) function works exactly as advertised. It seems as if the size discrepancy is the major issue, but even if I drop the colour setting (c for loop) I still have an array 65536 elements long.Strongo
This is mainly guesses You have a 2d array store, and a QByteArray frame. You are moving unsigned chars (1 byte) from the store to frame, but you need 3 bytes total for your RGB value. This means frame is essentially an array of bytes equal to 256*256*3, or 196609 bytes. I don't see where you are putting in header info to tell which kind of image it is, or any sort of meta characters to give the size...MirroredFate

1 Answers

0
votes

Ok, assuming that you are in fact trying to set RGB values for individual pixels, after reading the QImage details, I see you can do it using the following:

value = qRgb(189, 149, 39); // 0xffbd9527
image.setPixel(1, 1, value);

So, something like:

QImage pic = QImage(256, 256, QImage::Format_RGB888);
QRgb value;
int r,b,g;

for(int i = 0; i < height; i++) {
    for(int j = 0; j < width; j++) {
        // Access value of pixel at each location
        datum = store[i][j];
        //I get really confused what is going on here... you don't seem to be actually using `c` for the calculation?
        for(int c = 0; c < 3; c++) { //let's just pretend you set the ints r,b,g in here somewhere
            // Calculate colour at given pixel
            col = (255.0f * ((float)datum - (float)min) / ((float)(max - min)));
        }
        // Assign colour value to the pixel
        value = qRgb(r, g, b);
        pic.setPixel(i, j, value);
    }
}