dibapi.cpp

来自「图像处理软件,功能比较基础」· C++ 代码 · 共 1,120 行 · 第 1/3 页

CPP
1,120
字号
   if (IS_WIN30_DIB (lpbi))
	  return (WORD)(::DIBNumColors(lpbi) * sizeof(RGBQUAD));
   else
	  return (WORD)(::DIBNumColors(lpbi) * sizeof(RGBTRIPLE));
}


/*************************************************************************
 *
 * DIBNumColors()
 *
 * Parameter:
 *
 * LPSTR lpbi       - pointer to packed-DIB memory block
 *
 * Return Value:
 *
 * WORD             - number of colors in the color table
 *
 * Description:
 *
 * This function calculates the number of colors in the DIB's color table
 * by finding the bits per pixel for the DIB (whether Win3.0 or other-style
 * DIB). If bits per pixel is 1: colors=2, if 4: colors=16, if 8: colors=256,
 * if 24, no colors in color table.
 *
 ************************************************************************/


WORD WINAPI DIBNumColors(LPSTR lpbi)
{
	WORD wBitCount;  // DIB bit count

	/*  If this is a Windows-style DIB, the number of colors in the
	 *  color table can be less than the number of bits per pixel
	 *  allows for (i.e. lpbi->biClrUsed can be set to some value).
	 *  If this is the case, return the appropriate value.
	 */
/*
	if (IS_WIN30_DIB(lpbi))
	{
		DWORD dwClrUsed;

		dwClrUsed = ((LPBITMAPINFOHEADER)lpbi)->biClrUsed;
		if (dwClrUsed != 0)
			return (WORD)dwClrUsed;
	}
*/
	/*  Calculate the number of colors in the color table based on
	 *  the number of bits per pixel for the DIB.
	 */
	if (IS_WIN30_DIB(lpbi))
		wBitCount = ((LPBITMAPINFOHEADER)lpbi)->biBitCount;
	else
		wBitCount = ((LPBITMAPCOREHEADER)lpbi)->bcBitCount;

	/* return number of colors based on bits per pixel */
	switch (wBitCount)
	{
		case 1:
			return 2;

		case 4:
			return 16;

		case 8:
			return 256;

		default:
			return 0;
	}
}


//////////////////////////////////////////////////////////////////////////
//// Clipboard support

//---------------------------------------------------------------------
//
// Function:   CopyHandle (from SDK DibView sample clipbrd.c)
//
// Purpose:    Makes a copy of the given global memory block.  Returns
//             a handle to the new memory block (NULL on error).
//
//             Routine stolen verbatim out of ShowDIB.
//
// Parms:      h == Handle to global memory to duplicate.
//
// Returns:    Handle to new global memory block.
//
//---------------------------------------------------------------------

HGLOBAL WINAPI CopyHandle (HGLOBAL h)
{
	if (h == NULL)
		return NULL;

	DWORD dwLen = ::GlobalSize((HGLOBAL) h);
	HGLOBAL hCopy = ::GlobalAlloc(GHND, dwLen);

	if (hCopy != NULL)
	{
		void* lpCopy = ::GlobalLock((HGLOBAL) hCopy);
		void* lp     = ::GlobalLock((HGLOBAL) h);
		memcpy(lpCopy, lp, dwLen);
		::GlobalUnlock(hCopy);
		::GlobalUnlock(h);
	}

	return hCopy;
}

/*************************************************************************
 *
 * DIBToArray()
 *
 *   new own function 
 *
 * get image date from dib data to 2-D array
 *
 * Return value: DIB  Handle
 *
 *************************************************************************/
BYTE ** WINAPI DIBToArray(HDIB hDIB,WORD &wHeight,WORD &wWidth)
{
	WORD wNewWidth;
	DWORD dwSize;
	LPSTR lpDIBHdr;
	LPSTR lpDIBBits;
	unsigned char** uppImage;
	lpDIBHdr=(LPSTR)::GlobalLock((HGLOBAL)hDIB);
	lpDIBBits=::FindDIBBits(lpDIBHdr);
	wHeight=(WORD)(::DIBHeight(lpDIBHdr));
	wWidth=(WORD)(::DIBWidth(lpDIBHdr));
	wNewWidth=(((wWidth*8)+31)/32)*4;
	dwSize=(DWORD)wNewWidth*wHeight;
	DWORD dwOffset=dwSize;
	uppImage=(unsigned char**) CComlib::fspace_2d(wHeight,wWidth,
		                                sizeof(unsigned char));
	for(WORD i=0;i<wHeight;i++){
		dwOffset-=wNewWidth;
		for(WORD j=0;j<wWidth;j++)
			uppImage[i][j]=*(lpDIBBits+dwOffset+j);
	}
	::GlobalUnlock((HGLOBAL)hDIB);
	return(uppImage);
}

