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

📄 ddb.cpp

📁 使用大恒采集卡的图像显示
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// Ddb.cpp: implementation of the CDdb class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Ddb.h"

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

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
IMPLEMENT_DYNAMIC(CDdb,CObject)
CDdb::CDdb()
{
	m_pDdbData=NULL;
	m_hDdbData=0;
}

CDdb::~CDdb()
{
	ClearMemory();
}

#ifdef _DEBUG
void CDdb::Dump(CDumpContext& dc)const
{
	CObject::Dump(dc);
}
void CDdb::AssertValid()const
{
	CObject::AssertValid();
	ASSERT(m_pDdb!=NULL);
	ASSERT(m_hDdbData!=0);
	ASSERT(m_pDdbData!=NULL);

}
#endif

CDdb::CDdb(CBitmap *pBitmap)
{
	m_pDdbData=NULL;
	m_hDdbData=0;
	SetDdb(pBitmap);
}

void CDdb::ClearMemory()
{
	if(m_hDdbData!=NULL)
		::GlobalFree(m_hDdbData);
	m_pDdbData=NULL;
	m_hDdbData=0;
}

void CDdb::SetDdb(CBitmap *pBitmap)
{
	ASSERT(pBitmap);
	BITMAP bitmap;
	pBitmap->GetObject(sizeof(BITMAP),&bitmap);
	m_nWidth=bitmap.bmWidth;
	m_nHeight=bitmap.bmHeight;
	m_pDdb=pBitmap;
	HDC hdc=::GetDC(NULL);
	m_nBitCount=24;
	m_nBitCount=::GetDeviceCaps(hdc,BITSPIXEL);
	if(m_nBitCount<8)
	{
		AfxMessageBox("please change your display mode.Thank you!");
		return;
	}
	m_nDdbWidthBytes=CalcDdbWidthBytes(m_nWidth,m_nBitCount);
	DWORD dwDdbBitsSize=m_nDdbWidthBytes*m_nHeight;
	if(m_pDdbData!=NULL)
	{
		::GlobalFree(m_hDdbData);
		m_pDdbData=NULL;
		m_hDdbData=0;
	}
	m_hDdbData=(HGLOBAL)::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT,dwDdbBitsSize);
	if(m_hDdbData==0) return;
	m_pDdbData=(BYTE*)::GlobalLock(m_hDdbData);
	if(m_pDdbData==NULL)
	{
		::GlobalUnlock(m_hDdbData);
		::GlobalFree(m_hDdbData);
		m_hDdbData=0;
		return;
	}
	m_pDdb->GetBitmapBits(dwDdbBitsSize,m_pDdbData);
	::GlobalUnlock(m_hDdbData);
	::ReleaseDC(NULL,hdc);
}


BYTE* CDdb::GetDdbData() const
{
	return m_pDdbData;
}

BYTE CDdb::GetBitCount() const
{
	return m_nBitCount;
}

LONG CDdb::GetWidth() const
{
	return m_nWidth;
}

LONG CDdb::GetHeight() const
{
	return m_nHeight;
}

LONG CDdb::GetDdbWidthBytes() const
{
	return m_nDdbWidthBytes;
}

LONG CDdb::CalcDdbWidthBytes(LONG nWidth, BYTE byBitCount)
{
	return (((nWidth*byBitCount+15)/16)*2);
}

LONG CDdb::CalcDibWidthBytes(LONG nWidth, BYTE byBitCount)
{
	if(byBitCount==8)
		return (((nWidth*8+31)/32)*4);
	else
		return (((nWidth*24+31)/32)*4);

}

void CDdb::GetRGB16(BYTE *pbyRGB, WORD *pwColor)
{
	WORD* pwClr=pwColor;
	pbyRGB[0]=(BYTE)(((*pwClr)&0x001F)<<3);
	pbyRGB[1]=(BYTE)(((*pwClr)&0x07E0)>>3);
	pbyRGB[2]=(BYTE)(((*pwClr)&0xF800)>>8);
}

DWORD CDdb::SetBitmapBits(DWORD dwCount, const void *lpbyBits)
{
	ASSERT(lpbyBits);
	return (m_pDdb->SetBitmapBits(dwCount,lpbyBits));

}

