试图用c ++写一个ppm图像

时间:2017-01-11 11:33:31

标签: c++

我想读取和写入ppm图像并计算平均颜色数。

我的阅读方法运行正常,每种颜色的平均数也是正确的,但我的写法给了我错误的结果。

保存数据的缓冲区的类型为df.get("region")。每个3D矢量都包含Vec3<float>*rg值。

这是读取方法:

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;
}

1 个答案:

答案 0 :(得分:0)

在阅读文件时,您的值会在01之间进行标准化。写作时,您只需将float值转换为unsigned char,这样您就只能获得01值:我猜您的最终图像是用黑色填充的。

    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;