/*************************************************************************
 *
 * ArrayToDIB()
 *
 *   new own function 
 *
 *  make a 2-D array data into a dib
 *
 * Return value: DIB  Handle
 *
 *************************************************************************/
HDIB  WINAPI ArrayToDIB(WORD wHeight,WORD wWidth,unsigned char **Image)
{
	BITMAPINFO* bmfInfo;
	DWORD dwBitsSize,dwSize,dOffset,dwHeadsize;
	HDIB hDIB;
	LPSTR pDIB,lpDIBBits;
	WORD wNewWidth;
	
	wNewWidth=(((wWidth*8)+31)/32)*4;
	dwSize=(DWORD)wNewWidth*wHeight;
	dwHeadsize=sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD);
	dwBitsSize=dwHeadsize+dwSize;
	dOffset=dwSize;

	 // Allocate memory for DIB
	hDIB = (HDIB) ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, dwBitsSize);
	if (hDIB == 0)	return NULL;
	pDIB = (LPSTR) ::GlobalLock((HGLOBAL) hDIB);
	bmfInfo=(BITMAPINFO*)pDIB;
	WriteBmpHead(bmfInfo,wWidth,wHeight,8);
	lpDIBBits=pDIB+dwHeadsize;

  	for(WORD i=0;i<wHeight;i++)
	{
		dOffset-=wNewWidth;
		for(WORD j=0;j<wWidth;j++)
			*(lpDIBBits+dOffset+j)=Image[i][j];
	}

	::GlobalUnlock((HGLOBAL) hDIB);

	return hDIB;
}

// array data to DIB
HDIB WINAPI ArrayToDIB2(BYTE **Image, WORD wHeight, WORD wWidth,  CRect rect)
{
	rect.NormalizeRect();

	int x0 = rect.left;
	int x1 = rect.right;
	int y0 = rect.top;
	int y1 = rect.bottom;
	int Row = rect.Height();
	int Col = rect.Width();
	
	ASSERT(y1>=y0 && x1>=x0 );
	
	BYTE ** lpSubImg = (BYTE**) CComlib::fspace_2d(Row, Col, sizeof(BYTE));

	for(int i=0;i<Row;i++)
	for(int j=0;j<Col;j++)
	{
		lpSubImg[i][j]=Image[i+y0][j+x0];
	}
	
	HDIB ret = ArrayToDIB(Row, Col, lpSubImg);

	CComlib::ffree_2d( (void**) lpSubImg, Row);
	
	return ret;
}

/*************************************************************************
 *
 * CreatHangdle()
 *
 *   new own function 
 *
 * Alloc mem for DIB and  Write Bmp Header
 *
 * Return value: DIB  Handle
 *
 *************************************************************************/
HGLOBAL WINAPI CreatHandle (WORD wHeight,WORD wWidth)
{

	BITMAPINFO* bmfInfo;
	DWORD dwBitsSize,dwSize,dwHeadsize;
	HDIB hDIB;
	LPSTR pDIB;
	WORD wNewWidth;


	wNewWidth=(((wWidth*8)+31)/32)*4;
	dwSize=(DWORD)wNewWidth*wHeight;
	dwHeadsize=sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD);
	dwBitsSize=dwHeadsize+dwSize;


	 // Allocate memory for DIB
	 
	hDIB = (HDIB) ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, dwBitsSize);
	if (hDIB == 0)
	{
		return NULL;
	}
	pDIB = (LPSTR) ::GlobalLock((HGLOBAL) hDIB);
	bmfInfo=(BITMAPINFO*)pDIB;
	WriteBmpHead(bmfInfo,wWidth,wHeight,8);

	return hDIB;

}

/*************************************************************************
 *
 * WriteBmpHead()
 *
 *   new own function 
 *
 * Write Bmp Header
 *
 * Return value: 
 *
 *************************************************************************/
