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

📄 dib.cpp

📁 电子监控的网络编程实例
💻 CPP
📖 第 1 页 / 共 4 页
字号:
//DEL 	{
//DEL 		// allocate memory block for logical palette 
//DEL 		hLogPal = ::GlobalAlloc(GHND, sizeof(LOGPALETTE)
//DEL 			+ sizeof(PALETTEENTRY) * wNumColors);
//DEL 		// if not enough memory, clean up and return NULL 
//DEL 		if (hLogPal == 0)
//DEL 		{
//DEL 			::GlobalUnlock((HGLOBAL)m_hDIB);
//DEL 			return FALSE;
//DEL 		}
//DEL 		m_lpPal = (LPLOGPALETTE) ::GlobalLock((HGLOBAL) hLogPal);
//DEL 		// set version and number of palette entries 
//DEL 		m_lpPal->palVersion = PALVERSION;
//DEL 		m_lpPal->palNumEntries = (WORD)wNumColors;
//DEL 		// is this a Win 3.0 DIB? 
//DEL 		bWinStyleDIB = IS_WIN30_DIB(lpbi);
//DEL 		for (i = 0; i < (int)wNumColors; i++)
//DEL 		{
//DEL 			if (bWinStyleDIB)
//DEL 			{
//DEL 				m_lpPal->palPalEntry[i].peRed = lpbmi->bmiColors[i].rgbRed;
//DEL 				m_lpPal->palPalEntry[i].peGreen = lpbmi->bmiColors[i].rgbGreen;
//DEL 				m_lpPal->palPalEntry[i].peBlue = lpbmi->bmiColors[i].rgbBlue;
//DEL 				m_lpPal->palPalEntry[i].peFlags = 0;
//DEL 			}
//DEL 			else
//DEL 			{
//DEL 				m_lpPal->palPalEntry[i].peRed = lpbmc->bmciColors[i].rgbtRed;
//DEL 				m_lpPal->palPalEntry[i].peGreen = lpbmc->bmciColors[i].rgbtGreen;
//DEL 				m_lpPal->palPalEntry[i].peBlue = lpbmc->bmciColors[i].rgbtBlue;
//DEL 				m_lpPal->palPalEntry[i].peFlags = 0;
//DEL 			}
//DEL 		}
//DEL 		// create the palette and get handle to it 
//DEL 		m_pPal=new CPalette;
//DEL 		bResult = m_pPal->CreatePalette(m_lpPal);
//DEL 		::GlobalUnlock((HGLOBAL) hLogPal);
//DEL 		::GlobalFree((HGLOBAL) hLogPal);
//DEL 	}
//DEL 	::GlobalUnlock((HGLOBAL) m_hDIB);
//DEL 	return bResult;
//DEL }
/*************************************************************************
 * Function:		PaintDIB()
 * Parameters:
 *		CDC*pDC		- DC to do output to
 *      CRect dRect - rectangle on DC to do output to
 *      CRect sRect - rectangle of DIB to output 
 * Return Value:    TRUE if DIB was drawn, FALSE otherwise
 * Description:
 *   Painting routine for a DIB.  Calls StretchDIBits() or
 *   SetDIBitsToDevice() to paint the DIB.  The DIB is
 *   output to the specified DC, at the coordinates given
 *   in lpDCRect.  The area of the DIB to be output is
 *   given by lpDIBRect.
 *
 ************************************************************************/
BOOL CDIB::PaintDIB(CDC*pDC,CRect dRect,CRect sRect)
{
	LPSTR    lpDIBHdr;            // Pointer to BITMAPINFOHEADER
	LPSTR    lpDIBBits;           // Pointer to DIB bits
	BOOL     bSuccess=FALSE;      // Success/fail flag
	CPalette*pOldPal=NULL;        // Previous palette
	// Check for valid DIB handle 
	if (m_hDIB == NULL) return FALSE;
	// Lock down the DIB, and get a pointer to the beginning of the bit
	//   buffer
	lpDIBHdr  = (LPSTR)::GlobalLock((HGLOBAL)m_hDIB);
	lpDIBBits = lpDIBHdr + *(LPDWORD)lpDIBHdr + PaletteSize(lpDIBHdr);
	// Get the DIB's palette, then select it into DC
	//   Select as background since we have
	//   already realized in forground if needed
	if (m_pPal != NULL)
	{
		pOldPal = pDC->SelectPalette(m_pPal,TRUE);
		pDC->RealizePalette();
	}
	// Make sure to use the stretching mode best for color pictures 
	pDC->SetStretchBltMode(COLORONCOLOR);
	// Determine whether to call StretchDIBits() or SetDIBitsToDevice() 
	if (dRect.Width()==sRect.Width()&&dRect.Height()==sRect.Height())
		bSuccess = ::SetDIBitsToDevice(pDC->m_hDC,dRect.left,dRect.top,
		dRect.Width(),dRect.Height(),sRect.left,
		m_nHeight-sRect.top-sRect.Height(),0,m_nHeight,
 			    lpDIBBits,(LPBITMAPINFO)lpDIBHdr,DIB_RGB_COLORS);
	else 
		bSuccess = ::StretchDIBits(pDC->m_hDC,dRect.left,dRect.top,dRect.Width(),
		dRect.Height(),sRect.left,sRect.top,sRect.Width(),sRect.Height(),
		lpDIBBits,(LPBITMAPINFO)lpDIBHdr,DIB_RGB_COLORS,SRCCOPY);
	
	::GlobalUnlock((HGLOBAL) m_hDIB);
	// Reselect old palette 
	if (pOldPal != NULL) pDC->SelectPalette(pOldPal, TRUE);
	
	return bSuccess;
}

BOOL CDIB::PaintDIB(HDC pDC,CRect dRect,CRect sRect)
{
	LPSTR    lpDIBHdr;            // Pointer to BITMAPINFOHEADER
	LPSTR    lpDIBBits;           // Pointer to DIB bits
	BOOL     bSuccess=FALSE;      // Success/fail flag
	HPALETTE pOldPal=NULL;        // Previous palette

	// Check for valid DIB handle 
	if (m_hDIB == NULL) return FALSE;
	// Lock down the DIB, and get a pointer to the beginning of the bit
	//   buffer
	lpDIBHdr  = (LPSTR)::GlobalLock((HGLOBAL)m_hDIB);
	lpDIBBits = lpDIBHdr + *(LPDWORD)lpDIBHdr + PaletteSize(lpDIBHdr);
	// Get the DIB's palette, then select it into DC
	//   Select as background since we have
	//   already realized in forground if needed
	if (m_pPal != NULL)
	{
		pOldPal = SelectPalette(pDC,(HPALETTE )m_pPal->m_hObject,TRUE);
		RealizePalette(pDC);
	}
	// Make sure to use the stretching mode best for color pictures 
	SetStretchBltMode(pDC,COLORONCOLOR);
	// Determine whether to call StretchDIBits() or SetDIBitsToDevice() 
	if (dRect.Width()==sRect.Width()&&dRect.Height()==sRect.Height())
		bSuccess = SetDIBitsToDevice(pDC,dRect.left,dRect.top,
		dRect.Width(),dRect.Height(),sRect.left,
		m_nHeight-sRect.top-sRect.Height(),0,m_nHeight,
 			    lpDIBBits,(LPBITMAPINFO)lpDIBHdr,DIB_RGB_COLORS);
	else 
		bSuccess = ::StretchDIBits(pDC,dRect.left,dRect.top,dRect.Width(),
		dRect.Height(),sRect.left,sRect.top,sRect.Width(),sRect.Height(),
		lpDIBBits,(LPBITMAPINFO)lpDIBHdr,DIB_RGB_COLORS,SRCCOPY);
	
	::GlobalUnlock((HGLOBAL) m_hDIB);
	// Reselect old palette 
	if (pOldPal != NULL) SelectPalette(pDC,pOldPal, TRUE);
	
	return bSuccess;
}

DWORD CDIB::DIBWidthByByte()
{
	return WIDTHBYTES(m_nWidth*24);
}

/*************************************************************************
 * Function: DIBWidth()
 * Description:
 * This function gets the width of the DIB from the BITMAPINFOHEADER
 * width field if it is a Windows 3.0-style DIB or from the BITMAPCOREHEADER
 * width field if it is an other-style DIB.
 ************************************************************************/
int CDIB::DIBWidth()
{
	LPSTR				 lpDIBHdr;  // Pointer to BITMAPINFOHEADER
	LPBITMAPINFOHEADER lpbmi;		// pointer to a Win 3.0-style DIB
	LPBITMAPCOREHEADER lpbmc;		// pointer to an other-style DIB
	int w;
	
	lpDIBHdr=(LPSTR)::GlobalLock((HGLOBAL) m_hDIB);
	// point to the header (whether Win 3.0 and old) 
	lpbmi=(LPBITMAPINFOHEADER)lpDIBHdr;
	lpbmc=(LPBITMAPCOREHEADER)lpDIBHdr;
	// return the DIB width if it is a Win 3.0 DIB 
	if (IS_WIN30_DIB(lpDIBHdr))
		w=lpbmi->biWidth;
	else  // it is an other-style DIB, so return its width 
		w=lpbmc->bcWidth;
	
	::GlobalUnlock((HGLOBAL) m_hDIB);
	return(w);
}
/*************************************************************************
 * Function: DIBHeight()
 * Description:
 * This function gets the height of the DIB from the BITMAPINFOHEADER
 * height field if it is a Windows 3.0-style DIB or from the BITMAPCOREHEADER
 * height field if it is an other-style DIB.
 ************************************************************************/
int CDIB::DIBHeight()
{
	LPSTR				 lpDIBHdr;  // Pointer to BITMAPINFOHEADER
	LPBITMAPINFOHEADER lpbmi;		// pointer to a Win 3.0-style DIB
	LPBITMAPCOREHEADER lpbmc;		// pointer to an other-style DIB
	int h;
	// point to the header (whether old or Win 3.0
	lpDIBHdr  = (LPSTR) ::GlobalLock((HGLOBAL) m_hDIB);
	lpbmi = (LPBITMAPINFOHEADER)lpDIBHdr;
	lpbmc = (LPBITMAPCOREHEADER)lpDIBHdr;
	// return the DIB height if it is a Win 3.0 DIB 
	if (IS_WIN30_DIB(lpDIBHdr))
		h=lpbmi->biHeight;
	else  // it is an other-style DIB, so return its height 
		h=lpbmc->bcHeight;
	::GlobalUnlock((HGLOBAL) m_hDIB);
	return(h);
}
/*************************************************************************
 * Function: PaletteSize()
 * Description:
 * This function gets the size required to store the DIB's palette by
 * multiplying the number of colors by the size of an RGBQUAD (for a
 * Windows 3.0-style DIB) or by the size of an RGBTRIPLE (for an other-
 * style DIB).
 ************************************************************************/
int CDIB::PaletteSize(LPSTR lpbi)
{
	// calculate the size required by the palette 
	if (IS_WIN30_DIB (lpbi))
		return DIBNumColors(lpbi) * sizeof(RGBQUAD);
	else
		return DIBNumColors(lpbi) * sizeof(RGBTRIPLE);
}
/*************************************************************************
 * DIBNumColors()
 * 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.
 ************************************************************************/
int CDIB::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;
	}
}

BOOL CDIB::SaveDIB(CFile & file)
{
	BITMAPFILEHEADER bmfHdr;	// Header for Bitmap file
	LPBITMAPINFOHEADER lpBI;	// Pointer to DIB info structure
	DWORD dwDIBSize;
	
	if (m_hDIB == NULL)
		return FALSE;
	// Get a pointer to the DIB memory, the first of which contains a BITMAPINFO structure
	lpBI = (LPBITMAPINFOHEADER) ::GlobalLock((HGLOBAL) m_hDIB);
	if (lpBI == NULL)
		return FALSE;
	
	if (!IS_WIN30_DIB(lpBI))
	{
		::GlobalUnlock((HGLOBAL) m_hDIB);
		return FALSE;       // It's an other-style DIB (save not supported)
	}
	// Fill in the fields of the file header
	/* Fill in file type (first 2 bytes must be "BM" for a bitmap) */
	bmfHdr.bfType = DIB_HEADER_MARKER;  // "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).
	//
	// So, instead let's calculate the size manually (if we can)
	//
	// First, 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.
	dwDIBSize = *(LPDWORD)lpBI + PaletteSize((LPSTR)lpBI);  // Partial Calculation
	// Now calculate the size of the image
	if ((lpBI->biCompression == BI_RLE8) || (lpBI->biCompression == BI_RLE4))
	{
		// It's an RLE bitmap, we can't calculate size, so trust the
		// biSizeImage field
		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
		+ PaletteSize((LPSTR)lpBI);
	TRY
	{	// Write the file header
		file.Write((LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER));
		// Write the DIB header and the bits
		file.WriteHuge(lpBI, dwDIBSize);
	}
	CATCH (CFileException, e)
	{
		::GlobalUnlock((HGLOBAL) m_hDIB);
		THROW_LAST();
	}
	END_CATCH
		
		::GlobalUnlock((HGLOBAL) m_hDIB);
	return TRUE;
}

void CDIB::ReadBYTEFile(CFile & file, int size)
{
	DWORD dwBitsSize;
	LPSTR pDIB;
	LPBITMAPINFOHEADER lpBMIH;
    LPBITMAPINFO lpbmi;
	int i;

	dwBitsSize = sizeof(BITMAPINFOHEADER)+(DWORD)256*sizeof(RGBQUAD)+(DWORD)size*(DWORD)size;
	m_hDIB = (HDIB) ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT,dwBitsSize);
	if (m_hDIB == 0)
	{
		return ;
	}
	pDIB = (LPSTR) ::GlobalLock((HGLOBAL) m_hDIB);

	lpBMIH = (LPBITMAPINFOHEADER)pDIB;
	lpBMIH->biSize = sizeof(BITMAPINFOHEADER);
	lpBMIH->biWidth = (DWORD)size;
	lpBMIH->biHeight = (DWORD)size;
	m_nWidth=lpBMIH->biWidth;
	m_nHeight=lpBMIH->biHeight;
	lpBMIH->biPlanes = 1;
	lpBMIH->biBitCount = 8;
	lpBMIH->biCompression = 0;
	lpBMIH->biSizeImage = (DWORD)size*(DWORD)size;
	lpBMIH->biXPelsPerMeter = 0;
	lpBMIH->biYPelsPerMeter = 0;
	lpBMIH->biClrUsed =256;
	lpBMIH->biClrImportant =0;
	
	lpbmi=(LPBITMAPINFO)pDIB;
	for (i = 0; i < 256; i++)
	{
		lpbmi->bmiColors[i].rgbRed=i;
		lpbmi->bmiColors[i].rgbGreen=i;
		lpbmi->bmiColors[i].rgbBlue=i;
		lpbmi->bmiColors[i].rgbReserved = 0;
	}
	if (file.ReadHuge(pDIB+sizeof(BITMAPINFOHEADER)+(DWORD)256*sizeof(RGBQUAD),
		lpBMIH->biSizeImage) !=
		lpBMIH->biSizeImage)
	{
		::GlobalUnlock((HGLOBAL) m_hDIB);
		::GlobalFree((HGLOBAL) m_hDIB);
		return ;
	}
	
	::GlobalUnlock((HGLOBAL) m_hDIB);
	return ;
}

LPSTR CDIB::FindDIBBits()
{
	m_lpbi=(LPSTR)::GlobalLock((LPSTR)m_hDIB);
	return (m_lpbi + *(LPDWORD)m_lpbi+PaletteSize(m_lpbi));
//	return (lpbi+dwDibOffset-sizeof(BITMAPFILEHEADER));
}

void CDIB::ReadAVIFile(PGETFRAME pframe, int frame)
{
	LPSTR lpBuffer,lpBI1,pDIB,p,s1,s2;
	LPBITMAPINFOHEADER lpBI,lpBMIH;
	DWORD dwDIBSize,size;
    LPBITMAPINFO lpbmi;

	if(pframe!=NULL)
	{
		p=(LPSTR)pframe->GetFrame(frame);
		if (p!=NULL)
		{
			lpBI1=(LPSTR)::GlobalLock(p);
			lpBI=(LPBITMAPINFOHEADER) lpBI1;
			dwDIBSize = *(LPDWORD)lpBI + PaletteSize((LPSTR)lpBI);  // Partial Calculation
			// Now calculate the size of the image
			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)
			if(lpBI->biBitCount==24){
			   size= sizeof(BITMAPINFOHEADER)+(DWORD)256*sizeof(RGBQUAD)+(DWORD)lpBI->biWidth*(DWORD)lpBI->biHeight;
			   lpBuffer=(LPSTR)::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, size);
			   if(lpBuffer==NULL)  return ;
			   pDIB = (LPSTR) ::GlobalLock((HGLOBAL) lpBuffer);
			DWORD i;
			lpBMIH = (LPBITMAPINFOHEADER)pDIB;
			lpBMIH->biSize = sizeof(BITMAPINFOHEADER);
			lpBMIH->biWidth = (DWORD)lpBI->biWidth;//-320+128;
			lpBMIH->biHeight = (DWORD) lpBI->biHeight;//-240+128;
			m_nWidth=lpBMIH->biWidth;
			m_nHeight=lpBMIH->biHeight;
			lpBMIH->biPlanes = 1;
			lpBMIH->biBitCount = 8;
			lpBMIH->biCompression = 0;
			lpBMIH->biSizeImage = (DWORD)lpBI->biWidth*(DWORD) lpBI->biHeight;//128*128;
			lpBMIH->biXPelsPerMeter = 0;
			lpBMIH->biYPelsPerMeter = 0;
			lpBMIH->biClrUsed =256;
			lpBMIH->biClrImportant =0;

			lpbmi=(LPBITMAPINFO)pDIB;
			for (i = 0; i < 256; i++)
			{
				lpbmi->bmiColors[i].rgbRed=(unsigned char)i;
				lpbmi->bmiColors[i].rgbGreen=(unsigned char)i;
				lpbmi->bmiColors[i].rgbBlue=(unsigned char)i;
				lpbmi->bmiColors[i].rgbReserved = 0;
			}
			dwDIBSize = *(LPDWORD)lpBI + PaletteSize((LPSTR)lpBI);  // Partial Calculation
			s1=p+dwDIBSize;//+320*100;
			s2=pDIB+sizeof(BITMAPINFOHEADER)+(DWORD)256*sizeof(RGBQUAD);
			for(i=0;i<lpBMIH->biSizeImage;i++)
			{  
				CopyMemory (s2,s1,1);// +(320-128)*div(i,128).quot*3
				s1=s1+3;
				s2=s2+1;
			}
		}
		m_hDIB=(HDIB)pDIB;
		::GlobalUnlock((HGLOBAL) m_hDIB);
		::GlobalUnlock((HGLOBAL) lpBI1);
		}
	}
    return ;
}



void CDIB::Enlarge(CRect & sRect, CRect & dRect)
{
	int	ix,iy,gx,gy,xd,yd,xs,ys,xdist,ydist,x1,x2,y1,y2;
	float	deltax,deltay,dx,dx1,dy,dy1,xx,yy,zz;
	unsigned char image[512][512];

	LPSTR array;
	int y,i;
	unsigned char** oi;

	oi=new unsigned char*[m_nWidth];
	array=(LPSTR)FindDIBBits();	// TODO: Add your command handler code here
	for(y=0;y<m_nHeight;y++)
	{  
		oi[y]=(unsigned char*)array+m_nWidth*y;
	}
	
	for(ix=sRect.left;ix<sRect.right;ix++)
		for(iy=sRect.top;iy<sRect.bottom;iy++)
			image[iy-sRect.top][ix-sRect.left]=oi[iy][ix];
	delete oi;
	::GlobalUnlock(array);

	xd=dRect.Width();
	yd=dRect.Height();
	xs=sRect.Width();
	ys=sRect.Height();

⌨️ 快捷键说明

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