首页 文章

读取P6二进制ppm文件

提问于
浏览
2

所以我已经阅读了一些与此相关的问题,但它们都没有解决我的问题 . 我目前正在尝试读取P6 ppm文件(它是一个二进制文件) . 我目前的代码是

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

struct pixel {
    char red;
    char green;
    char blue;
};

int main(int argc, char **argv)
{
    char type[3];
    int numRow, numCol, maxNum;
    FILE *oldFile, *newFile;
    struct pixel currentPixel;
    char buffer[5];

    oldFile = fopen(argv[1], "rb");
    if(oldFile == NULL) {
        fprintf(stderr, "Could not open file %s for reading in binary", argv[1]);
        return 0;
    }
    fscanf(oldFile, "%2s", type);
    type[2] = '\0';
    if(strcmp(type, "P6") != 0) {  //Make sure we have a P6 file
        printf("This file is not of type P6");
        return 0;
    }

    newFile = fopen(argv[2], "wb");
    fprintf(newFile, "%s\n", type);
    /*Read number of columns
    rows and
    The max number that can represent a colour*/
    fscanf(oldFile, "%d", &numCol);
    fscanf(oldFile, "%d", &numRow);
    fscanf(oldFile, "%d", &maxNum);
    /*Print the information to newFile*/
    fprintf(newFile, "%d %d\n", numCol, numRow);
    fprintf(newFile, "%d\n", maxNum);
    fseek(oldFile, 1, SEEK_CUR);

    fread(&currentPixel, sizeof(struct pixel), 1, oldFile);
    printf("%c %c %c", currentPixel.red, currentPixel.green, currentPixel.blue);

    fclose(newFile);
    fclose(oldFile);
    return 0;
}

所以开始工作,我的newFile包含P6,3 3和255行 . 然后尝试用 fread 行读取实际像素 . 这是它失败的地方,我不知道为什么 . 它目前在钻石内打印出两个问号 . 我目前只试图读取组成一个像素的前三个数字(一个红色组件一个绿色和一个蓝色) .

我也有一个相同图片的P3文件,P3文件看起来像:

P3

3 3

255

  0 255 255   0   0   0   0   0 255

255   0 255 100 100 100 255   0   0

255 255   0 255 255 255   0 255   0

所以二进制文件应该像这样设置,但只是二进制格式 . 当我输入

od -c binaryImage.ppm

我明白了

0000000   P   6  \n   3       3  \n   2   5   5  \n  \0 377 377  \0  \0
0000020  \0  \0  \0 377 377  \0 377   X   X   X 377  \0  \0 377 377  \0
0000040 377 377 377  \0 377  \0
0000046

我不知道为什么我的fread功能不起作用 . 不确定是否相关,但我正在Linux Ubuntu上编译

gcc -Wall rotate.c -o rotate

1 回答

  • 2

    您将RGB值打印为字符而不是数字 . 将它们保留为 unsigned char (因为它们的值在[0-255]之间)在结构中,但在打印时使用 %d . 您应该使用 printf ,如下所示:

    printf("%d %d %d", currentPixel.red, currentPixel.green, currentPixel.blue);
    

    另外,我建议不要使用结构来读取RGB值,因为编译器可能会添加填充字节以将结构与机器字对齐(例如32位) . 在32位系统中,您将读取4个字节 . 您可以检查此打印 sizeof(struct pixel) . 要阅读有关结构对齐的更多信息,您可以查看Wikipedia文章Data Structure Alignment .

    而不是结构,使用 char 数组:

    unsigned char currentPixel[3];
    ...
    fread(currentPixel, 3, 1, oldFile);
    printf("%d %d %d", currentPixel[0], currentPixel[1], currentPixel[2]);
    

    此外,如果需要读取整个图像,请创建一个大小为 number of pixels x 3unsigned char 数组 . 3是RGB元组的字节数 . 如果PPM格式在每行末尾包含一些填充,则还需要考虑这一点 .

相关问题