将 ppm 转换为 ASCII 艺术的程序无法正常运行
The program for converting ppm to ASCII art does not work properly
我正在编写一个程序,用于将文件从 PPM 格式转换为 ASCII 艺术。通过计算红绿蓝值的平均值((red + green +blue)/3)
,将输入图像的每个像素转换为灰度。
基础版的升级是我在n*n
大小的window中计算RGB的平均值,并将其转换为字符,从而减小图像的大小。因此,如果给定数字 n
为 3
,则 window 的大小为 3*3
,这意味着您将所有九个红色、绿色和蓝色值相加并除以 3次 n*n
(在本例中为 3*3
)。当程序计算第一个 window 的灰度时,它会移动到另一个,依此类推,直到结束。当宽度结束时,它跳下 n 个像素并读取下一行等。
计算灰度后,将其转换为字符,并将该字符写入输出文件以形成 ASCII 艺术图像。
我的程序编译通过了,但是当我测试它时,我得到了错误的图像。一个非常简单的图像转换为空白文件,另一个看起来应该像棋盘,但它打印了一个非常大的列图像。这些图像都通过扫描像素块 1*1 转换为 ASCII 艺术。第三张图片很大,应该按3*3块转换,但是我得到的输出文件太大打不开。在一个简单的文本编辑器中。
谁能告诉我哪里出错了?
代码如下:
#include <stdio.h>
#include <stdlib.h>
// convert the calculated greyscale to a character based on brightness
char method_of_conversion(int greyscale){
if(greyscale >= 230){
return ' ';
}else if(greyscale >= 200 && greyscale < 230){
return '.';
}else if(greyscale >= 180 && greyscale < 200){
return '\'';
}else if(greyscale >= 160 && greyscale < 180){
return ':';
}else if(greyscale >= 130 && greyscale < 160){
return 'o';
}else if(greyscale >= 100 && greyscale < 130){
return '&';
}else if(greyscale >= 70 && greyscale < 100){
return '8';
}else if(greyscale >= 50 && greyscale < 70){
return '#';
}else if(greyscale < 50){
return '@';
}
}
int main(){
char ppmFile[100];
char outputFile[100];
int n;
scanf("%s", &ppmFile); //read the name of input file
scanf("%s", &outputFile); //read the name of output file
// the size of a window of pixels you have to convert to ascii art character
scanf("%d", &n);
FILE *input = fopen(ppmFile, "rb");
FILE *output = fopen(outputFile, "w");
int width, height; // max pixel is always 255
// read the header from the ppm file
fscanf(input, "P6\n%d %d\n255\n", &width, &height);
// allocate place for array[width][length][3]
int a, b;
int ***array;
array = malloc(width*sizeof(int **));
for(a = 0; a < width; a++){
array[a] = malloc(height*sizeof(int *));
for(b = 0; b < height; b++){
array[a][b] = malloc(3*sizeof(int));
}
}
int x, y;
for (x = 0; x < width; x++){
for(y=0; y < height; y++){
array[x][y][0] = fgetc(input); //red
array[x][y][1] = fgetc(input); //green
array[x][y][2] = fgetc(input); //blue
int greyscale;
int i, j;
// convert blocks of pixels to a character and write it into output file
for(i = 0; i < width; i+=n){
for(j=0; j < height; j+=n){
// greyscale = (red + green +blue)/3;
greyscale = (array[i][j][0] + array[i][j][1] +array[i][j][2])/(3*n*n);
char c = method_of_conversion(greyscale);
fprintf(output,"%c",c); // write the ASCII art directly in the output file
}
}
}fprintf(output,"\n"); // dont forget to go into a new line
}
free(array);
fclose(input);
fclose(output);
return 0;
}
这些行:
for(i = 0; i < width; i+=n){
for(j=0; j < height; j+=n){
可能不正确。如果 n = 3
,您读取图像 X 和 Y 上的每 3 个像素而不是局部块。这将为您提供一个分散的数据集,而不是一个块。
或者... 您在此代码中放置第二组 for 循环,从 0
计数到 n-1
并读取所有要平均的像素。这实际上可能是这里缺失的部分。
for(i = 0; i < width; i+=n){
for(j=0; j < height; j+=n){
for(blockx = 0; blockx < n; blockx++){
for(blocky=0; blocky < n; blocky++){
// Use current averaging code to gather all numbers,
// being careful of overflow.
我正在编写一个程序,用于将文件从 PPM 格式转换为 ASCII 艺术。通过计算红绿蓝值的平均值((red + green +blue)/3)
,将输入图像的每个像素转换为灰度。
基础版的升级是我在n*n
大小的window中计算RGB的平均值,并将其转换为字符,从而减小图像的大小。因此,如果给定数字 n
为 3
,则 window 的大小为 3*3
,这意味着您将所有九个红色、绿色和蓝色值相加并除以 3次 n*n
(在本例中为 3*3
)。当程序计算第一个 window 的灰度时,它会移动到另一个,依此类推,直到结束。当宽度结束时,它跳下 n 个像素并读取下一行等。
计算灰度后,将其转换为字符,并将该字符写入输出文件以形成 ASCII 艺术图像。
我的程序编译通过了,但是当我测试它时,我得到了错误的图像。一个非常简单的图像转换为空白文件,另一个看起来应该像棋盘,但它打印了一个非常大的列图像。这些图像都通过扫描像素块 1*1 转换为 ASCII 艺术。第三张图片很大,应该按3*3块转换,但是我得到的输出文件太大打不开。在一个简单的文本编辑器中。
谁能告诉我哪里出错了?
代码如下:
#include <stdio.h>
#include <stdlib.h>
// convert the calculated greyscale to a character based on brightness
char method_of_conversion(int greyscale){
if(greyscale >= 230){
return ' ';
}else if(greyscale >= 200 && greyscale < 230){
return '.';
}else if(greyscale >= 180 && greyscale < 200){
return '\'';
}else if(greyscale >= 160 && greyscale < 180){
return ':';
}else if(greyscale >= 130 && greyscale < 160){
return 'o';
}else if(greyscale >= 100 && greyscale < 130){
return '&';
}else if(greyscale >= 70 && greyscale < 100){
return '8';
}else if(greyscale >= 50 && greyscale < 70){
return '#';
}else if(greyscale < 50){
return '@';
}
}
int main(){
char ppmFile[100];
char outputFile[100];
int n;
scanf("%s", &ppmFile); //read the name of input file
scanf("%s", &outputFile); //read the name of output file
// the size of a window of pixels you have to convert to ascii art character
scanf("%d", &n);
FILE *input = fopen(ppmFile, "rb");
FILE *output = fopen(outputFile, "w");
int width, height; // max pixel is always 255
// read the header from the ppm file
fscanf(input, "P6\n%d %d\n255\n", &width, &height);
// allocate place for array[width][length][3]
int a, b;
int ***array;
array = malloc(width*sizeof(int **));
for(a = 0; a < width; a++){
array[a] = malloc(height*sizeof(int *));
for(b = 0; b < height; b++){
array[a][b] = malloc(3*sizeof(int));
}
}
int x, y;
for (x = 0; x < width; x++){
for(y=0; y < height; y++){
array[x][y][0] = fgetc(input); //red
array[x][y][1] = fgetc(input); //green
array[x][y][2] = fgetc(input); //blue
int greyscale;
int i, j;
// convert blocks of pixels to a character and write it into output file
for(i = 0; i < width; i+=n){
for(j=0; j < height; j+=n){
// greyscale = (red + green +blue)/3;
greyscale = (array[i][j][0] + array[i][j][1] +array[i][j][2])/(3*n*n);
char c = method_of_conversion(greyscale);
fprintf(output,"%c",c); // write the ASCII art directly in the output file
}
}
}fprintf(output,"\n"); // dont forget to go into a new line
}
free(array);
fclose(input);
fclose(output);
return 0;
}
这些行:
for(i = 0; i < width; i+=n){
for(j=0; j < height; j+=n){
可能不正确。如果 n = 3
,您读取图像 X 和 Y 上的每 3 个像素而不是局部块。这将为您提供一个分散的数据集,而不是一个块。
或者... 您在此代码中放置第二组 for 循环,从 0
计数到 n-1
并读取所有要平均的像素。这实际上可能是这里缺失的部分。
for(i = 0; i < width; i+=n){
for(j=0; j < height; j+=n){
for(blockx = 0; blockx < n; blockx++){
for(blocky=0; blocky < n; blocky++){
// Use current averaging code to gather all numbers,
// being careful of overflow.