我正在尝试从ppm文件中读取并提取RGB值,并将它们存储到带有C++的2d数组中。我确信这个解决方案很简单,但就我的一生而言,我看不到它。我所有的尝试都会产生大量的错误。
编辑:数组中的值必须按列主顺序排列。显然,我需要将数字存储在一个结构中,然后将这些数字存储到数组中
背景知识:
第一个参数是要打开和读取的文件的名称。第二个参数是保存颜色值的像素(结构(的2d阵列。"宽度"是在数组中"移动"所需的数组宽度(即列数(。"高度"是在阵列中"移动"所需的阵列高度(即行数(
到目前为止我的代码:
#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);
如果需要任何额外信息,请通知我。谢谢。
如果您知道如何分配图像,读取像素相对简单。
如果您想以2D数组的形式访问图像(分辨率是一个参数(,则需要分配一个指向数据的指针数组。
示例:
image -> [col0, col1, col2, ...]
(col0, col1, col2 are pointers to columns - applies column major)
col0 -> ####### (points first columns)
col1 -> #######
col2 -> #######
请参阅:如何使用new在C++中声明2d数组?
我使用了这里的示例图像,并添加了一列。
输入图像文件内容:
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;
}
结果(观察窗口(:
- 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