用 C++ 写一个 PPM 文件并得到扭曲的结果
Write a PPM file with C++ and get distorted result
我必须读取、修改和写入 PPM 图像。我试图通过尝试将其写入新文件来检查我是否正确获取了数组中 PPM 图像的所有数据。但是我得到的图像看起来像一台坏掉的电视:a pattern of this:
我不知道我做错了什么,我想至少知道一种方法来检查可能出了什么问题。这些是我的代码:
主要的:
图片实例;
string filename = "Image03.ppm";
string format = "ppm";
bool fileWritten = false;
if (instance.load(filename, format)) {
cout << "The file has been successfully loaded" << endl;
cout << "The dimensions of the image are:" << endl;
cout << instance.getWidth() << "x" << instance.getHeight() << endl;
...
bool imaging::Image::load(const string & filename, const string & format){
string extension = filename.substr(filename.find_last_of(".") + 1);
bool flag = false; // to stop the loop when a different letter is found.
bool result = false; // stores the return value
unsigned int sz = extension.size();
for (unsigned int i = 0; i < sz; ++i) {
if (tolower(extension[i]) != tolower(format[i]) && !flag) {
cout << "The extension of the file does not match the required format." << endl;
flag = true;
}
}
if (!flag) {
string filename1 = filename;
const char *cstr = filename1.c_str();
int pw = 0;
int ph = 0;
float* buff = ReadPPM(cstr, &pw, &ph);
width = pw;
height = ph;
bool h = WritePPM(buff, width, height, "kokoo.ppm");
...
bool WritePPM(const float * data, int w, int h, const char * filename) {
ofstream myfile;
myfile.open(filename, ios::out | ios::binary);
myfile << "P6\n" << w << "\n" << h << "\n255\n";
for (int i = 0; i < w*h; i++) {
myfile.write((char*)&data[i], sizeof(float));
}
myfile.close();
return 0;
}
...
float * ReadPPM(const char * filename, int* w, int* h) {
ifstream myfile;
myfile.open(filename, ios::binary);
if (myfile.is_open())
{
int i = 0;
string letter;
cout << "File successfully open" << endl;
myfile.ignore(2, ' ');
int width;
int height;
myfile >> width;
myfile >> height;
myfile.ignore(4, ' ');
*w = width;
*h = height;
int size = width*height * 3;
int k = myfile.peek();
while (k == 32) { //32 is ascii for whitespace.
myfile.ignore(256,' ');
k = myfile.peek();
}
unsigned char * temp = new unsigned char[size];
myfile.read((char*)temp, size);
float * buff = new float[size];
while (i < size) {
buff[i] = (float)temp[i]/255;
i++;
cout << "before" << buff[i] << endl;
cin.get();
}
delete[] temp;
return buff;
myfile.close();
}
else
{
cout << "Error opening file";
cin.get();
return 0;
}
}
即使我的代码看起来很傻,这也是我对这门语言不熟悉的原因,除非我做错了什么,我喜欢它的样子,无论如何它都是一个作业。
如果您真的必须转换为浮点数组,这就是您做错的地方:
你在 WritePPM
中的循环是完全错误的。你忘记了 3,你忘记了乘以 255 来缩减,你不能将浮点值写入 PPM。它应该是这样的:
for (int i = 0; i < 3*w*h; i++) {
unsigned char c = (unsigned char) (255.0f * data[i] + 0.5f);
myfile.write((char*) &c, sizeof(c));
}
我没有检查所有其他代码,但你肯定还有一些其他错误,例如在 ReadPPM
.
中的 return 语句后关闭文件
我必须读取、修改和写入 PPM 图像。我试图通过尝试将其写入新文件来检查我是否正确获取了数组中 PPM 图像的所有数据。但是我得到的图像看起来像一台坏掉的电视:a pattern of this:
我不知道我做错了什么,我想至少知道一种方法来检查可能出了什么问题。这些是我的代码: 主要的: 图片实例;
string filename = "Image03.ppm";
string format = "ppm";
bool fileWritten = false;
if (instance.load(filename, format)) {
cout << "The file has been successfully loaded" << endl;
cout << "The dimensions of the image are:" << endl;
cout << instance.getWidth() << "x" << instance.getHeight() << endl;
...
bool imaging::Image::load(const string & filename, const string & format){
string extension = filename.substr(filename.find_last_of(".") + 1);
bool flag = false; // to stop the loop when a different letter is found.
bool result = false; // stores the return value
unsigned int sz = extension.size();
for (unsigned int i = 0; i < sz; ++i) {
if (tolower(extension[i]) != tolower(format[i]) && !flag) {
cout << "The extension of the file does not match the required format." << endl;
flag = true;
}
}
if (!flag) {
string filename1 = filename;
const char *cstr = filename1.c_str();
int pw = 0;
int ph = 0;
float* buff = ReadPPM(cstr, &pw, &ph);
width = pw;
height = ph;
bool h = WritePPM(buff, width, height, "kokoo.ppm");
...
bool WritePPM(const float * data, int w, int h, const char * filename) {
ofstream myfile;
myfile.open(filename, ios::out | ios::binary);
myfile << "P6\n" << w << "\n" << h << "\n255\n";
for (int i = 0; i < w*h; i++) {
myfile.write((char*)&data[i], sizeof(float));
}
myfile.close();
return 0;
}
...
float * ReadPPM(const char * filename, int* w, int* h) {
ifstream myfile;
myfile.open(filename, ios::binary);
if (myfile.is_open())
{
int i = 0;
string letter;
cout << "File successfully open" << endl;
myfile.ignore(2, ' ');
int width;
int height;
myfile >> width;
myfile >> height;
myfile.ignore(4, ' ');
*w = width;
*h = height;
int size = width*height * 3;
int k = myfile.peek();
while (k == 32) { //32 is ascii for whitespace.
myfile.ignore(256,' ');
k = myfile.peek();
}
unsigned char * temp = new unsigned char[size];
myfile.read((char*)temp, size);
float * buff = new float[size];
while (i < size) {
buff[i] = (float)temp[i]/255;
i++;
cout << "before" << buff[i] << endl;
cin.get();
}
delete[] temp;
return buff;
myfile.close();
}
else
{
cout << "Error opening file";
cin.get();
return 0;
}
}
即使我的代码看起来很傻,这也是我对这门语言不熟悉的原因,除非我做错了什么,我喜欢它的样子,无论如何它都是一个作业。
如果您真的必须转换为浮点数组,这就是您做错的地方:
你在 WritePPM
中的循环是完全错误的。你忘记了 3,你忘记了乘以 255 来缩减,你不能将浮点值写入 PPM。它应该是这样的:
for (int i = 0; i < 3*w*h; i++) {
unsigned char c = (unsigned char) (255.0f * data[i] + 0.5f);
myfile.write((char*) &c, sizeof(c));
}
我没有检查所有其他代码,但你肯定还有一些其他错误,例如在 ReadPPM
.