具有原始图像数据的24bpp到8bpp转换C.

时间:2016-10-18 15:33:20

标签: c image bit-manipulation transformation color-palette

我目前正尝试将原始二进制图像数据(512 x 512 24bpp)转换为512 x 512 8bpp图像,方法是使用3位作为R通道,3位作为G通道,2位作为B通道。然而,当使用我的代码时,我的图片出现灰度?谁能告诉我我做错了什么?

/*24 bit per pixel - 8 bit per pixel transformation*/

unsigned char buf[512][512][3];
unsigned char in[512][512][3];
unsigned char out[512][512][3];
unsigned char pix[512][512];

int main(){

    FILE *fp, *output;
    int i, j;

    /*open file*/
    if((fp = fopen("LennaRGB512.data", "rb")) == NULL){
        printf("error opening file\n");
    }

    /*read file into buffer*/
    for (i = 0; i < 512; i++) {
        for (j = 0; j < 512; j++) {
            buf[i][j][0] = fgetc(fp); /*r*/
            buf[i][j][1] = fgetc(fp); /*g*/
            buf[i][j][2] = fgetc(fp); /*b*/

            in[i][j][0] = buf[i][j][0];
            in[i][j][1] = buf[i][j][1];
            in[i][j][2] = buf[i][j][2];
        }
    }

    fclose(fp);

    output = fopen("lenna_8bpp.data", "wb");
    for(i = 0; i < 512; i++){
        char pix[512][512];
        for(j = 0; j < 512; j++){
            out[i][j][0] = (in[i][j][0] * 8) / 256;
            out[i][j][1] = (in[i][j][1] * 8) / 256;
            out[i][j][2] = (in[i][j][2] * 4) / 256;
            pix[i][j] = (out[i][j][0] << 5) | (out[i][j][1] << 2) | out[i][j][2];
            fputc(pix[i][j], output);
        }
    }



    fclose(output);
    return 0;
}

使用.bmp文件和其他文件有很多问题,但我无法找到任何帮助逐像素地操作原始图像数据。

1 个答案:

答案 0 :(得分:2)

我同意评论者的观点。我认为灰度很可能是你观众的神器,而不是你的转换。但是,您的转化也可以得到改善。尝试以下输出循环:

unsigned char pix;   /* don't need 512*512 of them. */
unsigned char r, g, b;
for(row = 0; row < 512; row++){
    for(col = 0; col < 512; col++){
        r = in[row][col][0] >> 5;   /* keep 3 bits */
        g = in[row][col][1] >> 5;
        b = in[row][col][2] >> 6;   /* keep 2 bits */
        pix = (r << 5) | (g << 2) | b;
        fputc(pix, output);
    }
}

您一次只处理一个像素,因此您只需要一个pix值。

对于每个rgb,颜色组件(请记住始终指定unsigned char),请使用>>(右移)删除除最重要之外的所有位。这比*8/256序列更简单,更清晰。另外,我认为*8/256仅适用,因为算术被提升为int - 如果在char s中完成,*8可能会导致溢出并丢失数据。

编辑问题确实存在于显示屏中。我在my blog上发布了一个调色板和说明,因为这里的空间太长了。是的,我知道只有链接的答案很糟糕:(。我只是在链接腐烂的情况下将其保存到存档中。

您需要将图像打开为索引,然后指定图像的色彩映射。