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

📄 dib.cpp

📁 一个相当好的摄影测量学的程序
💻 CPP
字号:
// DIB.cpp: implementation of the CDIB class.
//
//////////////////////////////////////////////////////////////////////

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

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

#define WIDTHBYTES(bits)  ((bits+31)/32*4)
#define RECTWIDTH(x) (x->right-x->left)
#define RECTHEIGHT(x) (x->bottom-x->top)

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CDIB::CDIB()
{

}

CDIB::~CDIB()
{

}

//每行像素所占用的字节数
WORD CDIB::BytePerLine(HANDLE hDIB)
{
	WORD i;
	LPBITMAPINFOHEADER lpbi;				//文件信息头指针
	lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
	i = WIDTHBYTES((lpbi->biWidth)*24);		//得到字节数
	GlobalUnlock(hDIB);
	return i;
}

HANDLE CDIB::ReadDIBFile(HANDLE hFile)
{
	BITMAPFILEHEADER bmfHeader;
	DWORD dwBitsSize;				//文件大小
	HANDLE hDIB;
	HANDLE hDIBtmp;
	LPBITMAPINFOHEADER lpbi;
	DWORD dwRead;
    //得到文件大小
	dwBitsSize = GetFileSize(hFile,NULL);
	hDIB =  GlobalAlloc(GMEM_MOVEABLE,(DWORD)(sizeof(BITMAPINFOHEADER)));

	if(!hDIB)
		return NULL;

	lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
	if(!lpbi)
	{
		GlobalFree(hDIB);
		return NULL;
	}
	
	if(!ReadFile(hFile,(LPBYTE)&bmfHeader,sizeof(BITMAPFILEHEADER),&dwRead,NULL))
		goto ErrExit;
	if(sizeof(BITMAPFILEHEADER)!=dwRead)//读取文件出错
		goto ErrExit;
	if(bmfHeader.bfType != 0x4d42)//文件类型不匹配
		goto ErrExit;
	if(!ReadFile(hFile,(LPBYTE)lpbi,sizeof(BITMAPINFOHEADER),&dwRead,NULL))
		goto ErrExit;
	if(sizeof(BITMAPINFOHEADER)!= dwRead)//读取数据出错
		goto ErrExit;

	GlobalUnlock(hDIB);
	if(lpbi->biSizeImage==0)			//真彩色图像
		lpbi->biSizeImage = (this->BytePerLine(hDIB))*lpbi->biHeight;	//计算得到图像的数据大小
	hDIBtmp = GlobalReAlloc(hDIB,lpbi->biSize+lpbi->biSizeImage,0);
	if(!hDIBtmp)
		goto ErrExitNoUnlock;
	else
		hDIB = hDIBtmp;
	lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
	//根据情况设定文件指针
	if(bmfHeader.bfOffBits != 0L)
		SetFilePointer(hFile,bmfHeader.bfOffBits,NULL,FILE_BEGIN);
    //读取文件的象素颜色数据
	if(ReadFile(hFile,(LPBYTE)lpbi+lpbi->biSize,lpbi->biSizeImage,&dwRead,NULL))
			goto OKExit;
	
	ErrExit:
		GlobalUnlock(hDIB);
	
	ErrExitNoUnlock:
		GlobalFree(hDIB); //释放内存
		return NULL;

	OKExit:
		GlobalUnlock(hDIB);
		return hDIB;
}

HANDLE CDIB::LoadDIB(LPCTSTR lpFileName)
{
	HANDLE hDIB;
	HANDLE hFile;
	//创建文件句柄
	if((hFile = CreateFile(lpFileName,
							GENERIC_READ,
							FILE_SHARE_READ,
							NULL,
							OPEN_EXISTING,
							FILE_ATTRIBUTE_NORMAL|FILE_FLAG_SEQUENTIAL_SCAN,NULL))!= INVALID_HANDLE_VALUE)
	{  
		//读取数据
		hDIB = ReadDIBFile(hFile);
		//关闭文件句柄
		CloseHandle(hFile);
		return hDIB;
	}
	return NULL;
}

BOOL CDIB::SaveDIB(HANDLE hDib, LPCTSTR lpFileName)
{
    BITMAPFILEHEADER    bmfHdr;     // Header for Bitmap file 
    LPBITMAPINFOHEADER  lpBI;       // Pointer to DIB info structure 
    HANDLE              fh;         // file handle for opened file 
    DWORD               dwDIBSize; 
    DWORD               dwWritten; 
 
    if (!hDib) 
        return FALSE; 
 
    fh = CreateFile(lpFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 
            FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); 
 
    if (fh == INVALID_HANDLE_VALUE) 
        return FALSE; 
 
    // Get a pointer to the DIB memory, the first of which contains 
    // a BITMAPINFO structure 
 
    lpBI = (LPBITMAPINFOHEADER)GlobalLock(hDib); 
    if (!lpBI) 
    { 
        CloseHandle(fh); 
        return FALSE; 
    } 
 
    // Check to see if we're dealing with an OS/2 DIB.  If so, don't 
    // save it because our functions aren't written to deal with these 
    // DIBs. 
 
    if (lpBI->biSize != sizeof(BITMAPINFOHEADER)) 
    { 
        GlobalUnlock(hDib); 
        CloseHandle(fh); 
        return FALSE; 
    } 
 
    // Fill in the fields of the file header 
 
    // Fill in file type (first 2 bytes must be "BM" for a bitmap) 
 
    bmfHdr.bfType = 0x4d42;  // "BM" 
 
    // Calculating the size of the DIB is a bit tricky (if we want to 
    // do it right).  The easiest way to do this is to call GlobalSize() 
    // on our global handle, but since the size of our global memory may have 
    // been padded a few bytes, we may end up writing out a few too 
    // many bytes to the file (which may cause problems with some apps, 
    // like HC 3.0). 
    // 
    // So, instead let's calculate the size manually. 
    // 
    // To do this, find size of header plus size of color table.  Since the 
    // first DWORD in both BITMAPINFOHEADER and BITMAPCOREHEADER conains 
    // the size of the structure, let's use this. 
 
    // Partial Calculation 
 
    dwDIBSize = *(LPDWORD)lpBI;// + DIBNumColors((LPBYTE)lpBI) * sizeof(RGBQUAD);   
 
    // Now calculate the size of the image 
 
    // It's an RLE bitmap, we can't calculate size, so trust the biSizeImage 
    // field 
 
    if ((lpBI->biCompression == BI_RLE8) || (lpBI->biCompression == BI_RLE4)) 
        dwDIBSize += lpBI->biSizeImage; 
    else 
    { 
        DWORD dwBmBitsSize;  // Size of Bitmap Bits only 
 
        // It's not RLE, so size is Width (DWORD aligned) * Height 
 
        dwBmBitsSize = WIDTHBYTES((lpBI->biWidth)*((DWORD)lpBI->biBitCount)) * 
                lpBI->biHeight; 
 
        dwDIBSize += dwBmBitsSize; 
 
        // Now, since we have calculated the correct size, why don't we 
        // fill in the biSizeImage field (this will fix any .BMP files which  
        // have this field incorrect). 
 
        lpBI->biSizeImage = dwBmBitsSize; 
    } 
 
 
    // Calculate the file size by adding the DIB size to sizeof(BITMAPFILEHEADER) 
                    
    bmfHdr.bfSize = dwDIBSize + sizeof(BITMAPFILEHEADER); 
    bmfHdr.bfReserved1 = 0; 
    bmfHdr.bfReserved2 = 0; 
 
    // Now, calculate the offset the actual bitmap bits will be in 
    // the file -- It's the Bitmap file header plus the DIB header, 
    // plus the size of the color table. 
     
    bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + lpBI->biSize;/* + 
            DIBNumColors((LPBYTE)lpBI) * sizeof(RGBQUAD); */
 
    // Write the file header 
 
    WriteFile(fh, (LPBYTE)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL); 
 
    // Write the DIB header and the bits -- use local version of 
    // MyWrite, so we can write more than 32767 bytes of data 
     
    WriteFile(fh, (LPBYTE)lpBI, dwDIBSize, &dwWritten, NULL); 
 
    GlobalUnlock(hDib); 
    CloseHandle(fh); 
 
    if (dwWritten == 0) 
        return FALSE; // oops, something happened in the write 
    else 
        return TRUE; // Success code 
}

