【发布时间】:2014-05-12 10:44:06
【问题描述】:
众所周知,每个字节都是无符号字符,这意味着范围为 0 - 255。 我写了一个可以编写 BMP 的代码,该代码可以工作。问题是当我尝试编写一个宽度/高度大于 255 的 bmp 时,它显示为小于 255 的值。
在宽度的下一点上,我刚刚输入了1,它可以工作。它用 (500) 输出实数,但我希望它也适用于高度.. 但事实并非如此。图像坏了。
更新:高度超过 214 会导致 bmp 损坏。我想念什么? 这是我的代码:
typedef unsigned char BYTE; //1
typedef unsigned short WORD; //2
typedef unsigned long DWORD; //4
typedef struct BMP_HEADER
{
BYTE bmp_type[2]; //2
BYTE bmp_size[4]; //4
BYTE bmp_as[4]; //4
BYTE bmp_offset[4]; //4
} BMP;
typedef struct DIB_HEADER
{
BYTE dib_size[4]; //4
DWORD dib_BMPwidth; //4
DWORD dib_BMPheight; //4
BYTE dib_BMPcplanes[2]; //2
BYTE dib_BMPBPX[2]; //2
BYTE dib_BIRGB[4]; //4
BYTE dib_rawsize[4]; //4
BYTE dib_Xresolution[4]; //4
BYTE dib_Yresolution[4]; //4
BYTE dib_cpalette[4]; //4
BYTE dib_cimportant[4]; //4
} DIB;
typedef struct PIXEL_ARRAY
{
BYTE BGR[3]; //3
} PIX;
BYTE* PAD;
DWORD padding(DWORD BMPwidth)
{
int pitch = BMPwidth * 3;
if (pitch % 4 != 0)
{
pitch += 4 - (pitch % 4);
}
return pitch - (BMPwidth * 3);
}
void create_bmp(char BMPname[], DWORD BMPwidth, DWORD BMPheight, WORD BMPR, WORD BMPG, WORD BMPB)
{
// variables
char build_name[256];
FILE* fp;
BMP newBMP;
DIB newDIB;
PIX* template;
gedMaxGameMem = 2827465479;
if(BMPwidth > 1 && BMPheight > 1) template = (PIX*)malloc(BMPwidth*BMPheight);
else template = (PIX*)malloc(sizeof(PIX*)*max(BMPwidth, BMPheight));
// make file
sprintf(build_name, "%s.bmp", BMPname);
fp = fopen(build_name, "wb");
// BM
newBMP.bmp_type[0] = 'B';
newBMP.bmp_type[1] = 'M';
fwrite(&newBMP.bmp_type, 1, 2, fp);
{
// SIZE
DWORD sz = (sizeof(newBMP) + sizeof(newDIB) + sizeof(template));
fwrite(&sz, 1, 1, fp);
}
// Application specifics
fwrite(&newBMP.bmp_as, 1, 4, fp);
// offset
newBMP.bmp_offset[0] = (sizeof(newBMP) + sizeof(newDIB));
fwrite(&newBMP.bmp_offset, 1, 4, fp);
//
// DIB SIZE
newDIB.dib_size[0] = sizeof(newDIB);
fwrite(&newDIB.dib_size, 1, 4, fp);
// DIB Image width
newDIB.dib_BMPwidth = BMPwidth;
fwrite(&newDIB.dib_BMPwidth, 1, 4, fp);
// DIB Image height
newDIB.dib_BMPheight = BMPheight;
fwrite(&newDIB.dib_BMPheight, 1, 4, fp);
// DIB Color planes
newDIB.dib_BMPcplanes[0] = 1;
fwrite(&newDIB.dib_BMPcplanes, 1, 2, fp);
// DIB BMP Bits per pixel
newDIB.dib_BMPBPX[0] = 24;
fwrite(&newDIB.dib_BMPBPX, 1, 2, fp);
// DIB Compression method
fwrite(&newDIB.dib_BIRGB, 1, 4, fp);
// DIB Raw size
newDIB.dib_rawsize[0] = sizeof(template);
fwrite(&newDIB.dib_rawsize, 1, 4, fp);
// DIB Xresolution
newDIB.dib_Xresolution[0] = 19;
newDIB.dib_Xresolution[1] = 11;
fwrite(&newDIB.dib_Xresolution, 1, 4, fp);
// DIB Yresolution
newDIB.dib_Yresolution[0] = 19;
newDIB.dib_Yresolution[1] = 11;
fwrite(&newDIB.dib_Yresolution, 1, 4, fp);
// DIB Colors palette
fwrite(&newDIB.dib_cpalette, 1, 4, fp);
// DIB Important colors
fwrite(&newDIB.dib_cimportant, 1, 4, fp);
//
{
int i;
for(i=0; i<BMPwidth+1; i++)
{
template[i].BGR[0] = BMPB;
template[i].BGR[1] = BMPG;
template[i].BGR[2] = BMPR;
fwrite(template->BGR, 3, i, fp);
}
}
free(template);
fclose(fp);
}
【问题讨论】:
-
您似乎正在写入许多未初始化的值。例如,我看不到您将 newDIB 结构归零。您只需设置一些字段,例如 dib_BMPheight[0](有时还有 dib_BMPheight[1]),但不设置 dib_BMPheight[2] 和 dib_BMPheight[3]。然后你把它们写出来,所以它们可能是垃圾。
-
还要注意步幅可能与宽度不匹配。 (步幅是从一个扫描线到下一个扫描线的字节数。)每个扫描线必须与一个四字节边界对齐。那就是步幅必须是 4 的倍数。由于每个像素写入 3 个字节,因此只有当宽度是 4 的倍数时,步幅才匹配宽度*3。
-
“未初始化”值是什么意思?为什么我必须将 newDIB 结构“归零”,我使用 fwrite 来写入我想要的字节。而且宽度现在也有效,高度现在给我带来了问题。如果步幅日志。东西可以帮助我..我怎样才能用它来指定高度的步幅?
-
newDIB.dib_size[0] = sizeof(newDIB); fwrite(&newDIB.dib_size, 1, 4, fp);将四个字节写入文件,但您只设置了其中一个。其他三个未初始化。当您在堆栈上实例化一个变量时,它的值可以是任何值,直到您将其显式设置为某个值。如果变量是一个结构,那么你必须在使用它们之前初始化所有其中的字段。 -
我忘记了,谢谢 :) 即便如此.. 我在审查 BMP 结构的 1 小时内成功地做了一些事情,而且我的英语甚至很糟糕。现在我认为我对更改的初始化程序和使用的填充没有问题。
标签: c bitmap bmp image-size