C 读取P6二进制ppm文件

C 读取P6二进制ppm文件,c,struct,binaryfiles,ppm,C,Struct,Binaryfiles,Ppm,所以我已经读了很多和此相关的问题,但并没有一个能解决我的问题。我目前正试图读入一个P6PPM文件(它是一个二进制文件)。我现在的代码是 #include<stdio.h> #include<string.h> #include<stdlib.h> struct pixel { char red; char green; char blue; }; int main(int argc, char **argv) { char

所以我已经读了很多和此相关的问题,但并没有一个能解决我的问题。我目前正试图读入一个P6PPM文件(它是一个二进制文件)。我现在的代码是

#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;
}
所以二进制文件应该像这样设置,但只是二进制格式。当我打字的时候

od-c二进制图像.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-墙旋转。c-o旋转


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

printf("%d %d %d", currentPixel.red, currentPixel.green, currentPixel.blue);
另外,我建议不要使用结构来读取RGB值,因为编译器可能会添加一个填充字节来将结构与机器字对齐(例如32位)。在32位系统中,您将读取4个字节。您可以在打印
sizeof(struct pixel)
时检查此选项。要了解更多关于结构对齐的信息,您可以查看维基百科的文章

使用
char
数组代替结构:

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

另外,如果需要读取整个图像,请创建一个大小为
像素数x 3的
无符号字符数组。3是RGB元组的字节数。如果PPM格式在每条线的末尾都包含一些填充,则需要考虑这一点。

@ WeeVeVAN前三行是常规文本。使用
fscanf
读取这些文件可以很好地工作,但之后我们需要使用
fread
读取,因为文件的其余部分是用二进制编写的。为什么要将RGB值打印为字符(%c)而不是数字(%d)?这就是你在输出中得到奇怪符号的原因。@BrunoBellucci这是个好问题。我改变了我的代码,所以我将红色、绿色和蓝色改为int。它现在打印出
16776960 0-16711681
否。您的像素值应该是char,但您需要将它们打印为整数。@打印出
0-1-1
的BrunoBellucci不应该是
printf行(“%c%c%c”,currentPixel[0],currentPixel[1],currentPixel[2])be
printf(“%d%d%d”,currentPixel[0],currentPixel[1],currentPixel[2])
unsigned char currentPixel[3];
...
fread(currentPixel, 3, 1, oldFile);
printf("%d %d %d", currentPixel[0], currentPixel[1], currentPixel[2]);