从 ppm 文件中读取 RGB 值并使用结构(动态数组)将它们存储到名为 "Image" 的二维数组中

Reading RGB values from a ppm file & storing them into a 2d array called "Image" using a struct (dynamic arrays)

我正在尝试从 ppm 文件中读取并提取 RGB 值并将它们存储到带有 C++ 的二维数组中。我很确定解决方案非常简单,但对于我来说,我看不到它。我所有的尝试都会产生大量错误。

编辑:数组中的值必须按列优先顺序排列。显然我需要将数字存储在一个结构中,并将这些数字存储到数组中。

背景知识:

第一个参数是要打开和读取的文件名。 第二个参数是保存颜色值的二维像素(结构)数组。 "Width" 是整个数组 'travel' 所需的数组宽度(即列数)。 "Height" 是 'travel' 穿过数组

所需的数组高度(即行数)

我目前拥有的代码:

#include "functions.h"
#include <cmath>
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>

using namespace std;

bool imageLoader(string filename, Pixel** image, int width, int height) {
    ifstream fin(filename.c_str());

    if(!fin.is_open()) {
        cout << "Error: failed to open input file - " << filename << endl;
        return false;
    }

    // get type from preamble
    char type[3];
    fin >> type;                                        // should be P3
    if((toupper(type[0]) != 'P') || (type[1] != '3')) { // check that type is correct
        cout << "Error: type is " << type << "instead of P3" << endl;
        return false;
    }

    int w = 0, h = 0;
    fin >> w >> h;
    if(w != width) { // check that width matches what was passed into the function
        cout << "Error: input width (" << width << ")does not match value in file ("
             << w << ")" << endl;
        return false;
    }

    if(h != height) { // check that height matches what was passed into the function
        cout << "Error: input width (" << height
             << ") does not match value in file (" << h << ")" << endl;
        return false;
    }

    // get maximum value from preamble
    int colorMax = 0;
    fin >> colorMax;
    if(colorMax > 255 || colorMax < 0) {
        cout << "Error: invalid color value" << colorMax << endl;
        return false;
    }

    // THIS IS WHAT I NEED HELP WITH
    // I am not sure how this is supposed to work out
    // extract rgb values and place into 2d arr

    /* errors :(
    Pixel colors;
    int colors.r[][] = {0, 0, 0};
    int colors.b[][] = {0, 0, 0};
    int colors.g[][] = {0, 0, 0};
    for (int i = 0; i < height; i++)
    {
    for (int j = 0; j < width; j++) {
        fin >> colors.r >> colors.g >> colors.g;
        cout << colors.r[i][j];

    }
              }
   */

    return true;
}

这是我在头文件中包含的头文件。请不要修改。我们只关注 imageLoader:

#ifndef FUNCTIONS_H
#define FUNCTIONS_H

#include <string>
#include "functions.h"

struct Pixel {
  int r; // red
  int g; // green
  int b; // blue
};


Pixel** createImage(int width, int height);
void deleteImage(Pixel** image, int width);



bool imageLoader(std::string filename, Pixel** image, int width, int height);

如果需要任何额外信息,请通知我。谢谢你。

读取像素相对简单,如果你知道如何分配图像。

如果您想以二维数组的形式访问图像(分辨率是一个参数),您需要分配一个指向数据的指针数组。

示例:

image -> [col0, col1, col2, ...] 
         (col0, col1, col2 are pointers to columns - applies column major)

col0 -> ####### (points first columns)
col1 -> #######
col2 -> #######

参见:How do I declare a 2d array in C++ using new?


我使用了 here 中的示例图片,并添加了一列。

输入图像文件内容:

P3
5 4
255
0  0  0   100 0  0       0  0  0    255   0 255   0  0  255
0  0  0    0 255 175     0  0  0     0    0  0    0  0  255
0  0  0    0  0  0       0 15 175    0    0  0    0  0  255
255 0 255  0  0  0       0  0  0    255  255 255  0  0  255

读取像素的循环:

Pixel colors;

for (int i = 0; i < height; i++)
{
    for (int j = 0; j < width; j++) {
        fin >> colors.r >> colors.g >> colors.b;

        //Column major - row index comes first.
        image[j][i] = colors;   //Copy RGB values into image
    }
}

整个代码示例:

#include <string>
#include <cmath>
#include <fstream>
#include <iostream>
#include <sstream>

struct Pixel {
    int r; // red
    int g; // green
    int b; // blue
};


using namespace std;


