【问题标题】:Write a function ImageLoader to read the contents of a PPM file in P3 format using C++使用 C++ 编写函数 ImageLoader 以读取 P3 格式的 PPM 文件的内容
【发布时间】:2021-08-27 02:44:33
【问题描述】:

我在尝试从 PPM 文件中读取数据时完全迷失了方向并感到沮丧。我了解如何打开文件,以及如何访问幻数、宽度和高度以及最大颜色值。我正在努力理解从 PPM 文件中读取像素数据并将其分配给先前定义的私有变量/矩阵图像 [MAX_WIDTH[MAX_HEIGHT][3] 的过程。此函数的目标是将 PPM 文件数据加载到图像数组中,以便稍后在以后的函数中绘制现有文件。我习惯用python写,所以我的c++真的很生疏。

P3
720 540
255
123 125 124 
124 126 125 127 129 128 129 131 130 128 130 129 126 128 127 
132 134 133 132 135 134 135 140 139 137 143 141 136 142 140 135 143 140 
134 144 140 135 147 142 138 145 143 139 143 142 138 142 141 137 141 140 
139 144 143 139 143 142 139 143 142 140 143 141 143 142 140 140 140 137 
enum COLOR { RED, GREEN, BLUE }; // this is in a header file

// everything below is in a cpp file
void Image::ImageLoader(string filename) {
    int max_color;
    ifstream infile; // image variable used to read from a file
    infile.open(filename); // open the file, and associate image with it
    if(infile.fail()){ // true if filename doesn't exist
        throw "File failed to open";
    }
    string magic_num;
    infile >> magic_num >> width >> height >> max_color;


    if (max_color != MAX_COLOR){
        throw "Max color range not 255";
    }
    if (magic_num != "P3"){
        throw "Bad magic number";
    }
    if (width > MAX_WIDTH || width < 0)
        throw "Width out of bounds";
    if (height > MAX_HEIGHT || height < 0)
        throw "Height out of bounds";


// This is where i'm stuck. I think I'm lacking some fundamental knowledge in c++ that's making this part harder. 

// my goal with these loops is to parse through the file infile value by value, and assign these values to my image matrix. 
// I don't really get what's happening with the array image[MAX_WIDTH][MAX_HEIGHT][3]. I know it's a 3d array, but how does the use of enum play into iterating through the array?
// Am I supposed to increment the third index while iterating, or do I iterate all three colors at once? 
    for(int x = 0; x < width; x++){
        for(int y = 0; y < height; y++){
            if (0 > x || x > 255 || 0 > y || y > 255){
                throw "Color value invalid";
            }
            infile >> image[x][y][RED];
            infile >> image[x][y][GREEN];
            infile >> image[x][y][BLUE];


        }
    }

    }

【问题讨论】:

  • 你看过ppm - File Format吗?此外,请提供A Minimal, Complete, and Verifiable Example (MCVE),并将您的 ppm 文件作为文本而不是文本图片复制/粘贴到您的问题中。在数据上方和下方的行中包含 ```(3 个反引号),使其格式为固定文本(或全部缩进 4 个空格)。 (也注意:你的 widthheight 循环颠倒了)
  • 请参阅上面 ppm 链接的“格式”和“普通 PPM”部分。

标签: c++ rgb ppm


【解决方案1】:

来自specification

每个 PPM 映像包含以下内容:
...
高度行的栅格,按从上到下的顺序排列。
每行由 Width 像素组成,从左到右依次排列。
每个像素都是红色、绿色和蓝色样本的三元组,按此顺序。

这自然转化为嵌套循环:

for (int y = 0; y < height; y++) {
  for (int x = 0; x < width; x++) {
    unsigned int red, green, blue;
    infile >> red >> green >> blue;
    if (!infile) {
      std::cerr << "Error reading from file around (" << y << "," << x << ")" << std::endl;
      return;
    }
    // TODO: Check the values of red, green, blue against the interval [0,255] 
    image[y][x][0] = red;
    image[y][x][1] = green;
    image[y][x][2] = blue;
  }
}

最后,您定义了一个enum COLOR { RED, GREEN, BLUE }。 C++ 将为三个枚举值赋值,如下所示:RED=0, GREEN=1, BLUE=2

所以在上面的代码中使用这些枚举值代替 0,1,2 就可以了。

【讨论】:

  • 格式有点模糊,因为没有定义空格分隔值的数量和类型,并且可能存在注释行。至少您可能希望建议验证每个输入,例如if (!(infile &gt;&gt; red &gt;&gt; green &gt;&gt; blue)) { /* handle error */ }
  • 好点。 OP 没有提到 cmets,所以我认为这些超出了范围。
  • 使用unsigned int red, green, blue有什么意义?
  • 负值没有意义。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-07
相关资源
最近更新 更多