【问题标题】:Reading/Writing PPM image C++, new image is broken读/写 PPM 图像 C++,新图像损坏
【发布时间】:2015-06-14 12:25:30
【问题描述】:

我在 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

【问题讨论】:

    标签: c++ image ppm


    【解决方案1】:

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

    另外,你的高度和宽度循环应该是相反的,但这不会影响结果。大概它是旋转图像的代码的一部分。

    【讨论】:

      【解决方案2】:

      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)也是很好的选择。

      【讨论】:

      猜你喜欢
      • 2015-05-07
      • 1970-01-01
      • 1970-01-01
      • 2010-11-22
      • 2021-08-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多