⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dib.cpp

📁 一个基于PXA255的水情遥测、遥控系统现场服务器软件
💻 CPP
字号:
// DIB.cpp: implementation of the DIB class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "DIB.h"

#ifdef _DEBUG
#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()
{

}




/**************************************************************************************
  函数名:
  SaveDIBToFile			  保存DIB到文件	

  参数:
  LPSTR   hDib                    指向DIB数据的指针,(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结构,并锁定

	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结构的第一个DWORD都是该结构的大小)
	dwDIBSize = *(LPDWORD)lpBI + 0;//最后参数0表示是24位位图无调色板
	
	// 计算图像大小
	// 象素的大小
	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结构大小
	bmfHdr.bfSize = dwDIBSize + sizeof(BITMAPFILEHEADER);
	
	// 两个保留字
	bmfHdr.bfReserved1 = 0;
	bmfHdr.bfReserved2 = 0;
	
	// 计算偏移量bfOffBits,它的大小为Bitmap文件头大小+DIB头大小+颜色表大小
	bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + lpBI->biSize
		+ 0;//最后参数0表示是24位位图无调色板

	//打开文件
	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;
}

/**************************************************************************************
  
  函数名:
  GettingBits			  通过图像句柄得到DIB图像数据

  参数:
  HBITMAP hSourceBitmap           图像句柄                

  返回值:

  LPSTR lpDIB                     DIB 指针

  说明:                          源句柄需要在函数外部删除。

**************************************************************************************/
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,直接转换为DIB数据
HBITMAP DIB::CopyScreenToBitmap(HWND hPic, LPRECT lpRect)
{
	int       nWidth, nHeight; 
	HDC		   hScrDC;
	HDC		   hMemDC;      
	// 屏幕和内存设备描述表
	
	HBITMAP		hBitmap; 
	HBITMAP		hOldBitmap;   

	// 选定区域坐标
	int       nX, nY, nX2, nY2; 
	
	// 位图宽度和高度
//	int       nWidth, nHeight;  
    
	// 屏幕分辨率
	int       xScrn, yScrn;     

        // 确保选定区域不为空矩形
	if (IsRectEmpty(lpRect))	
		return NULL;
	//为屏幕创建设备描述表
	
	//hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL); 
	//这里如果使用DISPLAY设备DC的话
	//也许会更有趣:)。
	hScrDC = GetDC(hPic);
	//为屏幕设备描述表创建兼容的内存设备描述表
	hMemDC = CreateCompatibleDC(hScrDC);
	// 获得选定区域坐标
	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;
	//确保选定区域是可见的
	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;
	// 创建一个与屏幕设备描述表兼容的位图
	hBitmap = CreateCompatibleBitmap(hScrDC, nWidth, nHeight);
	// 把新位图选到内存设备描述表中
	hOldBitmap = (HBITMAP)SelectObject(hMemDC,hBitmap);
	// 把屏幕设备描述表拷贝到内存设备描述表中
	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;

}






⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -