以下是代码:
#include <stdio.h>
#include <stdlib.h>
void main(void)
{
char path_bmp [100];
char path_txt [100];
int w; //width
int h; //height
int wc; //width counter
int hc; //height counter
FILE *bfp; //BMP pointer
FILE *tfp; //TXT pointer
puts("BMP path");
gets(path_bmp);
puts("Resulting TXT path");
gets(path_txt);
bfp = fopen(path_bmp, "r");
tfp = fopen(path_txt, "w");
fseek(bfp, 18, SEEK_SET);
fscanf(bfp, "%i", &w);
fseek(bfp, 4, SEEK_CUR);
fscanf(bfp, "%i", &h);
printf("%i x %i", w, h);
char mat [w][h];
fseek(bfp, 54, SEEK_SET);
for(hc=0; hc < h; hc++)
fread(mat, 1, w, bfp);
for(hc=0; hc < h; hc++)
for(wc=0; wc < w; wc++)
{
if (mat [wc][hc] == 0)
fprintf(tfp, " ");
else
fprintf(tfp, "o");
}
fprintf(tfp, "\n");
}
它打算做什么: 它将.bmp转换为ASCII艺术,不是非常复杂,只是非常简单的黑白图片。 它应该读取.bmp,从标题获取高度和宽度,逐字节读取所有像素到矩阵( mat 数组),然后如果像素是白色则将空间写入文本文件,如果是像素则写入“0”是任何颜色,但白色。
它实际上做了什么:
它是从一个错误的地方读取w和h。
在printf("%i x %i", w, h);
上打印出一些大数字(我使用小图片进行测试,比如10x6像素),然后崩溃,进程返回更大的数字。据我所知,该程序显然是从一些垃圾读取,而不是它应该读取的地方,我无法理解(花了很多时间试图找出它)。
另外,我觉得在从数组读取数组/写入时我做错了,所以指出这些缺陷会非常感激。
UPD:谢谢你们,伙计们,你们给了我很大的帮助!答案 0 :(得分:2)
您的代码似乎存在一些问题,包括一些关于C的基本内容。 我评论了一些我第一眼看到的错误,但可能会有更多错误。 我还建议您查看bitmap format,特别是在描述添加到每行末尾的填充的部分。
#include <stdio.h>
#include <stdlib.h>
void main(void)
{
char path_bmp [100];
char path_txt [100];
int w; //width
int h; //height
int wc; //width counter
int hc; //height counter
FILE *bfp; //BMP pointer
FILE *tfp; //TXT pointer
puts("BMP path");
gets(path_bmp);
puts("Resulting TXT path");
gets(path_txt);
bfp = fopen(path_bmp, "r");
tfp = fopen(path_txt, "w");
fseek(bfp, 18, SEEK_SET);
fread(&w, sizeof(int), 1, bfp); // Read the width in binary format (signed integer)
fread(&h, sizeof(int), 1, bfp); // The position indicator of the stream is advanced by the total amount of bytes read (sizeof(int)).
printf("%i x %i", w, h);
pixel mat [w][h]; //This can be a packed structure or a union, so you can read all 3 color components with one fread() call
fseek(bfp, 54, SEEK_SET);
for(hc=0; hc < h; hc++)
{
for(wc=0; wc < w; wc++)
{
/* Note that you have to read three bytes, since every pixel has 3 color components*/
fread(mat[wc][hc].red, sizeof(char), 1, bfp);
fread(mat[wc][hc].green, sizeof(char), 1, bfp);
fread(mat[wc][hc].blue, sizeof(char), 1, bfp);
}
// you need to do a fseek() here, in order to advance the padding added to the end of each line defined in .BMP format
fprintf(tfp, "\n");
}
}
答案 1 :(得分:1)
fscanf
的 %i
读取一个整数作为ASCII数字序列,但宽度&amp; BMP的高度存储在原始二进制文件中。请改用fread
来阅读它们:
fread(&w, 1, 4, bfp);
fread(&h, 1, 4, bfp);
(在读取高度之前不需要fseek
,因为之前的fread
已经推进了流指针。fscanf
也是如此
作为宽度&amp;高度指定为4个字节,建议使用int32_t
而不是int
作为类型,以确保它始终完全适合。