DWORD CDdb::SetBitmapBits(int x, int y, int nWidth, int nHeight, int nBitCount, LPBYTE lpbyBits)
{
	ASSERT(lpbyBits);
	if(nBitCount!=m_nBitCount) return 0;
	if((x>m_nWidth-1) || (y>nHeight-1))
	{
		AfxMessageBox("Cross the border!");
		return 0;
	}
	LONG w=(LONG)min(nWidth,m_nWidth-x);
	LONG h=(LONG)min(nHeight,m_nHeight-y);
	DWORD dwScanLength=CalcDdbWidthBytes(nWidth,nBitCount);
	DWORD dwLength=w;
	DWORD dwOffset=x;
	if(nBitCount==16)
	{
		dwLength=w+w;
		dwOffset=x+x;
	}
	else if(nBitCount==24)
	{
		dwLength=3*w;
		dwOffset=3*x;
	}
	else if(nBitCount==32)
	{
		dwLength=4*w;
		dwOffset=4*x;
	}
	BYTE* pbyDdbDst=m_pDdbData+y*m_nDdbWidthBytes+dwOffset;
	BYTE* pbyDdbRsc=lpbyBits;
	for(int i=0;i<h;i++)
	{
		::CopyMemory(pbyDdbDst,pbyDdbRsc,dwLength);
		pbyDdbRsc+=dwScanLength;
		pbyDdbDst+=m_nDdbWidthBytes;
	}
	m_pDdb->SetBitmapBits(m_nDdbWidthBytes*m_nHeight,m_pDdbData);
	return (nWidth*nHeight*nBitCount);
}

void CDdb::GetDdbDataTo24(int x, int y, int nWidth, int nHeight, LPBYTE lpbyBits24)
{
	ASSERT(lpbyBits24);
	if((x>m_nWidth-1) || (y>nHeight-1))
	{
		AfxMessageBox("Cross the boader!");
		return;
	}
	LONG w=(LONG)min(nWidth,m_nWidth-x);
	LONG h=(LONG)min(nHeight,m_nHeight-y);
	DWORD dwWidthBytes24=((w*24+15)/16)*2;
	switch(m_nBitCount)
	{
	case 8:
		{
			RGBQUAD* pRGBQuad=new RGBQUAD[256];
			if(pRGBQuad==NULL) return;
			memset(pRGBQuad,0,256*sizeof(RGBQUAD));
			GetSystemPaletteEntries(pRGBQuad);
			DWORD dwBaseIndex=y*m_nDdbWidthBytes+x;
			DWORD dwBase24=0;
			for(LONG i=0;i<h;i++)
			{
				BYTE* pbyDdbRaw=m_pDdbData+dwBaseIndex;
				BYTE* pbyBits24Raw=lpbyBits24+dwBase24;
				for(LONG j=0;j<w;j++)
				{
					BYTE byPixel=*(pbyDdbRaw++);
					*(pbyBits24Raw++)=pRGBQuad[byPixel].rgbBlue;
					*(pbyBits24Raw++)=pRGBQuad[byPixel].rgbGreen;
					*(pbyBits24Raw++)=pRGBQuad[byPixel].rgbRed;
				}
				dwBaseIndex+=m_nDdbWidthBytes;
				dwBase24+=dwWidthBytes24;

			}
			delete[]pRGBQuad;
			break;	
		}
		
	case 24:
		{
			DWORD dwLength=w*3;
			BYTE* pbyDdbRaw=m_pDdbData+y*m_nDdbWidthBytes+x+x+x;
			BYTE* pbyBits24Raw=lpbyBits24;
			for(LONG i=0;i<h;i++)
			{
				::CopyMemory(pbyBits24Raw,pbyDdbRaw,dwLength);
				pbyDdbRaw+=m_nDdbWidthBytes;
				pbyBits24Raw+=dwWidthBytes24;
			}

			break;
		}
	case 16:
	case 32:
		{
			DWORD	dwBaseIndex=y*m_nDdbWidthBytes+((m_nBitCount==16)?(x+x):(4*x));
			DWORD dwBase24=0;
			for(LONG i=0;i<h;i++)
			{
				BYTE* pbyDdbRaw=m_pDdbData+dwBaseIndex;
				DWORD dwBitsIndex24=(DWORD)(i*dwWidthBytes24);
				BYTE* pbyBits24Raw=lpbyBits24+dwBase24;
				for(LONG j=0;j<w;j++)
				{
					if(m_nBitCount==16)
					{
						BYTE* pbyRGB=new BYTE[3];
						WORD* pwDdbData_16=(WORD*)(pbyDdbRaw++);
						GetRGB16(pbyRGB,pwDdbData_16);
						pbyDdbRaw++;
						*pbyBits24Raw++=pbyRGB[0];
						*pbyBits24Raw++=pbyRGB[1];
						*pbyBits24Raw++=pbyRGB[2];
					}
					if(m_nBitCount==32)
					{
						*pbyBits24Raw++=*pbyDdbRaw++;
						*pbyBits24Raw++=*pbyDdbRaw++;
						*pbyBits24Raw++=*pbyDdbRaw++;
						pbyDdbRaw++;
					}
				}
				dwBaseIndex+=m_nDdbWidthBytes;
				dwBase24+=dwWidthBytes24;
			}
			break;
		}
	}
}

void CDdb::GetDdbDataTo32(int x, int y, int nWidth, int nHeight, LPBYTE lpbyBits32)
{
	ASSERT(lpbyBits32);
	if((x>m_nWidth-1) || (y>nHeight-1))
	{
		AfxMessageBox("Cross the border!");
		return;
	}
	LONG w=(LONG)min(nWidth,m_nWidth-x);
	LONG h=(LONG)min(nHeight,m_nHeight-y);
	DWORD dwWidthBytes32= w*4;
	switch(m_nBitCount)
	{
	case 8:
		{
			RGBQUAD* pRGBQuad=new RGBQUAD[256];
			if(pRGBQuad==NULL) return;
			memset(pRGBQuad,0,256*sizeof(RGBQUAD));
			GetSystemPaletteEntries(pRGBQuad);
			DWORD dwBaseIndex=y*m_nDdbWidthBytes+x;
			DWORD dwBase32=0;
			for(LONG i=0;i<h;i++)
			{
				BYTE* pbyDdbRaw=m_pDdbData+dwBaseIndex;
				BYTE* pbyBits32Raw=lpbyBits32+dwBase32;
				for(LONG j=0;j<w;j++)
				{
					BYTE byPixel=*(pbyDdbRaw++);
					*(pbyBits32Raw++)=pRGBQuad[byPixel].rgbBlue;
					*(pbyBits32Raw++)=pRGBQuad[byPixel].rgbGreen;
					*(pbyBits32Raw++)=pRGBQuad[byPixel].rgbRed;
					pbyBits32Raw++;
				}
				dwBaseIndex+=m_nDdbWidthBytes;
				dwBase32+=dwWidthBytes32;
			}
			delete[] pRGBQuad;
			break;
		}
	case 24:
		{
			DWORD dwBaseIndex=y*m_nDdbWidthBytes+x+x+x;
			DWORD dwBase32=0;
			for(LONG i=0;i<h;i++)
			{
				BYTE* pbyDdbRaw=m_pDdbData+dwBaseIndex;
				BYTE* pbyBits32Raw=lpbyBits32+dwBase32;
				for(LONG j=0;j<w;j++)
				{
					*(pbyBits32Raw++)=*(pbyDdbRaw++);
					*(pbyBits32Raw++)=*(pbyDdbRaw++);
					*(pbyBits32Raw++)=*(pbyDdbRaw++);
					pbyBits32Raw++;
				}
				dwBaseIndex+=m_nDdbWidthBytes;
				dwBase32+=dwWidthBytes32;
			}
			break;
		}
	case 16:
		{
			DWORD dwBaseIndex=y*m_nDdbWidthBytes+x+x;
			DWORD dwBase32=0;
			for(LONG i=0;i<h;i++)
			{
				BYTE* pbyDdbRaw=m_pDdbData+dwBaseIndex;
				DWORD dwBitsIndex32=(DWORD)(i*dwWidthBytes32);
				BYTE* pbyBits32Raw=lpbyBits32+dwBase32;
				for(LONG j=0;j<w;j++)
				{
					BYTE* pbyRGB=new BYTE[3];
					WORD* pwDdbData_16=(WORD*)(pbyDdbRaw++);
					GetRGB16(pbyRGB,pwDdbData_16);
					pbyDdbRaw++;
					*pbyBits32Raw++=pbyRGB[0];
					*pbyBits32Raw++=pbyRGB[1];
					*pbyBits32Raw++=pbyRGB[2];
					pbyBits32Raw++;
					delete[]pbyRGB;
				}
				dwBaseIndex+=m_nDdbWidthBytes;
				dwBase32+=dwWidthBytes32;
			}
			break;
		}
	case 32:
		{
			DWORD dwLength=w*4;
			DWORD dwBaseIndex=y*m_nDdbWidthBytes+4*x;
			BYTE* pbyDdbRaw=m_pDdbData+dwBaseIndex;
			BYTE* pbyBits32Raw=lpbyBits32;
			for(LONG i=0;i<h;i++)
			{
				::CopyMemory(pbyBits32Raw,pbyDdbRaw,dwLength);
				pbyDdbRaw+=m_nDdbWidthBytes;
				pbyBits32Raw+=dwWidthBytes32;
			}
			break;
		}
	}
}

