计算PPM文件的平均RGB值

Calculate average RGB value of a PPM file

我正在尝试计算 PPM 图像的平均 RGB 值。我的尝试可以在下面的代码中看到,但是当我 运行 解决方案时,cmd 中的输出是:0 0 0

我觉得我尝试 int clr = fscanf(f, "%i %i %i", &x, &y, &z); 中的代码行也不正确 - 我试图使用 fscanf 代替 getPixel() ,它使用(显然)过时的 "graphics.h" header。

总结一下:

1.如何计算并打印 PPM 文件的平均 RGB 值?

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

//Image size 
#define WIDTH 2048 
#define HEIGHT 2048

int main()
{
int x, y, z;

//Used for tally
int R = 0;
int G = 0;
int B = 0;

//Loop count value
int total = 0;

//File handle 
FILE *f; 

//File open 
f = fopen("Dog2048x2048.ppm", "r"); 

if (f == NULL)
{
    fprintf(stderr, "Error: file could not be opened");
    exit(1);
}

//Iterate through the image width and height 
for (int i = 0; i < WIDTH; i++)
{
    for (int j = 0; j < HEIGHT; j++)
    {
        //Color clr = bmp.GetPixel(x, y);
        int clr = fscanf(f, "%i %i %i", &x, &y, &z);

        R += clr;
        G += clr;
        B += clr;

        total++;
    }
}

//Calculate average
R /= total;
G /= total;
B /= total;

//Print RGB 
printf("%i %i %i", R, G, B);

return 0; 
}

文件Dog2048x2048.ppm is indeed a P6 format PPM as defined is this PPM Format Specification。因此,它的样本不是以文本表示,而是 纯二进制 ,因此不是 fscanf(…%i…),而是 fread() 适合阅读它们,例如。 G。对于手头的文件 Maxval 255:

    // skip over P6\n2048\n2048\n255\n
    if (fscanf(f, "P6 2048 2048%d%*c", &z) < 1)
        puts("unexpected format of file"), exit(1);

    // Iterate through the image width and height 
    for (int i = 0; i < WIDTH; i++)
    {   // Note that you mixed up WIDTH and HEIGHT - just doesn't matter here
        for (int j = 0; j < HEIGHT; j++)
        {
            //Color clr = bmp.GetPixel(x, y);
            unsigned char clr[3];
            if (fread(clr, 3, 1, f) < 1)
                printf("read error at %d,%d\n", i, j), exit(1);

            R += clr[0];
            G += clr[1];
            B += clr[2];
            total++;
        }
    }

在每个 commented/shared 解决这个问题的用户的帮助下,我想我现在有了一个解决方案,它按照我想要的方式运行,如下所示。

代码以如下格式打印出ppm文件,然后继续查找文件的平均RGB值打印到cmd。

P6 
# ignores comments in header 
width 
height 
max colour value 

我的工作解决方案尝试如下所示:

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

typedef struct {
    unsigned char r, g, b;
} pixel;

int main(int argc, char* argv[]) {

char magic_number[1];
int w, h, m;
int red = 0; 
int green = 0; 
int blue = 0;
int total = 0;      //Loop count initialised at 0 
FILE* f;            //File handle
pixel currentPix;   //Variable declaration for the current pixel 

//Open and read the PPM file 
f = fopen("Dog2048x2048.ppm", "r");
if (f == NULL) {
    fprintf(stderr, "Error: file cannot be opened");
    exit(1);
}

//Get P6, width, height, maxcolour value 
fscanf(f, "%s %d %d %d", &magic_number, &w, &h, &m);
printf("magic_n = %s, width = %d, height = %d, max_colour = %d\n", magic_number, w, h, m);

//iterate through the height and width of the ppm file 
for (int j = 0; j < h; j++) {
    for (int i = 0; i < w; i++) {

        //Read data from the given stream 
        fread(&currentPix, 3, 1, f);

        //Stores current pixel RGB values in red, green, blue variables
        red += currentPix.r;
        green += currentPix.g;
        blue += currentPix.b;

        //Counts the iterations 
        total++; 
    }
}

//calculate averages for red, green, blue
red /= total;
green /= total;
blue /= total;

//print output of average rgb 
printf("%d, %d, %d", red, green, blue);
getchar();
return 0;
}