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

📄 dibapi.cpp

📁 vc++实现简单图像编辑器。。。。。。。。。
💻 CPP
📖 第 1 页 / 共 5 页
字号:
*                                                   
*   Return Value:                                 
*                                                   
*   A handle to DIB data buffer, or null if unsuccessful                  
*                                                   
*   Description:                                  
*                                                   
*   This function  reads in the DIB file into a global chuck
*   of memory.                 
*
************************************************************/

HDIB ReadDIBFile(HANDLE hFile)
{

	BITMAPFILEHEADER bmfHeader;
	DWORD dwBitsSize;
	UINT nNumColors;//number of colors in table
	HDIB hDIB;
	HDIB hDIBtmp;// used for global realloc()
	LPBITMAPINFOHEADER lpbi;
	DWORD offBits;
	DWORD dwRead;

	//get length of DIB in bytes for use when reading

	dwBitsSize=GetFileSize(hFile,NULL);

	//Allocate memory for header &color table, We 'll 
	//enlarge this memory as needed

	hDIB=GlobalAlloc(GMEM_MOVEABLE,
		             (DWORD)(sizeof(BITMAPINFOHEADER)+
					 256*sizeof(RGBQUAD)));
	if (!hDIB)
		return NULL;
	lpbi=(LPBITMAPINFOHEADER)GlobalLock(hDIB);
	if(!lpbi)
	{
		GlobalFree(hDIB);
		return NULL;
	}
	//read the BITMAPFILEHEADER from our file

	if(!ReadFile(hFile,
		         (LPBYTE) &bmfHeader,
				 sizeof(BITMAPFILEHEADER),
				 &dwRead,
				 NULL))
		goto ErrExit;
	

	if(sizeof(BITMAPFILEHEADER)!=dwRead)
		goto ErrExit;


	if(bmfHeader.bfType !=0x4d42)//"BM"
		goto ErrExit;

	//read the BITMAPINFOHEADER

	if(!ReadFile(hFile,
		(LPBYTE)lpbi,
		sizeof(BITMAPINFOHEADER),
		&dwRead,
		NULL))
	    goto ErrExit;

	if (sizeof(BITMAPINFOHEADER)!=dwRead)
		goto ErrExit;

	//check to see that it's a windows DIB--an os/2 DIB would
	// cause strange problems with the rest of the DIB API
    // since the file in the header are different and the color 
	//table entried are smaller

	// if it is not a window DIB, return NULL

	if (lpbi->biSize ==sizeof(BITMAPCOREHEADER))
		goto ErrExit;

	//Now determine the size of the color table and read it ,Since
	//the bitmap bits are offset in the file by bfoggbits,we need to
	//do some special processing here to make sure the bits directly
	//follow the color table because that's the format we are susposed
	// to pass back

	if (!(nNumColors=(UINT)lpbi->biClrUsed ))
	{
		//no color table for 24-bit, default size otherwise

		if (lpbi->biBitCount !=24)
			nNumColors=1<<lpbi->biBitCount ;//stardard size table
	}

	//fill in some default values if they are zero

	if(lpbi->biClrUsed  ==0)
		lpbi->biClrUsed=nNumColors;

	if(lpbi->biSizeImage ==0)
	{
		lpbi->biSizeImage =((((lpbi->biWidth *
			(DWORD)lpbi->biBitCount )+31)&~31)>>3)*lpbi->biHeight ;
	}

	//get the proper sized buffer for header,color table and bits

	GlobalUnlock(hDIB);

	hDIBtmp=GlobalReAlloc(hDIB,lpbi->biSize +nNumColors*
		sizeof(RGBQUAD)+lpbi->biSizeImage ,0);

	if(!hDIBtmp)//can't resize buffer for loading
		goto ErrExitUnlock;
	else
		hDIB=hDIBtmp;
	lpbi=(LPBITMAPINFOHEADER)GlobalLock(hDIB);

	//read the color table
	ReadFile(hFile,(LPBYTE)(lpbi)+lpbi->biSize,
		     nNumColors*sizeof(RGBQUAD),&dwRead,NULL);

	//offset to the bits from start of DIB header

	offBits=lpbi->biSize +nNumColors*sizeof(RGBQUAD);

	//If the bfOffBits field is none zero, then the bits might not
	// be directly following the color table in the file,Use the value
	//in bfOffBits to seek the bits
	if(bmfHeader.bfOffBits !=0L)
		SetFilePointer(hFile,bmfHeader.bfOffBits ,NULL,FILE_BEGIN);
	
	if(ReadFile(hFile,(LPBYTE)lpbi+offBits,lpbi->biSizeImage,
		        &dwRead,NULL))
		goto OKExit;

ErrExit:
	GlobalUnlock(hDIB);

ErrExitUnlock:
	GlobalFree(hDIB);
	return NULL;
OKExit:
	GlobalUnlock(hDIB);
	return hDIB;
}
/************************************************************
*                                                   
*   Function Name:                                 
*                                                   
*   SaveDIB()                                  
*                                                 
*   Parameters :                                  
*                                                  
*   HANDLE hDIB:  -handle of the DIB to save
*   LPTSTR lpFileName:-specifies the file to save the DIB to       
*                                                   
*   Return Value:                                 
*                                                   
*   TRUE if successful, or FALSE if unsuccessful                  
*                                                   
*   Description:                                  
*                                                   
*   This function  Save the specified DIB into a bitmap File
*   name on disk  
*
************************************************************/
BOOL SaveDIB(HDIB hDib, LPCTSTR lpFileName)
{
	BITMAPFILEHEADER bmfHdr;//Header for Bitmap FIle
	LPBITMAPINFOHEADER lpBI;//pointer to DIB infor 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 contails
	// a BITMAPINFO structure

	lpBI=(LPBITMAPINFOHEADER)GlobalLock(hDib);
	if(!lpBI)
	{
		GlobalUnlock(hDib);
		CloseHandle(fh);
		return FALSE;
	}

	//check to see if we'are dealing with an OS/2 DIB. if so,
	//don't save it because our functions aren't written to
	//deal with this DIBs

	if(lpBI->biSize !=sizeof(BITMAPINFOHEADER))
	{
		GlobalUnlock(hDib);
		CloseHandle(fh);
		return FALSE;
	}

	//Fill in the fields of the file header
	//Fill in the file type (first 2bytes must be "BM" for 
	//a Bitmap

	bmfHdr.bfType =DIB_HEADER_MARKER;//"BM"

	//calculating the size of the DIB is a bit trickly(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 uup writing out a 
	//few too many bytes to the file(which may vause 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 contains 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 butmap,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
		// fill in the biSizeImage field

		lpBI->biSizeImage =dwBmBitsSize;
	}

	//calculate the file size by adding the DIB size to
	//size of (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 tje 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 happend in the write
	else
		return TRUE;//success code
}

