内存块中的数据转存入位图

来源:互联网 发布:达内少儿编程能加盟吗 编辑:程序博客网 时间:2024/05/21 22:58

内存区块转存BMP图像

位图基本知识:

1. 位图格式 BMPbitmap的缩写形式,bitmap顾名思义,就是位图也即Windows位图。它一般由4部分组成:文件头信息块、图像描述信息块、颜色表(在真彩色模式无颜色表)和图像数据区组成。在系统中以BMP为扩展名保存。

2.打开Windows的画图程序,在保存图像时,可以看到三个选项:2色位图(黑白)、16色位图、256色位图和24位位图。

位图计算机存储:

位图文件头BITMAPFILEHEADER、位图信息头BITMAPINFOHEADER、调色板Palette、实际的位图数据ImageDate

第一部分为位图文件头BITMAPFILEHEADER,是一个结构,其定义如下:

typedef unsigned char BYTE

typedef unsigned short WORD

typedef unsigned long DWORD

typedef struct tagBITMAPFILEHEADER {

WORD bfType; //类型名,必须是0x424D,即字符串“BM”,

DWORD bfSize; //文件大小

WORD bfReserved1; //保留字,不考虑

WORD bfReserved2; //保留字,同上

DWORD bfOffBits; //实际位图数据的偏移字节数,即前三个部分长度之和

} BITMAPFILEHEADER;

 

第二部分为位图信息头BITMAPINFOHEADER,也是一个结构,其定义如下:

typedef struct tagBITMAPINFOHEADER{

DWORD biSize; //指定此结构体的长度,为40

LONG biWidth; //位图宽

LONG biHeight; //位图高

WORD biPlanes; //平面数,为1

WORD biBitCount //采用颜色位数,可以是12481624,新的可以是32

DWORD biCompression; //压缩方式,可以是012,其中0表示不压缩

DWORD biSizeImage; //实际位图数据占用的字节数

LONG biXPelsPerMeter; //X方向分辨率

LONG biYPelsPerMeter; //Y方向分辨率

DWORD biClrUsed; //使用的颜色数,如果为0,则表示默认值(2^颜色位数)

DWORD biClrImportant; //重要颜色数,如果为0,则表示所有颜色都是重要的

} BITMAPINFOHEADER;

 

第三部分为调色板Palette,当然,这里是对那些需要调色板的位图文件而言的。24位和32位是不需要调色板的。

typedef struct tagRGBQUAD {

BYTE rgbBlue; //该颜色的蓝色分量

BYTE rgbGreen; //该颜色的绿色分量

BYTE rgbRed; //该颜色的红色分量

BYTE rgbReserved; //保留值

} RGBQUAD;

 

第四部分就是实际的图象数据了。对于用到调色板的位图,图象数据就是该象素颜在调色板中的索引值。对于真彩色图,图象数据就是实际的RGB值。对于2色位图,用1位就可以表示该象素的颜色(一般0表示黑,1表示白),所以一个字节可以表示8个象素。对于16色位图,用4位可以表示一个象素的颜色,所以一个字节可以表示2个象素。对于256色位图,一个字节刚好可以表示1个象素。对于真彩色图,三个字节才能表示1个象素。要注意两点: (1) 每一行的字节数必须是4的整倍数,如果不是,则需要补齐。 (2)一般来说,.bMP文件的数据从下到上,从左到右的。也就是说,从文件中最先读到的是图象最下面一行的左边第一个象素,然后是左边第二个象素……接下来是倒数第二行左边第一个象素,左边第二个象素……依次类推,最后得到的是最上面一行的最右一个象素。

内存块转存BMP图像核心函数

BOOL DrawBmp(int *Orign,int weight,intheight)

