位图信息头BITMAPINFOHEADER

 
位图信息头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;  

这个结构的长度是固定的,为40个字节(LONG为32位整数),各个域的说明如下: biSize 指定这个结构的长度,为40。 biWidth 指定图象的宽度,单位是象素。 biHeight 指定图象的高度,单位是象素。 biPlanes 必须是1,不用考虑。 biBitCount 指定表示颜色时要用到的位数,常用的值为1(黑白二色图), 4(16色图), 8(256色), 24(真彩色图)(新的.bmp格式支持32位色,这里就不做讨论了)。 biCompression 指定位图是否压缩,有效的值为BI_RGB,BI_RLE8,BI_RLE4,BI_BITFIELDS(都是一些Windows定义好的常量)。要说明的是,Windows位图可以采用RLE4,和RLE8的压缩格式,但用的不多。我们今后所讨论的只有第一种不压缩的情况,即biCompression为BI_RGB的情况。 biSizeImage 指定实际的位图数据占用的字节数,其实也可以从以下的公式中计算出来: biSizeImage=biWidth’ × biHeight 要注意的是:上述公式中的biWidth’必须是4的整倍数(所以不是biWidth,而是biWidth’,表示大于或等于biWidth的,最接近4的整倍数。举个例子,如果biWidth=240,则biWidth’=240;如果biWidth=241,biWidth’=244)。如果biCompression为BI_RGB,则该项可能为零 biXPelsPerMeter 指定目标设备的水平分辨率,单位是每米的象素个数,关于分辨率的概念。 biYPelsPerMeter 指定目标设备的垂直分辨率,单位同上。 biClrUsed 指定本图象实际用到的颜色数,如果该值为零,则用到的颜色数为2biBitCount。 biClrImportant 指定本图象中重要的颜色数,如果该值为零,则认为所有的颜色都是重要的。

一般作为CreateDIBSection函数的第二个参数,CreateDIBSection函数如下:

HBITMAP CreateDIBSection(HDC hdc,CONST BITMAPINFO *pbmi,UINT iUsage,VOID** ppvBits,HANDLE hSection,DWORD dwOffset);

参数:

  hdc:设备环境句柄。如果iUsage的值是DIB_PAL_COLORS,那么函数使用该设备环境的逻辑调色板对与设备无关位图的颜色进行初始化。

  pbmi:指向BITMAPINFO结构的指针,该结构指定了与设备无关位图的各种属性,其中包括位图的维数和颜色。

  iUsage:指定由pbmi参数指定的BITMAPINFO结构中的成员bmiColors数组包含的数据类型(要么是逻辑调色板索引值,要么是原文的RGB值)。下列值是系统定义的,其含义为:

  DIB_PAL_COLORS:表示成员bmiColors是hdc指定的设备环境的逻辑调色板,使用的是16位索引值数组。

  DIB_RGB_COLORS:表示结构BITMAPINFO中包含了RGB值的数组。

  ppvBits:指向一个变量的指针,该变量接收一个指向DIB位数据值的指针。

  hSection:文件映射对象的句柄。函数将使用该对象来创建DIB(与设备无关位图)。该参数可以是NULL。

  如果hSection不是NULL,那么它一定是文件映射对象的句柄。该对象是通过调用带有PAGE_READWRITE或PAGE_WRITECOPY标志的CreateFileMapping函数创建的。不支持只读的DIB类型。通过其他方法创建的句柄将会引起CreateDIBSection函数执行失败。

  如果hSection不是NULL,那么函数CreateDIBSection将在hSection引用的文件映射对象中偏移量为dwOffset处获取位图的位数据值。应用程序可以在以后通过调用GetObject函数来检索hSection句柄,其中GetObject函数使用了GreateDIBSection函数返回的GBITMAP类型的对象。

  如果hSection为NULL,那么系统将为与设备无关位图(DIB)分配内存。在这种情况下,函数CreateDIBSection将忽略参数dwOffset,应用程序无法在以后获取指向内存的句柄。通过调用GetObject函数来填充的DIBSECTION结构成员dshSection也将成为NULL。

  DwOffset:指定从hSection引用的文件映射对象开始处算起的偏移量,超过这个偏移量的地方就是位图的位数据值开始存放的地方。在hSection为NULL时忽略该值。位图的位数据值是以DWORD为单位计算的。

  返回值:如果函数执行成功,那么返回值是一个指向刚刚创建的与设备无关位图的句柄,并且*ppvBits指向该位图的位数据值;如果函数执行失败,那么返回值为NULL,并且*ppvBit也为NULL,若想获得更多错误信息,请调用GetLastError函数。

