如何用 C++ 创建正方形、三角形、矩形或圆形并将其保存到便携式位图文件?

How to create in ascii square, triangle, rectangle or circle with C++ and save it to portable bitmap file?

我不知道如何在第 0 行和第 1 行中保存以创建图形。这是我的代码,它生成带零的行。我需要创建一个正方形、三角形或矩形(无关紧要)。只需要知道如何正确地做到这一点并将其作为单色图像保存到 pbm(便携式位图)。

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int main()
{
ofstream file;

int width=5;
int height=5;
int tab [10][10];

file.open("graphics.pbm");
if(file.good() == true)
{
    file << "P1" << endl;
    file << "# comment" << endl;
    file << "10 10" << endl;

    for (int  i=0; i<width; i++)
    {
        for (int j=0; j<height; j++)
        {
            tab[i][j]=0;
        }
    }

    for (int  i=0; i<width; i++)
    {
        for (int j=0; j<height; j++)
        {
            file << tab[i][j] << " ";
        }
    }

file.close();
}

return 0;
}

好吧,您还有一些工作要做...您需要为填充图像的每个几何形状指定一个函数。

这是一个更像 C++ 的示例,其中 class Image 处理计算几何形式的方法,例如 makeFillCircle()Image class 也处理 PBM 输出。请注意现在使用 std::ostream operator<< !

保存它是多么容易
#include <vector>
#include <iostream>
#include <algorithm>

struct Point { 
    Point(int xx, int yy) : x(xx), y(yy) {} 
    int x; 
    int y; 
};

struct Image {
    int width;
    int height;
    std::vector<int> data; // your 2D array of pixels in a linear/flatten storage

    Image(size_t w, size_t h) : width(w), height(h), data(w * h, 0) {} // we fill data with 0s

    void makeFillCircle(const Point& p, int radius) {
        // we do not have to test every points (using bounding box)
        for (int i = std::max(0, p.x - radius); i < std::min(width-1, p.x + radius) ; i ++) {
            for (int j = std::max(0,p.y - radius); j < std::min(height-1, p.y + radius); j ++) {
                // test if pixel (i,j) is inside the circle
                if ( (p.x - i) * (p.x - i) + (p.y - j) * (p.y - j) < radius * radius ) {
                    data[i * width + j] = 1;  //If yes set pixel on 1 !
                }
            }
        }
    }
};

std::ostream& operator<<(std::ostream& os, const Image& img) {
    os << "P1\n" << img.width << " " << img.height << "\n";
    for (auto el : img.data) { os << el << " "; }
    return os;
}

int main() {
    Image img(100,100);
    img.makeFillCircle(Point(60,40), 30); // first big circle
    img.makeFillCircle(Point(20,80), 10); // second big circle
    std::cout << img << std::endl; // the output is the PBM file
}

Live Code

结果是:

瞧...我让您可以根据自己的需要创建自己的函数 makeRectangle()makeTriangle()!这需要一些小数学运算!

编辑奖金

正如评论中所问,这里有一个小的成员函数,可以将图像保存在文件中。将其添加到图像 class 中(如果您愿意,也可以在 class 之外使用免费功能)。因为我们有一个 ostream operator<< 这很简单:

void save(const std::string& filename) {
    std::ofstream ofs;
    ofs.open(filename, std::ios::out);
    ofs << (*this);
    ofs.close();
}

另一种不修改代码的方法是在您的终端上用类似这样的文件捕获程序的输出:

./main >> file.pgm