我想读取和写入ppm图像并计算平均颜色数。
我的阅读方法运行正常,每种颜色的平均数也是正确的,但我的写法给了我错误的结果。
保存数据的缓冲区的类型为df.get("region")
。每个3D矢量都包含Vec3<float>*
,r
和g
值。
这是读取方法:
b
这是写方法:
Image * ReadPPM(const char * filename) {
Image* image;
ifstream file;
unsigned int width, height;
string version;
float maxvalue;
file.open(filename, ios::in | ios::binary);
if (!file) {
cerr << "file could not be open" << endl;
exit(EXIT_FAILURE);
}
// read the header
file >> version;
// check the header
// PPM "header" is valid
if (version.compare("P6") != 0)
{
cout << "Invalid image format (must be 'P6')";
exit(EXIT_FAILURE);
}
file >> width >> height >> maxvalue;
size_t size = height * width*3;
unsigned char * buffer = new unsigned char[size];
Vec3<float>* finalBuffer = new Vec3<float>[size / 3];
file.get();
file.read( (char *)buffer, size);
int j = 0;
for (int i = 0; i < size; i+=3) {
Vec3<float> vec(
(int)buffer[i]/maxvalue,
(int)buffer[i+1] / maxvalue,
(int)buffer[i+2] / maxvalue
);
finalBuffer[j] = vec;
j++;
}
file.clear();
file.close();
image = new Image(width, height, finalBuffer);
return image;
}
答案 0 :(得分:0)
在阅读文件时,您的值会在0
和1
之间进行标准化。写作时,您只需将float
值转换为unsigned char
,这样您就只能获得0
和1
值:我猜您的最终图像是用黑色填充的。
void*img = getRawDataPtr(); //returns void* buffer
unsigned char * temp = new unsigned char[size*3];
Vec3<float>* buff = (Vec3<float>*)img;
为什么要创建动态数组,您必须管理?您使用C ++进行编码,因此请使用std::vector
等容器。
for (int i = 0; i<size; i++) {
Vec3<float> vector;
vector[0] =buff[i].x;
vector[1] = buff[i].y;
vector[2] = buff[i].z; // /255.f;
buff[i] = vector;
}
这个循环的目的是什么?您正在创建一个Vec3<float>
,而不是从当前像素中的Vec3<float>
转换而不转换您的临时值:这只是什么都没做。
return true;
delete[] buff;
delete[] temp;
正如我在评论中所说,return
之后的代码未执行,因此您永远不会释放为temp
分配的内存。使用std::vector
,您无需这样做。 buff
是您的原始图片:您不应在此删除它。
清理后,您的代码可能会变为:
std::vector<unsigned char> temp(size*3);
Vec3<float>* buff = static_cast<Vec3<float>*>(getRawDataPtr());
for (int i = 0; i < size; i++) {
temp[i * 3] = static_cast<unsigned char>(buff[i].x * 255);
temp[i * 3 + 1] = static_cast<unsigned char>(buff[i].y * 255);
temp[i * 3 + 2] = static_cast<unsigned char>(buff[i].z * 255);
}
file.write(reinterpret_cast<char*>(&temp[0]), size * 3);
if (file.fail()) {
cerr << "Could not write data" << endl;
return false;
}
file.close();
return true;