Reputation: 3363
I'm writing a PPM file writer. The file format description can be found here. I want to write the file in binary format, which is the P6
type.
The P6 binary format of the same image represents each color component of each pixel with one byte (thus three bytes per pixel) in the order red, green, then blue. The file is smaller, but the color information is difficult to read by humans.
My image buffer is originally an array of Vec3f
, which is inside a float[3]
so I can manage to convert the Vec3f
array to float
array.
What I failed to do is convert the float
array to an unsigned char
array so that I can write to a .ppm
file.
Here's my code:
void writePPM(char *fn, Vec3f *buffer, int w, int h) {
FILE *fp = fopen(fn, "wb");
unsigned char *char_buffer = new unsigned char[w*h*3];
for (int i = 0; i < w*h; i+=3) {
char_buffer[i] = (unsigned char)buffer[i].x();
char_buffer[i+1] = (unsigned char)buffer[i].y();
char_buffer[i+2] = (unsigned char)buffer[i].z();
}
fprintf(fp, "P6\n%d %d\n\255\n", w, h);
fwrite(char_buffer, sizeof(unsigned char), w*h*3, fp);
fclose(fp);
}
buffer[i].x(), buffer[i].y(), buffer[i].z() range from [0,255]
The generated image is a completely black one, but width and height matches my image buffer, so I thought the fwrite
part is wrong. How can I fix it?
I'm also confused how float
be converted to char
? char
is 8-bit and float
is bigger so there must be some data loss?
Upvotes: 1
Views: 557
Reputation: 86701
This is a bit of a guess but I would expect a pixel specified as three floats would have each float in the range [0, 1] with 0 being black and 1 being white. Whereas I would expect your char based pixel would expect each element to be in the range [0, 255] with 0 being black and 255 being white.
The cast (char) someFloat
converts a float
to an char
by truncating the fractional part, so all your pixels will end up black - or very nearly black.
Try multiplying the float by 255 before the cast (and make sure the char
is unsigned) i.e. (unsigned char)(float * 255)
Upvotes: 0
Reputation: 758
buffer index check.
for (int i = 0; i < w*h; i+=3) {
char_buffer[i] = (unsigned char)buffer[i/3].x();
char_buffer[i+1] = (unsigned char)buffer[i/3].y();
char_buffer[i+2] = (unsigned char)buffer[i/3].z();
}
Upvotes: 1