void CDdb::GetSystemPaletteEntries(RGBQUAD *pRGBQuad)
{
	ASSERT(pRGBQuad);
	HDC hdc=::GetDC(NULL);
	PALETTEENTRY* paletteEntry=new PALETTEENTRY[256];
	::GetSystemPaletteEntries(hdc,0,256,paletteEntry);
	for(int index=0;index<256;index++)
	{
		pRGBQuad[index].rgbRed=paletteEntry[index].peRed;
		pRGBQuad[index].rgbGreen=paletteEntry[index].peGreen;
		pRGBQuad[index].rgbBlue=paletteEntry[index].peBlue;
		pRGBQuad[index].rgbReserved=0;
	}
	delete[] paletteEntry;
	::ReleaseDC(NULL,hdc);
}

void CDdb::QuantizeColor(LPBYTE lpbyDdbBits24, int nScanWidth, int nScanHeight,
						  LPBYTE lpbyDdbBits8, CPalette *pPalette)
{
	ASSERT(lpbyDdbBits24); 
	ASSERT(lpbyDdbBits8); 
	//第一步:对颜色分布进行统计:
	//COLORQUANTIZATION结构记录位于小颜色立方体中的像素个数, 颜色分量之和.
	typedef struct tagCOLORQUANTIZATION
	{
		DWORD dwRedSum; 			//红色总量
		DWORD dwGreenSum; 		//绿色总量
		DWORD dwBlueSum; 		//蓝色总量
		DWORD dwPixelCount; 		//进入一个Box的颜色个数
		BYTE  byFlag; 			//是否抛弃, 等于0则抛弃, 非0则不抛弃
	}COLORQUANTIZATION; 

	//分配内存, 必须初始化为0
	BYTE* pbyColorBox = new BYTE[252 * sizeof(COLORQUANTIZATION)]; 
	if (pbyColorBox == NULL)	return ; 
	memset(pbyColorBox,  0,  252 * sizeof(COLORQUANTIZATION)); 
	//指向COLORQUANTIZATION数据的指针
	COLORQUANTIZATION* pCQBox = (COLORQUANTIZATION*)pbyColorBox; 

	//每行的大小(字节)
	DWORD dwWidthBytes24 =  ((nScanWidth * 24 + 15) / 16) * 2; 
	DWORD dwWidthBytes8 = ((nScanWidth * 8 + 15) / 16) * 2; 

	//现在进行统计
	DWORD dwBaseIndex24 = 0; 
	DWORD dwBaseIndex8 = 0; 
	int i, j; 
	for(i = 0;  i < nScanHeight;  i++)
	{
		//指向Ddb内存数据的指针(行)
		BYTE* pbyDdb24 = lpbyDdbBits24 + dwBaseIndex24; 
		BYTE* pbyDdb8 = lpbyDdbBits8 + dwBaseIndex8; 

		for(j = 0;  j < nScanWidth;  j++)
		{
			//获取当前点的颜色分量

			BYTE byBlue = *(pbyDdb24++); 
			BYTE byGreen = *(pbyDdb24++); 
			BYTE byRed = *(pbyDdb24++); 

			//计算当前颜色在立方体中的位置:由颜色三分量的值决定, 因而这也是颜色量化映射关系.
			BYTE byIndexR = (byRed >= 210) ? 5 : (byRed / 42); 
			BYTE byIndexG = (byGreen >= 216) ? 6 : (byGreen / 36); 
			BYTE byIndexB = (byBlue >= 210) ? 5 : (byBlue / 42); 
			BYTE byInBox = 42 *  byIndexB + 6 * byIndexG + byIndexR; 
			
			(pCQBox + byInBox)->dwPixelCount++; 
			(pCQBox + byInBox)->dwRedSum += byRed; 
		    (pCQBox + byInBox)->dwGreenSum += byGreen; 
		    (pCQBox + byInBox)->dwBlueSum += byBlue; 

			*(pbyDdb8++) = byInBox; 
		}
		dwBaseIndex24 += dwWidthBytes24; 
		dwBaseIndex8 += dwWidthBytes8; 
	}

	//第二步选出发生频率最高的236种颜色
	//临时数组, 用于存放分布频数
	DWORD* pdwFrequency = new DWORD[252]; 

	for(i = 0;  i < 252;  i++)

⌨️ 快捷键说明

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