如何使用 C 将数独解决方案显示为图像
How can I display a sudoku solution as an image using C
我制作了一个解决数独问题的回溯代码,我想使用 C 库将它显示在屏幕上。我知道我可以使用 GTK,但我认为它对我的水平来说太复杂了。
如何使用数独网格上显示的解决方案创建图像。它也不需要创建网格,如果我使用带有网格的图像作为输入就可以了。所以基本上,我有一个矩阵(数独解决方案),我想将它显示为图像。
我提到我在带有 Mint 的虚拟机上使用 VSC。
来自我的热门评论...
我假设您已经有一个代表您的棋盘位置的二维矩阵。
您可以考虑使用 SDL2
而不是 GTK
,因为它更简单并且可以直接显示到 window.
或者,您可以创建一个图像文件,然后使用系统调用显示程序(例如 ImageMagick 的 display
命令)。输出 .bmp 文件非常容易。
或者,您可以创建一个 .ppm 格式的文件——这样更简单。
您甚至可以输出文本图形,因为数独表示并不太复杂。
ImageMagick 的 convert
可以将一种格式转换为任何其他格式。
Thank you for your help! I still have a question. @CraigEstey, How do I convert my 2D matrix who looks like a sudoku into a matrix that can be displayed as a ppm or bmp. I assume that I need to have a matrix of pixels for that. – Ionut Becheru
是的,您需要一个像素矩阵。
但是,如果您只是自己创建它,则必须创建一堆用于绘制矩形、绘制文本字体、添加颜色等的绘图基元。特别是,绘图 将文本转换为图像很复杂(我们需要字体定义)。
因此,我再次建议使用可以为您完成所有这些工作的图形包。而且,我再次建议 SDL2
.
除了 SDL2
的开发包之外,[至少在 fedora 上],您还需要安装 SDL2_ttf
的开发包。而且,您将需要字体包。
因此,您需要:
SDL2-devel
SDL2_ttf-devel
gnu-free-sans-fonts
gnu-free-fonts-common
以下代码改编自:How to render text in SDL2?
我添加了网格绘图、方框绘图,调整了文本绘图以在方框内绘制数独数字,并将图像保存到 .ppm
文件。
要构建,请执行(例如):
cc -o sudrend sudrend.c `pkg-config --libs --cflags SDL2_ttf` -g
这是代码。它有点乱 [和粗糙] 但它有效:
#include <stdlib.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_ttf.h>
#if 0
#define WINDOW_WIDTH 512
#endif
#if 0
#define WINDOW_WIDTH (64 * 9)
#endif
#if 1
#define WINDOW_WIDTH (32 * 9)
#endif
#define WINDOW_HEIGHT (WINDOW_WIDTH)
#define GRIDMAX (WINDOW_WIDTH / 3)
#define SUDBOXMAX 3
#define SUDXMAX (SUDBOXMAX * 3)
#define SUDYMAX (SUDBOXMAX * 3)
typedef int board_t[SUDYMAX][SUDXMAX];
typedef unsigned char byte;
typedef struct {
byte r;
byte g;
byte b;
#ifdef PIX32
byte a;
#endif
} pixel_t;
board_t brd;
TTF_Font *font;
/*
- x, y: upper left corner.
- texture, rect: outputs.
*/
void
get_text_and_rect(SDL_Renderer *renderer,
int x, int y,
char *text, TTF_Font *font,
SDL_Texture **texture, SDL_Rect *rect)
{
int text_width;
int text_height;
SDL_Surface *surface;
#if 0
SDL_Color textColor = { 255, 255, 255, 0 };
#endif
#if 0
SDL_Color textColor = { 237, 135, 45, 0 };
#endif
#if 1
SDL_Color textColor = { 255, 69, 0, 0 };
#endif
surface = TTF_RenderText_Solid(font,text,textColor);
*texture = SDL_CreateTextureFromSurface(renderer,surface);
text_width = surface->w;
text_height = surface->h;
SDL_FreeSurface(surface);
rect->x = x;
rect->y = y;
rect->w = text_width;
rect->h = text_height;
}
// genboard -- generate sudoku board
void
genboard(board_t brd)
{
for (int y = 0; y < SUDYMAX; ++y) {
for (int x = 0; x < SUDYMAX; ++x)
brd[y][x] = 0;
}
int maxpt = (rand() % (SUDYMAX * SUDXMAX)) + 1;
for (int curpt = 0; curpt < maxpt; ++curpt) {
int y = rand() % SUDYMAX;
int x = rand() % SUDYMAX;
int val = rand() % 10;
brd[y][x] = val;
}
}
// prtboard -- print sudoku board as text
void
prtboard(board_t brd)
{
for (int y = 0; y < SUDYMAX; ++y) {
if ((y % 3) == 0)
printf("\n");
for (int x = 0; x < SUDYMAX; ++x) {
if ((x % 3) == 0)
printf(" ");
int val = brd[y][x];
if (val == 0)
printf(" *");
else
printf(" %d",val);
}
printf("\n");
}
}
void
drawgrid(SDL_Renderer *renderer)
{
int gridmax;
int boxmax;
SDL_Rect rect;
#if 0
SDL_SetRenderDrawColor(renderer, 0, 0xFF, 0, 0);
#endif
#if 0
SDL_SetRenderDrawColor(renderer,143,188,143,0);
#endif
#if 1
SDL_SetRenderDrawColor(renderer,0,0,139,0);
#endif
gridmax = GRIDMAX;
boxmax = SUDYMAX;
for (int ybox = 0; ybox < boxmax; ++ybox) {
int ybase = ybox * gridmax;
rect.y = ybase;
rect.h = gridmax;
for (int xbox = 0; xbox < boxmax; ++xbox) {
int xbase = xbox * gridmax;
rect.x = xbase;
rect.w = gridmax;
SDL_RenderDrawRect(renderer,&rect);
}
}
}
void
drawbox(SDL_Renderer *renderer)
{
int gridmax;
int boxmax;
SDL_Rect rect;
#if 0
SDL_SetRenderDrawColor(renderer, 255, 216, 0, 0);
#else
SDL_SetRenderDrawColor(renderer,255,250,205,0);
#endif
gridmax = GRIDMAX / 3;
boxmax = SUDYMAX * 3;
for (int ybox = 0; ybox < boxmax; ++ybox) {
int ybase = ybox * gridmax;
rect.y = ybase;
rect.h = gridmax;
for (int xbox = 0; xbox < boxmax; ++xbox) {
int xbase = xbox * gridmax;
rect.x = xbase;
rect.w = gridmax;
SDL_RenderDrawRect(renderer,&rect);
}
}
}
void
drawtext(SDL_Renderer *renderer)
{
int gridmax;
int boxmax_y;
int boxmax_x;
SDL_Rect grect;
SDL_Rect trect;
SDL_Texture *texture;
char buf[2];
#if 0
SDL_SetRenderDrawColor(renderer, 255, 216, 0, 0);
#endif
#if 0
SDL_SetRenderDrawColor(renderer,255,250,205,0);
#endif
#if 1
SDL_SetRenderDrawColor(renderer,0,0,0,0);
#endif
gridmax = GRIDMAX / 3;
#if 0
boxmax_y = SUDYMAX * 3;
boxmax_x = SUDXMAX * 3;
#else
boxmax_y = SUDYMAX;
boxmax_x = SUDXMAX;
#endif
for (int ybox = 0; ybox < boxmax_y; ++ybox) {
int ybase = ybox * gridmax;
grect.y = ybase + gridmax / 3;
grect.h = gridmax / 3;
for (int xbox = 0; xbox < boxmax_x; ++xbox) {
int chr = brd[ybox][xbox];
if (chr != 0)
buf[0] = chr + '0';
else
buf[0] = ' ';
buf[1] = 0;
get_text_and_rect(renderer, 0, 0, buf, font, &texture, &trect);
int xbase = xbox * gridmax;
grect.x = xbase + gridmax / 3;
grect.w = gridmax / 3;
SDL_RenderCopy(renderer, texture, &trect, &grect);
SDL_DestroyTexture(texture);
}
}
}
// imgsave -- save image to P6 .ppm file
void
imgsave(SDL_Renderer *renderer,int imgno)
{
int pitch;
FILE *xf;
char file[1000];
pixel_t *pixmap;
pitch = sizeof(pixel_t) * WINDOW_WIDTH;
pixmap = malloc(pitch * WINDOW_HEIGHT);
// get pixel map from renderer image
#ifdef PIX32
SDL_RenderReadPixels(renderer,NULL,SDL_PIXELFORMAT_RGBA32,pixmap,pitch);
#else
SDL_RenderReadPixels(renderer,NULL,SDL_PIXELFORMAT_RGB24,pixmap,pitch);
#endif
sprintf(file,"img%3.3d.ppm",imgno);
xf = fopen(file,"w");
fprintf(xf,"P6\n");
fprintf(xf,"%d %d",WINDOW_WIDTH,WINDOW_HEIGHT);
fprintf(xf," %d\n",255);
#ifdef PIX32
pixel_t *pixcur = &pixmap[0];
pixel_t *pixlim = &pixmap[WINDOW_WIDTH * WINDOW_HEIGHT];
for (; pixcur < pixlim; ++pixcur) {
fputc(pixcur->r,xf);
fputc(pixcur->g,xf);
fputc(pixcur->b,xf);
}
#else
fwrite(pixmap,sizeof(pixel_t),WINDOW_WIDTH * WINDOW_HEIGHT,xf);
#endif
fclose(xf);
free(pixmap);
}
void
fontinit(const char *font_tail)
{
const char *dir;
char font_path[1000];
TTF_Init();
for (int idx = 0; idx <= 1; ++idx) {
switch (idx) {
case 0:
dir = NULL;
break;
default: // NOTE: my system needed this
dir = "/usr/share/fonts/gnu-free";
break;
}
if (dir == NULL)
strcpy(font_path,font_tail);
else
sprintf(font_path,"%s/%s",dir,font_tail);
font = TTF_OpenFont(font_path, 24);
if (font != NULL)
break;
}
if (font == NULL) {
fprintf(stderr, "error: font not found\n");
exit(EXIT_FAILURE);
}
}
int
main(int argc, char **argv)
{
SDL_Event event;
SDL_Renderer *renderer;
SDL_Window *window;
char *font_path;
int quit;
switch (argc) {
case 1:
font_path = "FreeSans.ttf";
break;
case 2:
font_path = argv[1];
break;
default:
fprintf(stderr, "error: too many arguments\n");
exit(EXIT_FAILURE);
break;
}
genboard(brd);
prtboard(brd);
/* Inint TTF. */
SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO);
SDL_CreateWindowAndRenderer(WINDOW_WIDTH, WINDOW_WIDTH, 0, &window,
&renderer);
fontinit(font_path);
#if 0
SDL_Rect rect1, rect2;
SDL_Texture *texture1, *texture2;
get_text_and_rect(renderer, 0, 0, "hello", font, &texture1, &rect1);
get_text_and_rect(renderer, 0, rect1.y + rect1.h, "world", font,
&texture2, &rect2);
#endif
quit = 0;
while (1) {
while (SDL_PollEvent(&event) == 1) {
if (event.type == SDL_QUIT)
quit = 1;
}
if (quit)
break;
// set background
#if 0
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
#else
SDL_SetRenderDrawColor(renderer,135,206,250,0);
#endif
SDL_RenderClear(renderer);
drawbox(renderer);
drawgrid(renderer);
drawtext(renderer);
/* Use TTF textures. */
#if 0
SDL_RenderCopy(renderer, texture1, NULL, &rect1);
SDL_RenderCopy(renderer, texture2, NULL, &rect2);
#endif
imgsave(renderer,0);
SDL_RenderPresent(renderer);
}
/* Deinit TTF. */
#if 0
SDL_DestroyTexture(texture1);
SDL_DestroyTexture(texture2);
#endif
TTF_Quit();
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return EXIT_SUCCESS;
}
这是程序的文本输出(请注意,程序只是生成一个随机测试矩阵,它可能是也可能不是有效的数独):
2 4 7 9 * 7 * 6 *
* 6 * * * * 9 * 1
7 1 * * * 3 * * 6
* * 6 * 7 * 5 7 *
* * 9 * 5 * * * *
* * 7 3 * * * 8 *
7 * 1 * * * 2 * 8
5 * 6 * 2 6 * * *
* 2 * * * * * * 3
这是生成的图像文件。程序将其保存到 img000.ppm
。然后我做了: convert img000.ppm img000.png
[使用 ImageMagick 的 convert
]
我制作了一个解决数独问题的回溯代码,我想使用 C 库将它显示在屏幕上。我知道我可以使用 GTK,但我认为它对我的水平来说太复杂了。
如何使用数独网格上显示的解决方案创建图像。它也不需要创建网格,如果我使用带有网格的图像作为输入就可以了。所以基本上,我有一个矩阵(数独解决方案),我想将它显示为图像。
我提到我在带有 Mint 的虚拟机上使用 VSC。
来自我的热门评论...
我假设您已经有一个代表您的棋盘位置的二维矩阵。
您可以考虑使用 SDL2
而不是 GTK
,因为它更简单并且可以直接显示到 window.
或者,您可以创建一个图像文件,然后使用系统调用显示程序(例如 ImageMagick 的 display
命令)。输出 .bmp 文件非常容易。
或者,您可以创建一个 .ppm 格式的文件——这样更简单。
您甚至可以输出文本图形,因为数独表示并不太复杂。
ImageMagick 的 convert
可以将一种格式转换为任何其他格式。
Thank you for your help! I still have a question. @CraigEstey, How do I convert my 2D matrix who looks like a sudoku into a matrix that can be displayed as a ppm or bmp. I assume that I need to have a matrix of pixels for that. – Ionut Becheru
是的,您需要一个像素矩阵。
但是,如果您只是自己创建它,则必须创建一堆用于绘制矩形、绘制文本字体、添加颜色等的绘图基元。特别是,绘图 将文本转换为图像很复杂(我们需要字体定义)。
因此,我再次建议使用可以为您完成所有这些工作的图形包。而且,我再次建议 SDL2
.
除了 SDL2
的开发包之外,[至少在 fedora 上],您还需要安装 SDL2_ttf
的开发包。而且,您将需要字体包。
因此,您需要:
SDL2-devel
SDL2_ttf-devel
gnu-free-sans-fonts
gnu-free-fonts-common
以下代码改编自:How to render text in SDL2?
我添加了网格绘图、方框绘图,调整了文本绘图以在方框内绘制数独数字,并将图像保存到 .ppm
文件。
要构建,请执行(例如):
cc -o sudrend sudrend.c `pkg-config --libs --cflags SDL2_ttf` -g
这是代码。它有点乱 [和粗糙] 但它有效:
#include <stdlib.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_ttf.h>
#if 0
#define WINDOW_WIDTH 512
#endif
#if 0
#define WINDOW_WIDTH (64 * 9)
#endif
#if 1
#define WINDOW_WIDTH (32 * 9)
#endif
#define WINDOW_HEIGHT (WINDOW_WIDTH)
#define GRIDMAX (WINDOW_WIDTH / 3)
#define SUDBOXMAX 3
#define SUDXMAX (SUDBOXMAX * 3)
#define SUDYMAX (SUDBOXMAX * 3)
typedef int board_t[SUDYMAX][SUDXMAX];
typedef unsigned char byte;
typedef struct {
byte r;
byte g;
byte b;
#ifdef PIX32
byte a;
#endif
} pixel_t;
board_t brd;
TTF_Font *font;
/*
- x, y: upper left corner.
- texture, rect: outputs.
*/
void
get_text_and_rect(SDL_Renderer *renderer,
int x, int y,
char *text, TTF_Font *font,
SDL_Texture **texture, SDL_Rect *rect)
{
int text_width;
int text_height;
SDL_Surface *surface;
#if 0
SDL_Color textColor = { 255, 255, 255, 0 };
#endif
#if 0
SDL_Color textColor = { 237, 135, 45, 0 };
#endif
#if 1
SDL_Color textColor = { 255, 69, 0, 0 };
#endif
surface = TTF_RenderText_Solid(font,text,textColor);
*texture = SDL_CreateTextureFromSurface(renderer,surface);
text_width = surface->w;
text_height = surface->h;
SDL_FreeSurface(surface);
rect->x = x;
rect->y = y;
rect->w = text_width;
rect->h = text_height;
}
// genboard -- generate sudoku board
void
genboard(board_t brd)
{
for (int y = 0; y < SUDYMAX; ++y) {
for (int x = 0; x < SUDYMAX; ++x)
brd[y][x] = 0;
}
int maxpt = (rand() % (SUDYMAX * SUDXMAX)) + 1;
for (int curpt = 0; curpt < maxpt; ++curpt) {
int y = rand() % SUDYMAX;
int x = rand() % SUDYMAX;
int val = rand() % 10;
brd[y][x] = val;
}
}
// prtboard -- print sudoku board as text
void
prtboard(board_t brd)
{
for (int y = 0; y < SUDYMAX; ++y) {
if ((y % 3) == 0)
printf("\n");
for (int x = 0; x < SUDYMAX; ++x) {
if ((x % 3) == 0)
printf(" ");
int val = brd[y][x];
if (val == 0)
printf(" *");
else
printf(" %d",val);
}
printf("\n");
}
}
void
drawgrid(SDL_Renderer *renderer)
{
int gridmax;
int boxmax;
SDL_Rect rect;
#if 0
SDL_SetRenderDrawColor(renderer, 0, 0xFF, 0, 0);
#endif
#if 0
SDL_SetRenderDrawColor(renderer,143,188,143,0);
#endif
#if 1
SDL_SetRenderDrawColor(renderer,0,0,139,0);
#endif
gridmax = GRIDMAX;
boxmax = SUDYMAX;
for (int ybox = 0; ybox < boxmax; ++ybox) {
int ybase = ybox * gridmax;
rect.y = ybase;
rect.h = gridmax;
for (int xbox = 0; xbox < boxmax; ++xbox) {
int xbase = xbox * gridmax;
rect.x = xbase;
rect.w = gridmax;
SDL_RenderDrawRect(renderer,&rect);
}
}
}
void
drawbox(SDL_Renderer *renderer)
{
int gridmax;
int boxmax;
SDL_Rect rect;
#if 0
SDL_SetRenderDrawColor(renderer, 255, 216, 0, 0);
#else
SDL_SetRenderDrawColor(renderer,255,250,205,0);
#endif
gridmax = GRIDMAX / 3;
boxmax = SUDYMAX * 3;
for (int ybox = 0; ybox < boxmax; ++ybox) {
int ybase = ybox * gridmax;
rect.y = ybase;
rect.h = gridmax;
for (int xbox = 0; xbox < boxmax; ++xbox) {
int xbase = xbox * gridmax;
rect.x = xbase;
rect.w = gridmax;
SDL_RenderDrawRect(renderer,&rect);
}
}
}
void
drawtext(SDL_Renderer *renderer)
{
int gridmax;
int boxmax_y;
int boxmax_x;
SDL_Rect grect;
SDL_Rect trect;
SDL_Texture *texture;
char buf[2];
#if 0
SDL_SetRenderDrawColor(renderer, 255, 216, 0, 0);
#endif
#if 0
SDL_SetRenderDrawColor(renderer,255,250,205,0);
#endif
#if 1
SDL_SetRenderDrawColor(renderer,0,0,0,0);
#endif
gridmax = GRIDMAX / 3;
#if 0
boxmax_y = SUDYMAX * 3;
boxmax_x = SUDXMAX * 3;
#else
boxmax_y = SUDYMAX;
boxmax_x = SUDXMAX;
#endif
for (int ybox = 0; ybox < boxmax_y; ++ybox) {
int ybase = ybox * gridmax;
grect.y = ybase + gridmax / 3;
grect.h = gridmax / 3;
for (int xbox = 0; xbox < boxmax_x; ++xbox) {
int chr = brd[ybox][xbox];
if (chr != 0)
buf[0] = chr + '0';
else
buf[0] = ' ';
buf[1] = 0;
get_text_and_rect(renderer, 0, 0, buf, font, &texture, &trect);
int xbase = xbox * gridmax;
grect.x = xbase + gridmax / 3;
grect.w = gridmax / 3;
SDL_RenderCopy(renderer, texture, &trect, &grect);
SDL_DestroyTexture(texture);
}
}
}
// imgsave -- save image to P6 .ppm file
void
imgsave(SDL_Renderer *renderer,int imgno)
{
int pitch;
FILE *xf;
char file[1000];
pixel_t *pixmap;
pitch = sizeof(pixel_t) * WINDOW_WIDTH;
pixmap = malloc(pitch * WINDOW_HEIGHT);
// get pixel map from renderer image
#ifdef PIX32
SDL_RenderReadPixels(renderer,NULL,SDL_PIXELFORMAT_RGBA32,pixmap,pitch);
#else
SDL_RenderReadPixels(renderer,NULL,SDL_PIXELFORMAT_RGB24,pixmap,pitch);
#endif
sprintf(file,"img%3.3d.ppm",imgno);
xf = fopen(file,"w");
fprintf(xf,"P6\n");
fprintf(xf,"%d %d",WINDOW_WIDTH,WINDOW_HEIGHT);
fprintf(xf," %d\n",255);
#ifdef PIX32
pixel_t *pixcur = &pixmap[0];
pixel_t *pixlim = &pixmap[WINDOW_WIDTH * WINDOW_HEIGHT];
for (; pixcur < pixlim; ++pixcur) {
fputc(pixcur->r,xf);
fputc(pixcur->g,xf);
fputc(pixcur->b,xf);
}
#else
fwrite(pixmap,sizeof(pixel_t),WINDOW_WIDTH * WINDOW_HEIGHT,xf);
#endif
fclose(xf);
free(pixmap);
}
void
fontinit(const char *font_tail)
{
const char *dir;
char font_path[1000];
TTF_Init();
for (int idx = 0; idx <= 1; ++idx) {
switch (idx) {
case 0:
dir = NULL;
break;
default: // NOTE: my system needed this
dir = "/usr/share/fonts/gnu-free";
break;
}
if (dir == NULL)
strcpy(font_path,font_tail);
else
sprintf(font_path,"%s/%s",dir,font_tail);
font = TTF_OpenFont(font_path, 24);
if (font != NULL)
break;
}
if (font == NULL) {
fprintf(stderr, "error: font not found\n");
exit(EXIT_FAILURE);
}
}
int
main(int argc, char **argv)
{
SDL_Event event;
SDL_Renderer *renderer;
SDL_Window *window;
char *font_path;
int quit;
switch (argc) {
case 1:
font_path = "FreeSans.ttf";
break;
case 2:
font_path = argv[1];
break;
default:
fprintf(stderr, "error: too many arguments\n");
exit(EXIT_FAILURE);
break;
}
genboard(brd);
prtboard(brd);
/* Inint TTF. */
SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO);
SDL_CreateWindowAndRenderer(WINDOW_WIDTH, WINDOW_WIDTH, 0, &window,
&renderer);
fontinit(font_path);
#if 0
SDL_Rect rect1, rect2;
SDL_Texture *texture1, *texture2;
get_text_and_rect(renderer, 0, 0, "hello", font, &texture1, &rect1);
get_text_and_rect(renderer, 0, rect1.y + rect1.h, "world", font,
&texture2, &rect2);
#endif
quit = 0;
while (1) {
while (SDL_PollEvent(&event) == 1) {
if (event.type == SDL_QUIT)
quit = 1;
}
if (quit)
break;
// set background
#if 0
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
#else
SDL_SetRenderDrawColor(renderer,135,206,250,0);
#endif
SDL_RenderClear(renderer);
drawbox(renderer);
drawgrid(renderer);
drawtext(renderer);
/* Use TTF textures. */
#if 0
SDL_RenderCopy(renderer, texture1, NULL, &rect1);
SDL_RenderCopy(renderer, texture2, NULL, &rect2);
#endif
imgsave(renderer,0);
SDL_RenderPresent(renderer);
}
/* Deinit TTF. */
#if 0
SDL_DestroyTexture(texture1);
SDL_DestroyTexture(texture2);
#endif
TTF_Quit();
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return EXIT_SUCCESS;
}
这是程序的文本输出(请注意,程序只是生成一个随机测试矩阵,它可能是也可能不是有效的数独):
2 4 7 9 * 7 * 6 *
* 6 * * * * 9 * 1
7 1 * * * 3 * * 6
* * 6 * 7 * 5 7 *
* * 9 * 5 * * * *
* * 7 3 * * * 8 *
7 * 1 * * * 2 * 8
5 * 6 * 2 6 * * *
* 2 * * * * * * 3
这是生成的图像文件。程序将其保存到 img000.ppm
。然后我做了: convert img000.ppm img000.png
[使用 ImageMagick 的 convert
]