示例:

	HDC hTempDC = ::CreateCompatibleDC(hDestDC);
	if (NULL == hTempDC)
		return;

	//Creates Source DIB
	LPBITMAPINFO lpbiSrc;
	// Fill in the BITMAPINFOHEADER
	lpbiSrc = (LPBITMAPINFO) new BYTE[sizeof(BITMAPINFOHEADER)];
	lpbiSrc->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
	lpbiSrc->bmiHeader.biWidth = dwWidth;
	lpbiSrc->bmiHeader.biHeight = dwHeight;
	lpbiSrc->bmiHeader.biPlanes = 1;
	lpbiSrc->bmiHeader.biBitCount = 32;
	lpbiSrc->bmiHeader.biCompression = BI_RGB;
	lpbiSrc->bmiHeader.biSizeImage = dwWidth * dwHeight;
	lpbiSrc->bmiHeader.biXPelsPerMeter = 0;
	lpbiSrc->bmiHeader.biYPelsPerMeter = 0;
	lpbiSrc->bmiHeader.biClrUsed = 0;
	lpbiSrc->bmiHeader.biClrImportant = 0;

	COLORREF* pSrcBits = NULL;
	//创建应用程序可以直接写入的、与设备无关的位图(DIB)
	HBITMAP hSrcDib = CreateDIBSection (
		hSrcDC, lpbiSrc, DIB_RGB_COLORS, (void **)&pSrcBits,
		NULL, NULL); 
	if ((NULL != hSrcDib) && (NULL != pSrcBits))
	{
		HBITMAP hOldTempBmp = (HBITMAP)::SelectObject (hTempDC, hSrcDib);
                  .................
                  .................
         }



 

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
windows平台上支持BITMAPCOREHEADERBITMAPINFOHEADERBITMAPV4HEADERBITMAPV5HEADER四种类型位图的类库! 简单用法举例: DibBitmap bmp,ret,tmp; bmp.Open(_T("E:\\bmp.bmp"));//打开 bmp.ConvertBit(4,ret);//转为4位位图,ret保存返回值 ret.RotateLeft(tmp);//向左旋转90度,tmp保存返回值 tmp.Invert();//所有像素反色,即RGB(1,2,3)变为RGB(254,253,252) tmp.At(10,10)=tmp.At(20,20);//单个像素点的取值和赋值操作 tmp.At(10,20)=ret.At(30,30);//注意,设置成的颜色如果颜色表内不存在,会设置成相近色 tmp.At(20,10)=RGB(255,0,0); bmp.AlphaBlend(0,0,tmp,128,RGB(255,255,255),true);//tmp以透明度128画到bmp的(0,0)处,其中tmp中的白色会镂空 bmp.Mirror();//bmp水平翻转 bmp.ConvertBit(16,ret,true);//转为5-6-5型16位位图,ret保存返回值 ret.SetClipbrd();//存入剪切板中 ret.Save(_T("E:\\bmp2.bmp"));//保存到文件 该类的文件接口大致如下: class DibBitmap { BITMAPFILEHEADER* m_pbmfh; DWORD m_size;//保存m_pbmfh中malloc出来的内存大小,即是capacity//不为0时保证图像是可以处理的 public: enum BmType{NONE=0,CORETYPE,INFOTYPE,V4TYPE,V5TYPE}; public: class reference { //略.. }; public://DibBitmap01.cpp DibBitmap(); explicit DibBitmap(LPCTSTR pstrFileName); explicit DibBitmap(BITMAPFILEHEADER* pbmfh);//只是简单的赋值给成员变量m_pbmfh DibBitmap(HDC hdc, HBITMAP hBitmap, int BitCount);//1,4,8;16,24,32 DibBitmap(const DibBitmap& rhs); ~DibBitmap(); bool Open(LPCTSTR pstrFileName);//打开失败会Close() bool Save(LPCTSTR pstrFileName)const; void Close(); void Swap(DibBitmap& rhs); DibBitmap& operator=(const DibBitmap& rhs);//不一定申请过新内存 public://DibBitmap01.cpp BITMAPFILEHEADER* Get();//获取文件 const BITMAPFILEHEADER* Get()const; BITMAPINFOHEADER* GetInfoHead();//获取信息 const BITMAPINFOHEADER* GetInfoHead()const; RGBQUAD* GetQuad();//获取颜色表//没有颜色表,则返回NULL const RGBQUAD* GetQuad()const; BYTE* GetByte();//获取图素位 const BYTE* GetByte()const; bool GetMask(DWORD* dwMask,bool b565=false)const; //dwMask个数为四,需要屏蔽码时,依次存入RGB屏蔽码,并返回true //当为BITMAPV4HEADER以上时,还存入AlphaMask;b565参数同GetClr bool Attach(BITMAPFILEHEADER* pbmfh); BITMAPFILEHEADER* Detach();//返回值最后须free掉 HBITMAP CreateBitmap(HDC hdc)const;//返回值最后须DeleteObject掉 HBITMAP CreateDibSection ()const;//返回值最后须DeleteObject掉 BmType Type()const; DWORD Capacity()const;//返回m_size的值//注意,此值可能小于实际malloc的内存长度 DWORD FileSize()const;//整个文件的大小//不是返回m_size的值,m_size的值大于等于此返回值 DWORD BitsSize()const;//图素位的大小,即去掉文件信息和颜色表之后的大小 DWORD Offset()const;//图素位的偏移量 LONG Width()const; LONG Height()const;//可能为负值 WORD Planes()const; WORD BitCount()const; DWORD ClrUsed()const; //一般是4,8位图才小于2^(4,8),其余的等于对应颜色数,m_pbmfh为空时返回0,32位图时,返回-1,16位555位图颜色数按565算 public://DibBitmap02.cpp LPTSTR DisplayDibHeader (LPTSTR szBuffer)const;//szBuffer得大于1200个//返回szBuffer RGBQUAD GetClr(size_t x,size_t y,bool b565=false)const; //获取(x,y)处的颜色值,已考虑方向问题,b565只有在16位深位图且没有屏蔽码时才有用,指明是5-5-5还是5-6-5 COLORREF GetRGBClr(size_t x,size_t y,bool b565=false)const;//条件同上//返回的最高位为0 bool GetClipbrd(HWND hwnd);//失败不一定会Close() void SetClipbrd(HWND hwnd)const; //If hwnd is NULL, the open clipboard is associated with the current task. void Mirror(bool bHoriz);//镜像//false表示垂直镜像 public://DibBitmap03.cpp void Invert(bool b565=false);//反色//在这里b565参数不起任何作用 RGBQUAD Invert(size_t x,size_t y,bool b565=false);//(x,y)处的颜色反色,返回反色后的近似颜色 RGBQUAD SetClr(size_t x,size_t y,RGBQUAD quad,bool b565=false);//设置颜色,返回设置成的最相近的颜色 COLORREF SetRGBClr(size_t x,size_t y,COLORREF clr,bool b565=false);//设置颜色,返回设置成的最相近的颜色 //以下两个函数相当牛逼,可直接引用修改颜色 COLORREF At(size_t x,size_t y,bool b565=false)const;//获取(x,y)处的颜色 reference At(size_t x,size_t y,bool b565=false);//获取(x,y)处的颜色引用,可直接进行修改 void AlphaBlend(int x,int y,const DibBitmap& rhs,BYTE bAlpha,COLORREF clr,bool bClr=false,bool b565=false); //把rhs以透明度bAlpha画到this中的(x,y)处(可以为负),注意:当&rhs==this时直接返回,啥也不操作 //若bClr为true,则clr参数有用,rhs中颜色值为clr的像素点完全透明 void RotateLeft(DibBitmap& ret)const; //this旋转(逆时针90度)后存入ret中,若this原先为空,则不改变ret,注意:当&ret==this时直接返回,啥也不操作 void RotateRight(DibBitmap& ret)const; //this旋转(顺时针90度)后存入ret中,若this原先为空,则不改变ret,注意:当&ret==this时直接返回,啥也不操作 void RotateOpposite();//旋转180度,注意后面没有const,此函数是旋转自身 public://DibBitmap04.cpp bool ConvertBit(WORD BitCount,DibBitmap& ret,bool b565=false)const; //转为同类型的不同位数位图//1,4,8;16,24,32,注意:当&ret==this时直接返回,啥也不操作 }; 说明: 此类支持四种位图格式: BITMAPCOREHEADERBITMAPINFOHEADERBITMAPV4HEADERBITMAPV5HEADER。 该类像素点坐标序号从0开始,原点位于位图左上角,不管位图信息的高度字段是否为负,内部都已作转化处理 暂不支持这四种位图的以下几种情况: 1、biCompression字段为BI_RLE4,BI_RLE8,BI_JPEG,BI_PNG的位图; 2、BITMAPV5HEADER时,bV5CSType字段等于PROFILE_LINKED或PROFILE_EMBEDDED时的位图。 有问题联系:hastings1986@163.com

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值