1

So, I'm doing an image manipulation assignment for my class using QT, I was asked to save the current Image data that I have into PPM format manually, as well as loading it back to the QDialog program.

I managed to save the image correctly (verified the output file with gimp) but loading from the file created a disaster like the following

Here is the original:

circle1

And the bad loading:

circle2

And here is my file loading code:

//... opens the file and pulling out headers & etc...

            unsigned char* data = new unsigned char[width*height*3];

            //Manual loading each byte into char array
            for(long h = 0; h < height; h++){ //for all 600 rows
                getline(readPPM,temp); //readPPM is an ifstream, temp is a string
                std::stringstream oneLine(temp);

                for(long w = 0; w < width*3; w++){ //to every position in that line 800*3
                    int readVal;
                    oneLine >> readVal; //string stream autofill get the int value instead of just one number
                    data[width*h+w] = (unsigned char)readVal; //put it into unsign char
                }
            }


            //Method 1: create the QImage with constructor 
(it blacked out 2/3 of the bottom of the image, and I'm not exactly familiar with QImage data type)
            imageData = QImage(data,width,height,QImage::Format_BGR888);

            //Method 2: manually setting each pixel
            for(int h = 0; h < height; h++){
                for(int w = 0; w < width; w++){
                    int r,g,b;
                    r = (int)data[width*h+w*3];
                    g = (int)data[width*h+w*3+1];
                    b = (int)data[width*h+w*3+2];
                    QColor color = qRgb(r,g,b);
                    imageData.setPixelColor(w,h,color);
                }
            }

//...set image to display...

I would like the display to look like the original image when I load from the file, and I'm not sure what went wrong to cause the corruption, please help

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
Zyc
  • 13
  • 2
  • The PPM format is supported with `QImage` , did you check the Qt doc [Reading and Writing Image Files](https://doc.qt.io/qt-5/qimage.html#reading-and-writing-image-files) , Did you try to load the QImage directly from PPM file .... Not sure if your assignment allows that .. – Mohammad Kanan Sep 16 '20 at 01:01
  • It is not allowed hence I'm writing my own method – Zyc Sep 16 '20 at 01:43
  • 1
    You use position like `width*h+w*3+1` but should be `3*width*h+w*3+1` as there are 3 RGB ints per pixel. – Arty Sep 16 '20 at 04:01
  • 1
    Hence each row has `3 * width` length. – Arty Sep 16 '20 at 04:07
  • If this fixes your issue I may post my comment as answer so that your question will not stay un-answered. – Arty Sep 16 '20 at 14:36
  • @ArtyOneSoul Thanks and yeah it did fix the logic error, however now it displays the same kind of result as if I use a constructor, which looks something like [this](https://imgur.com/79Pd9ID). I guess there is a problem with my file loading methods then – Zyc Sep 16 '20 at 15:36
  • @Zyc Can you provide your PPM file? To see how it looks like, and what it contains. – Arty Sep 16 '20 at 15:44
  • @ArtyOneSoul here is the [file](https://file.io/kdiuDSYohhtO) – Zyc Sep 16 '20 at 16:26
  • I would check back later in the day, got class and exam coming – Zyc Sep 16 '20 at 16:31
  • @Zyc Your link to file is broken - Not-Found Page (Code 404). Maybe you haven't shared (gave permissions) your file to public. – Arty Sep 16 '20 at 16:33
  • try [this](http://www.mediafire.com/file/o5s18nf4g7qv37y/test.ppm/file) instead – Zyc Sep 16 '20 at 18:07
  • @Zyc You need to replace piece of code `data[width*h+w] = (unsigned char)readVal;` with `data[3*width*h+w] = (unsigned char)readVal;`, i.e. multiply by `3`. Before fixing this I got as you 3 half-circles, after that correct 1 full-circle. I told you already to fix this, but you need to do that in all places where you index RGB array, both in reading-from-file place and in setting-QImage-pixels place. – Arty Sep 17 '20 at 10:27
  • @ArtyOneSoul Ah I overlooked that part, thanks for the clarification! it works fine now – Zyc Sep 17 '20 at 14:27

1 Answers1

0

One row of image has size of 3 * width bytes not width, hence this should be fixed everywhere in data[] indexing.

I.e. code

data[width*h+w] = (unsigned char)readVal;

should be replaced with

data[3*width*h+w] = (unsigned char)readVal;

and code

r = (int)data[width*h+w*3];
g = (int)data[width*h+w*3+1];
b = (int)data[width*h+w*3+2];

replaced with

r = (int)data[3*width*h+w*3];
g = (int)data[3*width*h+w*3+1];
b = (int)data[3*width*h+w*3+2];
Arty
  • 14,883
  • 6
  • 36
  • 69