读取/写入 PPM 图像C++,新图像损坏

Reading/Writing PPM image C++, new image is broken

本文关键字:图像 损坏 新图像 C++ 写入 PPM 读取      更新时间:2023-10-16

我在SO上找到了一些用于读取/写入图像的C++代码。我想改进它,以便我可以旋转等图像。但是,一开始我遇到了一些问题。当我写入图像时,似乎我的读取函数只读取了其中的一部分,因为它只写入原始图像的一部分。请参阅我的代码和输入,输出图像。

    #include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main(int argc, char **argv)
{
    ifstream in;
    in.open("OldImage.ppm", std::ios::binary);
    ofstream out;
    std::string magic_number;
    int width, height, maxColVal, i, j;
    in >> magic_number;
    in >> width >> height >> maxColVal;
    in.get();
    char **image;
    image = new char* [width];
    for(i=0; i<width; i++)
    {
        image[i] = new char [height];
        for(j=0; j<height; j++)
        {
            in >> image[i][j];
        }
    }
    out.open("NewImage.ppm", std::ios::binary);
    out << "P3"     << "n"
        << width       << " "
        << height      << "n"
        << maxColVal   << "n"
        ;
    for(i=0; i<width; i++)
    {
        for(j=0; j<height; j++)
        {
            out << image[i][j];
        }
    }
    in.clear();
    in.close();
    out.clear();
    out.close();
    return 0;
}

输入图像:https://www.dropbox.com/s/c0103eyhxzimk0j/OldImage.ppm?dl=0

输出图像:https://www.dropbox.com/s/429i114c05gb8au/NewImage.ppm?dl=0

根据此文档,ppm图像文件有两种形式:原始和普通。您似乎假设正常的原始格式,但您使用的是用于普通 ppm 的幻数 P3。尝试 P6

此外,您的高度和宽度循环应该是相反的,但这不会影响结果。据推测,旋转图像是代码的一部分。

ppm文件的每个像素有 3 个值(R、G 和 B)。您的代码假设只有 1 个值(强度?尝试读取和写入pgm文件("magic_number"等于 P2 )。

或者,读取每个像素的所有 3 个值:

typedef char (*row_ptr)[3];
// I don't know how to express the following without a typedef
char (**image)[3] = new row_ptr[height];
...
for(i=0; i<height; i++)
{
    image[i] = new char[width][3];
    for(j=0; j<width; j++)
    {
        for(colour=0; colour<3; colour++)
        {
            in >> image[i][j][colour];
        }
    }
}

请注意,我切换了 widthheight 的位置,因此代码与文件中像素的顺序匹配。最好使用有意义的名称(如 xy)作为坐标,而不是混淆名称,如 ij .