BOOL WINAPI WriteBmpHead(BITMAPINFO *BitmapInfo,WORD ColLen,WORD RowLen,WORD BitCount)
{
    DWORD ImgSize;
    int i;

    ImgSize=(DWORD)ColLen*RowLen;
    BitmapInfo->bmiHeader.biSize=40;
    BitmapInfo->bmiHeader.biWidth=ColLen;
    BitmapInfo->bmiHeader.biHeight=RowLen;
    BitmapInfo->bmiHeader.biPlanes=1;
    BitmapInfo->bmiHeader.biBitCount=BitCount;
    BitmapInfo->bmiHeader.biCompression=0;
    BitmapInfo->bmiHeader.biSizeImage=ImgSize;
    BitmapInfo->bmiHeader.biXPelsPerMeter=0xB13;
    BitmapInfo->bmiHeader.biYPelsPerMeter=0xB13;
    BitmapInfo->bmiHeader.biClrUsed=256;
    BitmapInfo->bmiHeader.biClrImportant=0;
    BitmapInfo->bmiHeader.biSizeImage=ColLen*RowLen;
	for(i=0;i<256;i++)
    {
       BitmapInfo->bmiColors[i].rgbBlue=(BYTE)i;
       BitmapInfo->bmiColors[i].rgbGreen=(BYTE)i;
       BitmapInfo->bmiColors[i].rgbRed=(BYTE)i;
       BitmapInfo->bmiColors[i].rgbReserved=0;
    }
    return 1;
}

/*************************************************************************
 *
 * SavePICFile(HDIB hDib, CString FileName)
 *
 * Saves the specified PIC or RAW into the specified CFile.  The CFile
 * is opened and closed by the caller.
 *
 * Parameters:
 *
 * HDIB hDib - Handle to the dib to save
 *
 * CFile& file - open CFile used to save PIC
 *
 * Return value: TRUE if successful, else FALSE or CFileException
 *
 *************************************************************************/
BOOL WINAPI SavePICFile(HDIB hDib, CString FileName)
{
	WORD wHeight,wWidth,wNewWidth;
	DWORD dwSize;
	LPSTR lpDIBHdr;
	LPSTR lpDIBBits;
	unsigned char** uppImage;

	if(hDib==NULL)
		return 0L ;
	lpDIBHdr=(LPSTR)::GlobalLock((HGLOBAL)hDib);
	lpDIBBits=::FindDIBBits(lpDIBHdr);
	wHeight=(WORD)(::DIBHeight(lpDIBHdr));
	wWidth=(WORD)(::DIBWidth(lpDIBHdr));
	wNewWidth=(((wWidth*8)+31)/32)*4;
	dwSize=(DWORD)wNewWidth*wHeight;
	DWORD dwOffset=dwSize;
	uppImage=(unsigned char**)CComlib::fspace_2d(wHeight,wWidth,sizeof(unsigned char));
	for(WORD i=0;i<wHeight;i++)
	{
		dwOffset-=wNewWidth;
		for(WORD j=0;j<wWidth;j++)
			uppImage[i][j]=*(lpDIBBits+dwOffset+j);
	}

	CComlib::OutputImageWithName( uppImage ,  wHeight ,wWidth ,FileName);

	CComlib::ffree_2d((void**)uppImage,wHeight);
	
	::GlobalUnlock((HGLOBAL)hDib);
	return TRUE;
}

BOOL WINAPI SaveRAWFile(HDIB hDib, CString FileName , int HeadBytes )
{
	WORD wHeight,wWidth,wNewWidth;
	DWORD dwSize;
	LPSTR lpDIBHdr;
	LPSTR lpDIBBits;
	unsigned char** uppImage;

	if(hDib==NULL)
		return 0L ;
	lpDIBHdr=(LPSTR)::GlobalLock((HGLOBAL)hDib);
	lpDIBBits=::FindDIBBits(lpDIBHdr);
	wHeight=(WORD)(::DIBHeight(lpDIBHdr));
	wWidth=(WORD)(::DIBWidth(lpDIBHdr));
	wNewWidth=(((wWidth*8)+31)/32)*4;
	dwSize=(DWORD)wNewWidth*wHeight;
	DWORD dwOffset=dwSize;
	uppImage=(unsigned char**)CComlib::fspace_2d(wHeight,wWidth,sizeof(unsigned char));
	for(WORD i=0;i<wHeight;i++)
	{
		dwOffset-=wNewWidth;
		for(WORD j=0;j<wWidth;j++)

⌨️ 快捷键说明

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