/************************************************************
*                                                   
*   Function Name:                                 
*                                                   
*   BytesPerLine()                                  
*                                                 
*   Parameters :                                  
*                                                  
*   LPBYTE  lpDIB:  -pointer to packed -DIB memory block
*                                                   
*   Return Value:                                 
*                                                   
*   DWORD  -number of bytes in one scan line                  
*                                                   
*   Description:                                  
*                                                   
*   This function  calculates the number of bytes  in one
*   scan line
*
************************************************************/
DWORD BytesPerLine(LPBYTE lpDIB)
{
	//计算每行需要的字节数
	return WIDTHBYTES(((LPBITMAPINFOHEADER)lpDIB)->biWidth *
		((LPBITMAPINFOHEADER)lpDIB)->biPlanes *
		((LPBITMAPINFOHEADER)lpDIB)->biBitCount );
}
/************************************************************
*                                                   
*   Function Name:                                 
*                                                   
*   BytesPerLine()                                  
*                                                 
*   Parameters :                                  
*                                                  
*   HANDLE hDIB:  -handle of the DIB 
*                                                   
*   Return Value:                                 
*                                                   
*   DWORD  -number of bytes in one scan line                  
*                                                   
*   Description:                                  
*                                                   
*   This function  calculates the number of bytes  in one
*   scan line
*
************************************************************/
DWORD BytesPerLine(HDIB hDIB)
{
	LPBITMAPINFOHEADER lpDIB;

	lpDIB=(LPBITMAPINFOHEADER)GlobalLock(hDIB);
	DWORD dwBytes= WIDTHBYTES(((LPBITMAPINFOHEADER)lpDIB)->biWidth *
		((LPBITMAPINFOHEADER)lpDIB)->biPlanes *
		((LPBITMAPINFOHEADER)lpDIB)->biBitCount );
	GlobalUnlock(hDIB);
	return dwBytes;
}

/************************************************************
*                                                   
*   Function Name:                                 
*                                                   
*   DIBLockSize()                                  
*                                                 
*   Parameters :                                  
*                                                  
*   LPBYTE  lpDIB:  -pointer to packed -DIB memory block
*                                                      
*   Return Value:                                 
*                                                   
*   DWORD -DIB block size                  
*                                                   
*   Description:                                  
*                                                   
*   This function  calculates the block size of image bit  
*

⌨️ 快捷键说明

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