BOOL CDIB::PaintDIBTrue(HDC hDC, LPRECT lpDCRect, HANDLE hDIB, LPRECT lpDIBRect, DWORD dwRop)
{
	LPBYTE lpDIBHdr;
	LPBYTE lpDIBBits;
	BOOL bSuccess = FALSE;

	if(!hDIB)
		return FALSE;
	lpDIBHdr = (LPBYTE)GlobalLock(hDIB);
	lpDIBBits = lpDIBHdr + sizeof(BITMAPINFOHEADER);	//指向图像数据
	bSuccess = StretchDIBits(hDC,lpDCRect->left,
								 lpDCRect->top,
								 RECTWIDTH(lpDCRect),
								 RECTHEIGHT(lpDCRect),
								 lpDIBRect->left,
								 ((LPBITMAPINFOHEADER)lpDIBHdr)->biHeight-lpDIBRect->top-RECTHEIGHT(lpDIBRect),
								 RECTWIDTH(lpDIBRect),
								 RECTHEIGHT(lpDIBRect),
								 lpDIBBits,
								 (LPBITMAPINFO)lpDIBHdr,
								 DIB_RGB_COLORS,
								 SRCCOPY);
	GlobalUnlock(hDIB);
	return bSuccess;
}

long CDIB::PixelOffset(int i, int j, WORD wBytesPerLine)
{
	long Offset;
	Offset=i*wBytesPerLine+j*3;				//计算偏移
	return Offset;
}

long CDIB::PixelOffsetEP(int i, int j, int height, WORD wBytesPerLine)
{
	long Offset;
	Offset=(height-j-1)*wBytesPerLine+i*3;				//计算偏移
	return Offset;
}

HDIB CDIB::ToGray(HANDLE hDIB)
{
	HDIB hNewDIB=NULL;
	LPBITMAPINFOHEADER lpSrc,lpDest;
	LPBYTE lpS,lpD;
	DWORD dwBytesPerLine;
	DWORD dwImgSize;
	WORD wBytesPerLine;
	unsigned i,j,height,width;
	if(!hDIB)
		return NULL;
	lpSrc=(LPBITMAPINFOHEADER)GlobalLock(hDIB);
    dwBytesPerLine = WIDTHBYTES(24*(lpSrc->biWidth));	//每行图像占用的位数
	dwImgSize=lpSrc->biHeight*dwBytesPerLine;			//图像数据大小
	hNewDIB=GlobalAlloc(GHND,sizeof(BITMAPINFOHEADER)+dwImgSize);
	lpDest=(LPBITMAPINFOHEADER)GlobalLock(hNewDIB);
	memcpy((void*)lpDest,(void*)lpSrc,sizeof(BITMAPINFOHEADER));
	DWORD dwSBytesPerLine;
	dwSBytesPerLine=(24*(lpSrc->biWidth)+31)/32*4;		//每行图像占用的字节数
	height=lpDest->biHeight;
	width=lpDest->biWidth;
	lpS=(LPBYTE)lpSrc;
	wBytesPerLine=this->BytePerLine(hDIB);
	lpD=(LPBYTE)lpDest;
	lpS=lpS+sizeof(BITMAPINFOHEADER);
	lpD=lpD+sizeof(BITMAPINFOHEADER);
	unsigned r,g,b,gray;
	for(i=0;i<height;i++)
	{
		for(j=0;j<(unsigned)lpDest->biWidth;j++)
		{
			r=*(lpS++); 
			g=*(lpS++);
			b=*(lpS++);
			gray=(g*50+r*39+b*11)/100;
			*(lpD++)=gray;
			*(lpD++)=gray;
			*(lpD++)=gray;
		}
	//处理四字节对齐问题
		unsigned k;
		for(k=0;k<dwSBytesPerLine-lpSrc->biWidth*3;k++)
		{
			lpS++;
			lpD++;
		}
	}
	GlobalUnlock(hDIB);
	GlobalUnlock(hNewDIB);
	return hNewDIB;
}

HANDLE CDIB::WB(HANDLE hDIB, int Value)
{
	HANDLE hDib;
    hDib=(HANDLE)ToGray(hDIB);

	LPBITMAPINFOHEADER lpbi;
	LPBYTE lpS;
	

	int width,height;
	long lOffset;

	WORD wBytesPerLine=BytePerLine(hDib);

	lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
	width=lpbi->biWidth;
	height=lpbi->biHeight;
	
	lpS=(LPBYTE)lpbi;
	lpS=lpS+sizeof(BITMAPINFOHEADER);
	for(int i=0;i<height;i++)
		for(int j=0;j<width;j++)
		{
			lOffset=this->PixelOffset(i,j,wBytesPerLine);
			if(*(lpS+lOffset)<Value)
			{
				*(lpS+lOffset++)=0;
				*(lpS+lOffset++)=0;
				*(lpS+lOffset)=0;
			}
			else
			{
				*(lpS+lOffset++)=255;
				*(lpS+lOffset++)=255;
				*(lpS+lOffset)=255;
			}
		}
		
	GlobalUnlock(hDib);
	return hDib;
}

⌨️ 快捷键说明

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