1、前14个字节为文件信息头,在这部分信息中包含了位图信息标志、该bmp图像的大小和图像实际数据的相宽简对偏移量这三部分有用的信息慎码裤。
位图标志一定为“0x4D42”,否则,该文件不是bmp图像。
在VC++中,这14个字节对应一个数据类型,类型名为“BITMAPFILEHEADER”,它的定义为:
typedef struct tagBITMAPFILEHEADER {
WORDbfType //位图信息标志
DWORD bfSize //图像的大小
WORDbfReserved1
WORDbfReserved2
DWORD bfOffBits//图像实际数据的相对偏移量
} BITMAPFILEHEADER, FAR *LPBITMAPFILEHEADER, *PBITMAPFILEHEADER
可以设一个该类型的变量:BITMAPFILEHEADER bmfh,将bmp图像文件的前14字节数据读入这个变量中,然后通过判断bmfh.bfType == 0x4D42,确定是不是为bmp图像。
2、接下来40个字节为位图信息头,其中存储了该bmp图像的有关信息。这些信息包括:图像宽度(像素)、图像高度(像素)、图像长度(字节,仅仅是图像实际数据的长度,不包括各个信息头)、水平分辨率、垂直分辨率、每个像素的存储位数等信息。
其中,通过“每个像素的存储位数”这个信息可以知道图像的颜色:
如果“每个像素的存储位数”的值只有四种:为1,说明图像只有两种颜色(黑、白);为4,说明图像有16种颜色;为8,说明图像有256种颜色;为24,说明该图像为真彩色图像,颜色数为2^24。这四种取值对应四种bmp图像,也就是说,bmp图像只有这四种。
在这四种bmp图像种,前三种都需要在图像文件中包含调色板数据,分别存储三种图像的2、16、256种颜色。而最后一种bmp格式的图像不需要调色板,因为这种图像的“每个像素的存储位数”值为24,也就是说,存储一个像素值需要24位,正好可以存储一个像素的颜色模腊(红、绿、蓝各8位)。
在VC++中,这40个字节的位图信息头也有一个数据类型,类型名为“BITMAPINFOHEADER”,它的定义为:
typedef struct tagBITMAPINFOHEADER{
DWORD biSize
LONG biWidth //图像宽度(像素)
LONG biHeight//图像高度(像素)
WORD biPlanes
WORD biBitCount //每个像素的存储位数
DWORD biCompression
DWORD biSizeImage //图像长度(字节,仅仅是图像实际数据的长度,不包括各个信息头)
LONG biXPelsPerMeter //水平分辨率
LONG biYPelsPerMeter //垂直分辨率
DWORD biClrUsed
DWORD biClrImportant
} BITMAPINFOHEADER, FAR *LPBITMAPINFOHEADER, *PBITMAPINFOHEADER
3、接下来若干个字节为调色板,只有前三种bmp图像有,第四种真彩色bmp图像没有这部分数据。
调色板是一个数组,每个数组元素有四字节,只有三个字节有用,另外一个没有。有用的三个字节存储一种颜色(红绿蓝各占一字节),这四个字节在VC++中定义为:
typedef struct tagRGBQUAD {
BYTErgbBlue
BYTErgbGreen
BYTErgbRed
BYTErgbReserved
} RGBQUAD
定义一个这种类型的数组即为调色板。数组的长度可由BITMAPINFOHEADER中的biBitCount推算出来。
4、上述三部分信息之后,即是实际的像素数据。一个像素的存储位数为1、4、8或16,正如前面所述。
如果是1位,对应的bmp图像应该有一个长度为2的调色板。这一位的值只能是0或1,用来指明该像素的颜色在调色板中的地址。
如果是4位,对应的bmp图像应该有一个长度为16的调色板。这4位的值有16种,同样指示该像素的颜色在调色板中的地址。
如果是8位,对应的bmp图像应该有一个长度为256的调色板。这8位的值有256种,同样指示该像素的颜色在调色板中的地址。
如果是24位,对应的bmp图像没有调色板,该像素的颜色由这24位数据直接表示。
bmp图像的数据就这几个部分。
任何一个bmp图像的像素都是由红绿蓝三种颜色组成(带调色板也好,不带调色板也好)。如果一个像素的红绿蓝三种色的值相等,那么该像素就是灰色的。灰度图是这样一种有严格规定的bmp图像:它是上述四种bmp图像的第三种,并且它的调色板的每个数组元素的红绿蓝三值都相同,所以灰度图的灰度种数是256。
若要保存图像,需要按顺序保存文件信息头、位图信息头、调色板(如果有)和图像的实际数据。程序可以这样写:
bool Write(CString FileName)
{
CFile file
BITMAPFILEHEADER bmfh
if(! (bmi &&pBits))
{
AfxMessageBox("Data is not valid!")
return FALSE
}
//创建文件
if(!file.Open(FileName,CFile::modeCreate | CFile::modeWrite))
{
AfxMessageBox("File creating fails!")
return FALSE
}
//填写文件信息头
bmfh.bfType = 0x4d42
bmfh.bfReserved1 = bmfh.bfReserved2 = 0
int nInfoSize = sizeof(BITMAPINFOHEADER) + GetPaletteSize() * sizeof(RGBQUAD)
bmfh.bfOffBits = sizeof(bmfh) + nInfoSize
bmfh.bfSize = bmfh.bfOffBits + bmi->bmiHeader.biSizeImage
//写文件
file.Write( (LPVOID)&bmfh, sizeof(bmfh))
file.Write( (LPVOID)bmi, nInfoSize)
file.Write( (LPVOID)pBits, bmi->bmiHeader.biSizeImage)
return TRUE
}
http://wenku.baidu.com/view/550a8fd049649b6648d7478a.html
http://wenku.baidu.com/view/fe8ff04ffe4733687e21aa95.html
http://wenku.baidu.com/view/c2438ceb6294dd88d0d26b95.html
http://wenku.baidu.com/view/685704a1284ac850ad024295.html
最简单的办法,声颂前明一个TBitmap类型洞伍的对象,然后读取你要的文件,然后画出来就可以了代码如下:
var bmp: TBitmap
bmp := TBitmap.Create
try
bmp.LoadFromFile(Filename)
Canvas.Draw(x, y, bmp) //x, y换成你要的坐标
finally
bmp.Free
end
Delphi还支持PNG,纳樱或JPG和GIF格式的读取。你需要在Uses里面添加PNGImage,JPEG,
如果你想要直接Bmp图片是怎么读取进来的详细细节,把鼠标移动到Uses下的Graphics,按住Ctrl单击Graphics,然后搜索TBitmap类,看LoadFromStream函数,可以看到详细的代码。
1、首先要了解bmp位图的格式,搜索些技术支持文档,bmp位图基本上是分4大部分,文件信息结果部分,文件头信息结果部分,调色板结果部分,后面就是数据孙乎实体部分。及其每个部分对应有用的信息。比如长宽。当然长宽信息你自己可以从window系统下看得到。打开bmp文件,把前面三部分的字节总数给固定下来,逐个字符读取,然后读取数据实体部分,输出就可以了。
2、例程:
#include <stdio.h>#include <stdlib.h>
#pragma pack(2)
/*定义WORD为两个字节的类型*/
typedef unsigned short WORD
/*定义DWORD为e四个字节的类型*/
typedef unsigned long DWORD
/*位图文件头*/
typedef struct BMP_FILE_HEADER
{
WORD bType /* 文件标识符 */
DWORD bSize /* 文件的大小 */
WORD bReserved1 /* 保留值,必须设置为0 */
WORD bReserved2 /* 保留值,必须设置为0 */
DWORD bOffset /* 文件头的最后到图像数据位开始的偏移量 */
} BMPFILEHEADER
/*位图信息头*/
typedef struct BMP_INFO
{
DWORD bInfoSize /* 信息头的大小 */
DWORD bWidth /* 图像的宽度 */
DWORD bHeight /* 图像的则搏悉高度 */
WORD bPlanes /* 图银做像的位面数 */
WORD bBitCount /* 每个像素的位数 */
DWORD bCompression /* 压缩类型 */
DWORD bmpImageSize /* 图像的大小,以字节为单位 */
DWORD bXPelsPerMeter /* 水平分辨率 */
DWORD bYPelsPerMeter /* 垂直分辨率 */
DWORD bClrUsed /* 使用的色彩数 */
DWORD bClrImportant /* 重要的颜色数 */
} BMPINF
/*彩色表*/
typedef struct RGB_QUAD
{
WORD rgbBlue /* 蓝色强度 */
WORD rgbGreen /* 绿色强度 */
WORD rgbRed /* 红色强度 */
WORD rgbReversed /* 保留值 */
} RGBQUAD
int main()
{
FILE *fp
BMPFILEHEADER fileHeader
BMPINF infoHeader
long offset, bmpImageSize, width, height, bytesPerPixel, size, bitCount
// int i, j
// unsigned char **p
WORD c
if((fp = fopen("5.bmp", "rb")) == NULL)
{
printf("Cann't open the file!\n")
exit(0)
}
fseek(fp, 0, 0)
fread(&fileHeader, sizeof(fileHeader), 1, fp)
fread(&infoHeader, sizeof(infoHeader), 1, fp)
//计算并输出位图数据的偏移量,图像的大小,宽度和高度,每个像素点所占的字节
size = fileHeader.bSize
offset = fileHeader.bOffset
bmpImageSize = infoHeader.bmpImageSize
width = infoHeader.bWidth
height = infoHeader.bHeight
bitCount = infoHeader.bBitCount
bytesPerPixel = infoHeader.bBitCount / 8
printf("%d %d %d %d %d %d\n", size, offset, bmpImageSize, width, height, bitCount, bytesPerPixel)
//输出每个像素点所占字节中的内容
c = fgetc(fp)
while (!feof(fp))
{
printf("%x ", c)
c = fgetc(fp)
}
printf("\n")
fclose(fp)
return 0
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)