现在的位置: 首页 > 综合 > 正文

VC_读写bmp方式

2014年01月31日 ⁄ 综合 ⁄ 共 3993字 ⁄ 字号 评论关闭

读写BMP图片的方式

1.加载bmp图片到bmp句柄

HBITMAP hBitmap;
 //hBitmap = (HBITMAP)::LoadImage(::AfxGetInstanceHandle(), "NetFriend.bmp", IMAGE_BITMAP, 0,0,LR_LOADFROMFILE|LR_CREATEDIBSECTION);//从文件中加载,
 hBitmap = (HBITMAP)::LoadImage(::AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_BITMAP1), IMAGE_BITMAP, 0,0,LR_CREATEDIBSECTION);//从资源文件中加载

2.获得bmp的信息头

BITMAP bm ;

GetObject(sizeof(BITMAP), &bm) ;

unsigned char *pc = new unsigned char[bm.bmheight * bm.bmWidthBytes];

GetBitmapBit(bm.bmheight * bm.bmWidthBytes, px) ;

3.生成数据信息

// A file is created, this is where we will save the screen capture.
     HANDLE hFile = CreateFile("d:\\My Documents\\桌面
\\66.bmp",
        GENERIC_WRITE,
        0,
        NULL,
        CREATE_ALWAYS,
        FILE_ATTRIBUTE_NORMAL, NULL);  
   
    // Add the size of the headers to the size of the bitmap to get the total file size
    DWORD dwSizeofDIB = dwBmpSize + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
 
    //Offset to where the actual bitmap bits start.
    bmfHeader.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER);

   
    //Size of the file
    bmfHeader.bfSize = dwSizeofDIB;
   
    //bfType must always be BM for Bitmaps
    bmfHeader.bfType = 0x4D42; //BM  
 
    DWORD dwBytesWritten = 0;
    WriteFile(hFile, (LPSTR)&bmfHeader, sizeof(BITMAPFILEHEADER), &dwBytesWritten, NULL);
    WriteFile(hFile, (LPSTR)&bi, sizeof(BITMAPINFOHEADER), &dwBytesWritten, NULL);
    WriteFile(hFile, (LPSTR)lpbitmap, dwBmpSize, &dwBytesWritten, NULL);
以下是参考资料:

GetBitmapBits和GetDIBits的区别(Windows GDI)

Windows GDI中有两个用来得到位图图像数据的API,分别是GetBitmapBits和GetDIBits;按照MSDN的解释,前者是用来得到设备独立位图的BITS,后者是得到兼容位图的BITS,所以在调用该函数的时候,第一个主要的区别是:GetDIBits需要提供一个设备内容,同时需要将位图的HANDLE选进这个设备内容(DC)才能能够得到位图的信息。
我想上面的区别大家可能都知道,其实它还隐藏着另一个区别:
就是对于同一个位图,得到的BITS内容的BUFFER不一样!
大家都知道BMP文件存储数据是倒叙的,也就是从图像的右下角开始存储,文件的最后是图像的左上角(这个来历可以看:WINDOWS编程中介绍);使用GetBitmapBits取得的BUFFER,位图的右下角的内容为第一个字节,实际上和真正的图像字节应该是一样的,而GetDIBits刚好相反,其BUFFER的顺序符合BMP文件中的顺序,如果按照正常的坐标,其存储顺序应该是倒叙。
所以在程序中要合理的使用这两个API来得到你想要的位图数据。

 

以下是自己写的测试通过的代码,参考了帮助文档

#if 1
 HBITMAP bitmap;
 BITMAP bm;
 
 bitmap=(HBITMAP)LoadImage(NULL,m_bmppath,IMAGE_BITMAP,0,0,LR_LOADFROMFILE|LR_CREATEDIBSECTION|LR_DEFAULTSIZE);

 GetObject(bitmap,   sizeof(BITMAP), &bm); 
 

 //unsigned char * ptrBuffer=new unsigned char [80];

 //tmp=GetBitmapBits(bitmap,80,ptrBuffer);
 //HDC hdcWindow;
 
    //hdcWindow =(HDC)GetDC();

 BITMAPFILEHEADER   bmfHeader;   
    BITMAPINFOHEADER   bi;
    
    bi.biSize = sizeof(BITMAPINFOHEADER);   
    bi.biWidth = bm.bmWidth;   
    bi.biHeight = bm.bmHeight; 
    bi.biPlanes = 1;   
    bi.biBitCount = 24;   
    bi.biCompression = BI_RGB;   
    bi.biSizeImage = 0; 
    bi.biXPelsPerMeter = 0;   
    bi.biYPelsPerMeter = 0;   
    bi.biClrUsed = 0;   
    bi.biClrImportant = 0;

    DWORD dwBmpSize = ((bm.bmWidth * bi.biBitCount + 31) / 32) * 4 * bm.bmHeight;

 HANDLE hDIB = GlobalAlloc(GHND,dwBmpSize);
    char *lpbitmap = (char *)GlobalLock(hDIB);   

    // Gets the "bits" from the bitmap and copies them into a buffer
    // which is pointed to by lpbitmap.
    GetDIBits(0, bitmap, 0,
        (UINT)bm.bmHeight,
        lpbitmap,
        (BITMAPINFO *)&bi, DIB_RGB_COLORS);
 
 GetBitmapBits(bitmap,dwBmpSize,lpbitmap);
 //GetBitmapBits(bitmap,dwBmpSize,lpbitmap);
 
  // A file is created, this is where we will save the screen capture.
     HANDLE hFile = CreateFile("d:\\My Documents\\桌面\\66.bmp",
        GENERIC_WRITE,
        0,
        NULL,
        CREATE_ALWAYS,
        FILE_ATTRIBUTE_NORMAL, NULL);  
   
    // Add the size of the headers to the size of the bitmap to get the total file size
    DWORD dwSizeofDIB = dwBmpSize + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
 
    //Offset to where the actual bitmap bits start.
    bmfHeader.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER);

   
    //Size of the file
    bmfHeader.bfSize = dwSizeofDIB;
   
    //bfType must always be BM for Bitmaps
    bmfHeader.bfType = 0x4D42; //BM  
 
    DWORD dwBytesWritten = 0;
    WriteFile(hFile, (LPSTR)&bmfHeader, sizeof(BITMAPFILEHEADER), &dwBytesWritten, NULL);
    WriteFile(hFile, (LPSTR)&bi, sizeof(BITMAPINFOHEADER), &dwBytesWritten, NULL);
    WriteFile(hFile, (LPSTR)lpbitmap, dwBmpSize, &dwBytesWritten, NULL);
   
    //Unlock and Free the DIB from the heap
    GlobalUnlock(hDIB);   
    GlobalFree(hDIB);

    //Close the handle for the file that was created
    CloseHandle(hFile);
#endif

 

抱歉!评论已关闭.