0

I am trying to write a PGM file in a C program, but once it is written, if I try to open it to view the image I am told the image file format can't be determined.

However, if I create a new file in geany, copy the data over, and then save THAT as a new PGM, it works.

Any idea why this could be?

FILE * grey = fopen("greyscale.pgm", "w");

fprintf(grey, "P2 \r\n%d %d \r\n255 \r\n", width, height);

for (i = 0; i < width; i++) {
    for (j = 0; j < height; j++) {
        fprintf(grey, "%d ", ((imageArray[i][j].red + imageArray[i][j].green + imageArray[i][j].blue)/3));
    }
    fprintf(grey, "\r\n");
}

I am converting a colour image to greyscale.

Luke
  • 2,434
  • 9
  • 39
  • 64
  • It could be related with the header of your PGM file. Could you add the piece of code that create the PGM file? – pQB Feb 27 '12 at 16:42
  • 1
    1/3 is not a good coefficient when you convert RGB to gray. Try `0.299R + 0.587G + 0.114B` which is a widespread formula. – Benoit Feb 28 '12 at 09:05
  • Thanks, Benoit. It looks much better with that formula. – Luke Feb 29 '12 at 11:18

2 Answers2

1

Looking at your code, I see that you insert a new line every height elements. According with the PGM file format, after the header, follows

  • A raster of Height rows, in order from top to bottom. Each row consists of Width gray values, in order from left to right.

But your are writing a row of height element. So, your are probably accessing data in a wrong way. In fact, try to debug (with a pencil) an image of 3 columns (width) and 4 rows (height).

Said that, change your loop to write data in row-major order:

// write data to file
int row, col;
for (row = 0; row < height; ++row)
{
    for (col = 0; col < width; ++col)
    {
        fprintf(grey, "%d ", (imageArray[row][col].red + imageArray[row][col].green + imageArray[row][col].blue)/3));
    }
    fprintf(grey, "\n\r");
}
pQB
  • 3,077
  • 3
  • 23
  • 49
  • That's pretty much exactly what I am doing... I just put my code in the OP. – Luke Feb 27 '12 at 17:32
  • I did not notice you were writing an ascii file – pQB Feb 27 '12 at 20:56
  • I was originally writing a binary file... that didn't work either. – Luke Feb 27 '12 at 22:11
  • Thanks. It's working now. I know I have height and width the wrong way around, but that's just me naming it wrong when I initially read the data in. – Luke Feb 29 '12 at 11:19
1

I think you should not use \r\n as a line delimiter, but only \n. Also, check that no line has above 70 characters in length. Since each pixel needs at most 4 characters (3 plus space) insert \n after every 17 pixels. You can separate real lines with comments (for example:

pixel11 pixel12 pixel13
pixel14 pixel15
# switch to next row
pixel21 pixel22 pixel23
pixel24 pixel25
# etc.
Benoit
  • 76,634
  • 23
  • 210
  • 236
  • Thanks. I managed to get it working. I think it was a problem with the amount of whitespace in the header or after it or something. – Luke Feb 29 '12 at 11:19