?? dib.cpp
字號:
// DIB.cpp: implementation of the DIB class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "DIB.h"
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
///////////////////////////////我的定義///////////////////////////////////
#define DIB_HEADER_MARKER ((WORD) ('M' << 8) | 'B')
#define WIDTHBYTES(bits) ((((bits) + 31)>>5)<<2)
#define IS_WIN30_DIB(lpbi) ((*(LPDWORD)(lpbi)) == sizeof(BITMAPINFOHEADER))
struct DIBINFO : public BITMAPINFO
{
RGBQUAD arColors[255]; // Color table info - adds an extra 255 entries to palette
operator LPBITMAPINFO() { return (LPBITMAPINFO) this; }
operator LPBITMAPINFOHEADER() { return &bmiHeader; }
RGBQUAD* ColorTable() { return bmiColors; }
};
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
DIB::DIB()
{
}
DIB::~DIB()
{
}
/**************************************************************************************
函數(shù)名:
SaveDIBToFile 保存DIB到文件
參數(shù):
LPSTR hDib 指向DIB數(shù)據(jù)的指針,(BYTE)
LPCTSTR szFileName 文件全名,(包括路徑)
返回值:
失敗返回 FALSE 否則 返回 TRUE
**************************************************************************************/
BOOL DIB::SaveDIBToFile(LPSTR hDib)
{
// CFileDialog FileDlg(FALSE,_T("BMP"),_T("*.bmp"),OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,_T("*.bmp|*.bmp|*.*|*.*|"));
// if(FileDlg.DoModal()!=IDOK)
// return FALSE;
// LPCTSTR szFileName=(LPCTSTR)FileDlg.GetPathName();
HANDLE ghFile=NULL;
BOOL bResult=FALSE;
// Bitmap文件頭
BITMAPFILEHEADER bmfHdr;
// 指向BITMAPINFOHEADER的指針
LPBITMAPINFOHEADER lpBI=NULL;
// DIB大小
DWORD dwDIBSize=0;
DWORD dwBytes=0;
if (hDib == NULL)
{
return FALSE;
}
// 讀取BITMAPINFO結(jié)構(gòu),并鎖定
lpBI=(LPBITMAPINFOHEADER)hDib;
if (lpBI == NULL)
{
return FALSE;
}
// 判斷是否是WIN3.0 DIB
if (!IS_WIN30_DIB(lpBI))
{
// 返回FALSE
return FALSE;
}
// 文件類型"BM"
bmfHdr.bfType = DIB_HEADER_MARKER;
// 文件頭大小+顏色表大小
// (BITMAPINFOHEADER和BITMAPCOREHEADER結(jié)構(gòu)的第一個DWORD都是該結(jié)構(gòu)的大小)
dwDIBSize = *(LPDWORD)lpBI + 0;//最后參數(shù)0表示是24位位圖無調(diào)色板
// 計算圖像大小
// 象素的大小
DWORD dwBmBitsSize;
// 大小為Width * Height
dwBmBitsSize = WIDTHBYTES((lpBI->biWidth)*((DWORD)lpBI->biBitCount)) * lpBI->biHeight;
// 計算出DIB真正的大小
dwDIBSize += dwBmBitsSize;
// 更新biSizeImage(很多BMP文件頭中biSizeImage的值是錯誤的,對于24位位圖來說,這里也可以為0)
lpBI->biSizeImage = dwBmBitsSize;
// 計算文件大小:DIB大小+BITMAPFILEHEADER結(jié)構(gòu)大小
bmfHdr.bfSize = dwDIBSize + sizeof(BITMAPFILEHEADER);
// 兩個保留字
bmfHdr.bfReserved1 = 0;
bmfHdr.bfReserved2 = 0;
// 計算偏移量bfOffBits,它的大小為Bitmap文件頭大小+DIB頭大小+顏色表大小
bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + lpBI->biSize
+ 0;//最后參數(shù)0表示是24位位圖無調(diào)色板
//打開文件
ghFile=CreateFile(szFileName, GENERIC_WRITE|GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (ghFile==INVALID_HANDLE_VALUE)
{
//NKDbgPrintfW(_T("save dib to file fail. \r\n"));
return FALSE;
}
//寫文件頭
bResult=WriteFile(ghFile,(LPSTR)&bmfHdr,sizeof(BITMAPFILEHEADER),&dwBytes,NULL);
ASSERT(bResult!=FALSE);
// 寫DIB頭和象素
bResult=WriteFile(ghFile,(LPSTR)lpBI,dwDIBSize,&dwBytes,NULL);
ASSERT(bResult!=FALSE);
CloseHandle(ghFile);
// 返回TRUE
return TRUE;
}
/**************************************************************************************
函數(shù)名:
GettingBits 通過圖像句柄得到DIB圖像數(shù)據(jù)
參數(shù):
HBITMAP hSourceBitmap 圖像句柄
返回值:
LPSTR lpDIB DIB 指針
說明: 源句柄需要在函數(shù)外部刪除。
**************************************************************************************/
LPSTR DIB::GettingBits(HBITMAP hSourceBitmap)
{
LPSTR lpDIB=NULL;
//1. Initialize source bitmap. For example load from resources.
//HBITMAP hSourceBitmap = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_BITMAP1));
//2. Getting bimap size.
BITMAP bm;
GetObject(hSourceBitmap, sizeof(BITMAP), &bm);
lpDIB=(LPSTR)LocalAlloc(LPTR,bm.bmHeight*WIDTHBYTES(bm.bmWidth*24)+40);
if(lpDIB==NULL)
{
return NULL;
}
//3. Creating new bitmap and receive pointer to it's bits.
HBITMAP hTargetBitmap;
void *pBuffer;
//3.1 Initilize DIBINFO structure
DIBINFO dibInfo;
dibInfo.bmiHeader.biBitCount = 24;
dibInfo.bmiHeader.biClrImportant = 0;
dibInfo.bmiHeader.biClrUsed = 0;
dibInfo.bmiHeader.biCompression = 0;
dibInfo.bmiHeader.biHeight = bm.bmHeight;
dibInfo.bmiHeader.biPlanes = 1;
dibInfo.bmiHeader.biSize = 40;
dibInfo.bmiHeader.biSizeImage = WIDTHBYTES(bm.bmWidth*24)*bm.bmHeight;
dibInfo.bmiHeader.biWidth = bm.bmWidth;
dibInfo.bmiHeader.biXPelsPerMeter = 3780;
dibInfo.bmiHeader.biYPelsPerMeter = 3780;
dibInfo.bmiColors[0].rgbBlue = 0;
dibInfo.bmiColors[0].rgbGreen = 0;
dibInfo.bmiColors[0].rgbRed = 0;
dibInfo.bmiColors[0].rgbReserved = 0;
//3.2 Create bitmap and receive pointer to points into pBuffer
HDC hDC = ::GetDC(NULL);
ASSERT(hDC);
hTargetBitmap = CreateDIBSection(
hDC,
(const BITMAPINFO*)dibInfo,
DIB_RGB_COLORS,
(void**)&pBuffer,
NULL,
0);
::ReleaseDC(NULL, hDC);
//4. Copy source bitmap into the target bitmap.
//4.1 Create 2 device contexts
HDC memDc;
memDc=CreateCompatibleDC(NULL);
ASSERT(memDc!=NULL);
HDC targetDc;
targetDc=CreateCompatibleDC(NULL);
ASSERT(targetDc!=NULL);
//4.2 Select source bitmap into one DC, target into another
HBITMAP hOldBitmap1 = (HBITMAP)::SelectObject(memDc, hSourceBitmap);
HBITMAP hOldBitmap2 = (HBITMAP)::SelectObject(targetDc, hTargetBitmap);
//4.3 Copy source bitmap into the target one
BitBlt(targetDc,0, 0, bm.bmWidth, bm.bmHeight, memDc, 0, 0, SRCCOPY);
//4.4 Restore device contexts
::SelectObject(memDc, hOldBitmap1);
::SelectObject(targetDc, hOldBitmap2);
DeleteDC(memDc);
DeleteDC(targetDc);
//Here we can bitmap bits: pBuffer. Note:
// 1. pBuffer contains 3 bytes per point
// 2. Lines ane from the bottom to the top!
// 3. Points in the line are from the left to the right
// 4. Bytes in one point are BGR (blue, green, red) not RGB
// 5. Don't delete pBuffer, it will be automatically deleted
// when delete hTargetBitmap
LPSTR lptmp=lpDIB;
CopyMemory(lptmp,&dibInfo.bmiHeader,40);
lptmp+=40;
CopyMemory(lptmp,pBuffer,dibInfo.bmiHeader.biSizeImage);
// DeleteObject(hSourceBitmap);
DeleteObject(hTargetBitmap);
return lpDIB;
}
//CopyScreenToDIB,直接轉(zhuǎn)換為DIB數(shù)據(jù)
HBITMAP DIB::CopyScreenToBitmap(HWND hPic, LPRECT lpRect)
{
int nWidth, nHeight;
HDC hScrDC;
HDC hMemDC;
// 屏幕和內(nèi)存設(shè)備描述表
HBITMAP hBitmap;
HBITMAP hOldBitmap;
// 選定區(qū)域坐標(biāo)
int nX, nY, nX2, nY2;
// 位圖寬度和高度
// int nWidth, nHeight;
// 屏幕分辨率
int xScrn, yScrn;
// 確保選定區(qū)域不為空矩形
if (IsRectEmpty(lpRect))
return NULL;
//為屏幕創(chuàng)建設(shè)備描述表
//hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL);
//這里如果使用DISPLAY設(shè)備DC的話
//也許會更有趣:)。
hScrDC = GetDC(hPic);
//為屏幕設(shè)備描述表創(chuàng)建兼容的內(nèi)存設(shè)備描述表
hMemDC = CreateCompatibleDC(hScrDC);
// 獲得選定區(qū)域坐標(biāo)
nX = lpRect->left;
nY = lpRect->top;
nX2 = lpRect->right;
nY2 = lpRect->bottom;
// 獲得屏幕分辨率
RECT rc1;
GetWindowRect(hPic,&rc1);
// xScrn = GetDeviceCaps(hScrDC, HORZRES);
xScrn=rc1.right-rc1.left;
// yScrn = GetDeviceCaps(hScrDC, VERTRES);
yScrn=rc1.bottom-rc1.top;
//確保選定區(qū)域是可見的
if (nX < 0)
nX = 0;
if (nY < 0)
nY = 0;
if (nX2 > xScrn)
nX2 = xScrn;
if (nY2 > yScrn)
nY2 = yScrn;
nWidth=nX2 - nX;
nHeight=nY2 - nY;
// 創(chuàng)建一個與屏幕設(shè)備描述表兼容的位圖
hBitmap = CreateCompatibleBitmap(hScrDC, nWidth, nHeight);
// 把新位圖選到內(nèi)存設(shè)備描述表中
hOldBitmap = (HBITMAP)SelectObject(hMemDC,hBitmap);
// 把屏幕設(shè)備描述表拷貝到內(nèi)存設(shè)備描述表中
BitBlt(hMemDC, 0, 0, nWidth, nHeight,hScrDC, nX, nY, SRCCOPY);
//得到屏幕位圖的句柄
hBitmap=(HBITMAP)SelectObject(hMemDC, hOldBitmap);
//清除
ReleaseDC(hPic,hScrDC);
DeleteDC(hMemDC);
// 返回位圖句柄
return hBitmap;
}
///////////////////////////////////////////////////////////////////
HBITMAP DIB::DIBLoaditmap()
{
CString lpszFileName;
HBITMAP hBitmap;
TCHAR szFileter[] = _T("BMP Files(*.BMP)|*.BMP||*.* Files(*.*)|*.*||");
CFileDialog FileDlg(TRUE,NULL,NULL,OFN_HIDEREADONLY,szFileter);
if(FileDlg.DoModal()!=IDOK)
return NULL;
lpszFileName=FileDlg.GetPathName();
DeleteObject(hBitmap);
hBitmap=SHLoadDIBitmap(lpszFileName);
return hBitmap;
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -