【问题标题】:How to do a black-and-white picture of a ppm file in C?如何在C中制作ppm文件的黑白图片?
【发布时间】:2019-09-17 09:52:50
【问题描述】:

嘿,我的代码需要一点帮助,我阅读了一个 ppm 文件,将颜色更改为黑白,并希望将其保存到一个新文件中。我可以读取文件的标题并将其写入新文件,但我一直在努力改变颜色。我知道我可以通过以下公式得到灰度值:0.299 * 红色分量 + 0.587 * 绿色分量 + 0.114 * 蓝色分量。有谁知道我怎么把它写成代码?

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

    FILE *oldFile, *newFile;
    int width, height, max_colour;
    oldFile = fopen("oldpic.ppm","rb"); 
    newFile = fopen("newpic.ppm","wb");

    fscanf (oldFile, "P6\n %d %d %d", &width, &height, &max_colour);

    unsigned char *data = malloc(width*height);
    fread(data,1,width*height,oldFile);


   fprintf(newFile, "P6\n%d %d\n%d\n", width, height, max_colour);

  for (int j = 0; j < width; ++j)
  {
    for (int i = 0; i < height; ++i)
    {

       unsigned char color[3];
      color[0] = 0.299 * ? + 0.587 * ? + 0.114 * ?; /* red */
      color[1] = 0.299 * ? + 0.587 * ? + 0.114 * ?;  /* green */
      color[2] = 0.299 * ? + 0.587 * ? + 0.114 * ?;  /* blue */
      (void) fwrite(color, 1, 3, newFile);
    }
  }
  (void) fclose(newFile);
   return 0;
} 

【问题讨论】:

    标签: c image ppm


    【解决方案1】:

    您可能想要缩放二进制算术。

    此外,即使您可以将输入数据读入一个大数组,也可能更容易读取并一次处理一个像素。

    为了做到这一点,你的代码被重新设计了:

    int
    main(int argc, char **argv)
    {
    
        FILE *oldFile;
        FILE *newFile;
        int width;
        int height;
        int max_colour;
    
        oldFile = fopen("oldpic.ppm", "rb");
        newFile = fopen("newpic.ppm", "wb");
    
        fscanf(oldFile, "P6\n %d %d %d", &width, &height, &max_colour);
    
    #if 0
        unsigned char *data = malloc(width * height);
        fread(data, 1, width * height, oldFile);
    #endif
    
        fprintf(newFile, "P6\n%d %d\n%d\n", width, height, max_colour);
    
        for (int j = 0; j < width; ++j) {
            for (int i = 0; i < height; ++i) {
                unsigned char color[3];
                unsigned int grey;
    
                fread(color, 1, 3, oldFile);
    
                grey = 0;
                grey += 299u * color[0];  // red
                grey += 586u * color[1];  // green
                grey += 114u * color[2];  // blue
                grey /= 1000;
    
                color[0] = grey;
                color[1] = grey;
                color[2] = grey;
    
                fwrite(color, 1, 3, newFile);
            }
        }
    
        fclose(oldFile);
        fclose(newFile);
    
        return 0;
    }
    

    【讨论】:

    • 为什么要砍掉#include 语句,使其无法编译?
    • @MarkSetchell 我没有砍它们。它们不在 OP 的原始代码中。大多数情况下,如果缺少它们,我会添加它们,特别是如果我需要在发布前进行测试。但并不总是[取决于]。最近,我不得不为我正在处理的商业/生产代码执行完全相同的缩放算法,所以代码在我脑海中是新鲜的,所以我可以编写它而无需在这里编译/测试它(即桌面检查就足够了) .
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多