{

       HDChDC;

       intiBits; //当前分辨率下每象素所占字节数   

       WORDwBitCount; //位图中每象素所占字节数

       //定义调色板大小,位图中像素字节大小,位图文件大小,写入文件字节数

       DWORDdwPaletteSize=0, dwBmBitsSize=0, dwDIBSize=0, dwWritten=0; 

       BITMAPBitmap;  //位图属性结构  

       BITMAPFILEHEADERbmfHdr;  //位图文件头结构      

       BITMAPINFOHEADERbi; //位图信息头结构   

       LPBITMAPINFOHEADERlpbi; //指向位图信息头结构    

       HANDLEfh, hDib, hPal,hOldPal=NULL; //定义文件,分配内存句柄,调色板句柄      iBits =GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES); //计算位图文件每个像素所占字节数

       if(iBits <= 1) wBitCount = 1;

       elseif (iBits <= 4) wBitCount = 4;

       elseif (iBits <= 8) wBitCount = 8;

       elseif (iBits <=24) wBitCount = 24;

       elsewBitCount = 32; 

       Bitmap.bmBits= Orign;

       Bitmap.bmWidth= weight;

       Bitmap.bmHeight= height;

       Bitmap.bmWidthBytes= weight * 4;

       Bitmap.bmType=0;

       Bitmap.bmBitsPixel=32;

       Bitmap.bmPlanes=1;

       bi.biSize= sizeof(BITMAPINFOHEADER);

       bi.biWidth= Bitmap.bmWidth;

       bi.biHeight= Bitmap.bmHeight;

       bi.biPlanes= 1;

       bi.biBitCount= wBitCount;

       bi.biCompression= BI_RGB;

       bi.biSizeImage= 0;

       bi.biXPelsPerMeter= 0;

       bi.biYPelsPerMeter= 0;

       bi.biClrImportant= 0;

       bi.biClrUsed= 0;

       dwBmBitsSize= ((Bitmap.bmWidth * wBitCount + 31) / 32) * 4 * Bitmap.bmHeight;

       //为位图内容分配内存

       hDib= GlobalAlloc(GHND,dwBmBitsSize + dwPaletteSize + sizeof(BITMAPINFOHEADER));

       lpbi= (LPBITMAPINFOHEADER)GlobalLock(hDib);

      

       *lpbi=bi;

       //处理调色板  

       hPal= GetStockObject(DEFAULT_PALETTE);

       if(hPal)

       {

              hDC= ::GetDC(NULL);

              hOldPal= ::SelectPalette(hDC, (HPALETTE)hPal, FALSE);

              RealizePalette(hDC);

       }

       //获取该调色板下新的像素值

       LPVOIDpoi=(LPSTR)lpbi + sizeof(BITMAPINFOHEADER) +dwPaletteSize;

       for(int i=0;i<Bitmap.bmWidth;i++)

       {

              for(int j=0;j<Bitmap.bmHeight;j++)

              {

                     ((int*)poi)[i*Bitmap.bmHeight+j]=((int*)Bitmap.bmBits)[i*Bitmap.bmHeight+j];

              }

       }

       //恢复调色板  

       if(hOldPal)

       {

              ::SelectPalette(hDC, (HPALETTE)hOldPal,TRUE);

              RealizePalette(hDC);

              ::ReleaseDC(NULL,hDC);

       }

       //创建位图文件  

       fh= CreateFile(_T("1.bmp"), GENERIC_WRITE,0, NULL, CREATE_ALWAYS,

              FILE_ATTRIBUTE_NORMAL| FILE_FLAG_SEQUENTIAL_SCAN, NULL);

       if(fh == INVALID_HANDLE_VALUE)   returnFALSE;

       //设置位图文件头

       bmfHdr.bfType= 0x4D42; // "BM"

       dwDIBSize= sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwPaletteSize +dwBmBitsSize;  

       bmfHdr.bfSize= dwDIBSize;

       bmfHdr.bfReserved1= 0;

       bmfHdr.bfReserved2= 0;

       bmfHdr.bfOffBits= (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER) +dwPaletteSize;

       //写入位图文件头

       WriteFile(fh,(LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);

       //写入位图文件其余内容

       WriteFile(fh,(LPSTR)lpbi, dwDIBSize, &dwWritten, NULL);

       //清除

       GlobalUnlock(hDib);

       GlobalFree(hDib);   

       CloseHandle(fh);

       returnTRUE;      

}

void show()

{

int height=400;

       intwidth =500;

       srand(100);

       A=(int*)malloc(sizeof(int)*width*height);

       for(int i=0;i<width;++i)

       {

              for(int j=0;j<height;++j)

              {

                     A[i*height+j]=rand()%255;

              }

       }

       DrawBmp(A,width,height);

  free(A);

}

0 0