bool imageLoader(string filename, Pixel** image, int width, int height) {
    ifstream fin(filename.c_str());

    if(!fin.is_open()) {
        cout << "Error: failed to open input file - " << filename << endl;
        return false;
    }

    // get type from preamble
    char type[3];
    fin >> type;                                        // should be P3
    if((toupper(type[0]) != 'P') || (type[1] != '3')) { // check that type is correct
        cout << "Error: type is " << type << "instead of P3" << endl;
        return false;
    }

    int w = 0, h = 0;
    fin >> w >> h;
    if(w != width) { // check that width matches what was passed into the function
        cout << "Error: input width (" << width << ")does not match value in file ("
             << w << ")" << endl;
        return false;
    }

    if(h != height) { // check that height matches what was passed into the function
        cout << "Error: input width (" << height
             << ") does not match value in file (" << h << ")" << endl;
        return false;
    }

    // get maximum value from preamble
    int colorMax = 0;
    fin >> colorMax;
    if(colorMax > 255 || colorMax < 0) {
        cout << "Error: invalid color value" << colorMax << endl;
        return false;
    }

    // THIS IS WHAT I NEED HELP WITH
    // I am not sure how this is supposed to work out
    // extract rgb values and place into 2d arr

    /* errors :(    
    int colors.r[][] = {0, 0, 0};
    int colors.b[][] = {0, 0, 0};
    int colors.g[][] = {0, 0, 0};
    */
    Pixel colors;

    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++) {
            fin >> colors.r >> colors.g >> colors.b;
            //cout << "(" << i << ", " << j << "): " << colors.r << " " << colors.g << " " << colors.b << endl;

            //Column major - row index comes first.
            image[j][i] = colors;   //Copy RGB values into image
        }
    }

    return true;
}



int main()
{
    //img.ppm
    //https://www.cs.swarthmore.edu/~soni/cs35/f12/Labs/extras/01/ppm_info.html

    //P3
    //5 4
    //255
    //0  0  0   100 0  0       0  0  0    255   0 255   0  0  255
    //0  0  0    0 255 175     0  0  0     0    0  0    0  0  255
    //0  0  0    0  0  0       0 15 175    0    0  0    0  0  255
    //255 0 255  0  0  0       0  0  0    255  255 255  0  0  255

    int width = 5;    //Number of columns
    int height = 4;   //Number of rows

    //Allocate memory
    //////////////////////////////////////////////////////////////////////////
    //Allocate array of 128 pointers (pointer to columns - since column major is required)
    Pixel** image = new Pixel* [width];

    //Allocate columns (each column is 96 pixels).
    for (int j = 0; j < width; j++) {
        image[j] = new Pixel[height];
    }
    //////////////////////////////////////////////////////////////////////////

    bool res = imageLoader("img.ppm", image, width, height);

    if (!res) {
        cout << "res = " << res << endl;
    }

    //Free memory
    //////////////////////////////////////////////////////////////////////////
    //Delete columns.
    for (int j = 0; j < width; j++) {
        delete [] image[j];
    }

    //Delete image.
    delete [] image;
    //////////////////////////////////////////////////////////////////////////

    return 0;
}

结果(观看 window):

-    image[0],4    0x0000000000ba2f20 {r=0 g=0 b=0 }    Pixel *
+    [0]    {r=0 g=0 b=0 }    Pixel
+    [1]    {r=0 g=0 b=0 }    Pixel
+    [2]    {r=0 g=0 b=0 }    Pixel
+    [3]    {r=255 g=0 b=255 }    Pixel
-    image[1],4    0x0000000000ba2fc0 {r=100 g=0 b=0 }    Pixel *
+    [0]    {r=100 g=0 b=0 }    Pixel
+    [1]    {r=0 g=255 b=175 }    Pixel
+    [2]    {r=0 g=0 b=0 }    Pixel
+    [3]    {r=0 g=0 b=0 }    Pixel
-    image[2],4    0x0000000000ba7470 {r=0 g=0 b=0 }    Pixel *
+    [0]    {r=0 g=0 b=0 }    Pixel
+    [1]    {r=0 g=0 b=0 }    Pixel
+    [2]    {r=0 g=15 b=175 }    Pixel
+    [3]    {r=0 g=0 b=0 }    Pixel
-    image[3],4    0x0000000000ba7510 {r=255 g=0 b=255 }    Pixel *
+    [0]    {r=255 g=0 b=255 }    Pixel
+    [1]    {r=0 g=0 b=0 }    Pixel
+    [2]    {r=0 g=0 b=0 }    Pixel
+    [3]    {r=255 g=255 b=255 }    Pixel
-    image[4],4    0x0000000000ba75b0 {r=0 g=0 b=255 }    Pixel *
+    [0]    {r=0 g=0 b=255 }    Pixel
+    [1]    {r=0 g=0 b=255 }    Pixel
+    [2]    {r=0 g=0 b=255 }    Pixel
+    [3]    {r=0 g=0 b=255 }    Pixel