c ++ - 将float数组转换为unsigned char数组并写入文件

时间:2018-03-15 08:23:46

标签: c arrays file io

我正在写一个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如何转换为charchar是8位且float更大,因此必须有一些数据丢失?

2 个答案:

答案 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)