我正在写一个PPM文件编写器。可以找到文件格式说明here。我想以二进制格式编写文件,即P6
类型。
同一图像的P6二进制格式表示每个像素的每个颜色分量,其中一个字节(因此每个像素三个字节)按红色,绿色,然后是蓝色的顺序。文件较小,但人类难以阅读颜色信息。
我的图片缓冲区最初是Vec3f
的数组,位于float[3]
内,因此我可以设法将Vec3f
数组转换为float
数组。
我未能做的是将float
数组转换为unsigned char
数组,以便我可以写入.ppm
文件。
这是我的代码:
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()范围从[0,255]
生成的图像是完全黑色的,但宽度和高度与我的图像缓冲区匹配,所以我认为fwrite
部分是错误的。我该如何解决?
我也很困惑float
如何转换为char
? char
是8位且float
更大,因此必须有一些数据丢失?
答案 0 :(得分:1)
缓冲区索引检查。
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();
}
答案 1 :(得分:0)
这是一个猜测,但我希望指定为三个浮点数的像素将使每个浮点数在[0,1]范围内,其中0为黑色,1为白色。而我希望你的基于char的像素会期望每个元素在[0,255]范围内,0为黑色,255为白色。
广播(char) someFloat
通过截断小数部分将float
转换为char
,因此所有像素都将以黑色结束 - 或者非常接近黑色。
尝试在施法前将浮点数乘以255(并确保char
无符号),即(unsigned char)(float * 255)