为了拿到像素点,GetPixel的速度太慢,改用CreateDIBSection

我使用GetPixel取720x576的像素点是,至少得2秒,当然取决于你取的图得多大

之前的做法

unsigned long PixelBuf[720] = {0};
void CPCI_Transfer_Data(CDC &mCDC)
{
	
	unsigned long R,G,B;
	unsigned long Y,U,V;
	int wide = PIC_W;
	int high = PIC_H;
	COLORREF colorref;
	memset(PixelBuf, 0, sizeof(PixelBuf)/4);
	
	
	//范围限定
	if(wide > 720)
		wide = 720;
	if(high > 576)
		high = 576;
	
	
	for (int i = 0; i < high; i++)
	{	
		
		for (int j = 0; j < wide; j++)
		{
			colorref = mCDC.GetPixel(j, i);
			
			R = GetRValue(colorref) & 0xff;
			G = GetGValue(colorref) & 0xff;
			B = GetBValue(colorref) & 0xff;
			
			Y = 0.299*R + 0.587*G + 0.114*B;
			U = 0.5*R - 0.4187*G - 0.0813*B + 128;
			V = 0.5*B - 0.1687*R - 0.3313*G + 128;
			
			if(j%2 == 0)
				PixelBuf[j] = (Y & 0xff) + (V & 0xff) * 0x100;
			else
				PixelBuf[j] = (Y & 0xff) + (U & 0xff) * 0x100;	
		}
		
		//ALTERA_ReadWriteBlock(hALTERA, ALTERA_AD_BAR0, 0x400000+i*800*4+4, FALSE , PixelBuf, PIC_W*4, ALTERA_MODE_DWORD);
	}
	
	//ALTERA_WriteDword (hALTERA, ALTERA_AD_BAR0, 0x800020,0x1);
	
}

改用CreateDIBSection

HBITMAP CreateDIBSection(
  HDC              hdc,
  const BITMAPINFO *pbmi,
  UINT             usage,
  VOID             **ppvBits,
  HANDLE           hSection,
  DWORD            offset
);

最好先看msdn https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-createdibsection

再看优秀的博客写的

CreateDIBSection最简单的形式仅需要第二和第四个参数

这是改用CreateDIBSection替代GetPixel

unsigned long PixelBuf[720] = {0};
void CPCI_Transfer_Data(BYTE * g_pBits)
{
	
	unsigned long R,G,B;
	unsigned long Y,U,V;
	int wide = PIC_W;
	int high = PIC_H;
	COLORREF colorref;
	
	memset(PixelBuf, 0, sizeof(PixelBuf)/4);
	
	//范围限定
	if(wide > 720)
		wide = 720;
	if(high > 576)
		high = 576;
	
	
	for (int y = 0; y < high; y++)
	{	
		
		for (int x = 0; x < wide; x++)
		{
			
			R = g_pBits[(PIC_H-1-y) * PIC_W * 3+ x * 3 + 2];
			G = g_pBits[(PIC_H-1-y) * PIC_W * 3+ x * 3 + 1];
			B = g_pBits[(PIC_H-1-y) * PIC_W * 3+ x * 3];
			
			
			Y = 0.299*R + 0.587*G + 0.114*B;
			U = 0.5*R - 0.4187*G - 0.0813*B + 128;
			V = 0.5*B - 0.1687*R - 0.3313*G + 128;
			
			if(x%2 == 0)
				PixelBuf[x] = (Y & 0xff) + (V & 0xff) * 0x100;
			else
				PixelBuf[x] = (Y & 0xff) + (U & 0xff) * 0x100;	
		}
		
		//ALTERA_ReadWriteBlock(hALTERA, ALTERA_AD_BAR0, 0x400000+y*800*4+4, FALSE , PixelBuf, PIC_W*4, ALTERA_MODE_DWORD);
	}
	
	//ALTERA_WriteDword (hALTERA, ALTERA_AD_BAR0, 0x800020,0x1);
	
	
}



BYTE bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
void drawCPCI(CDC *pDC, unsigned char *pBuf,int iKZ, int x, int y,int w, int h, int iW, int iH, CDC &dcMemory)
{
	int iZerox = iW/2 - 360;
	int iZeroy = iH/2 - 288;
	int iShowx = 0, iShowy = 0;
	if (iKZ==0)
	{
		iShowx = iZerox + x;
	    iShowy = iZeroy + y;
	}
	else
	{
		iShowx = iZerox + x/4;
	    iShowy = iZeroy + y/8;
	}
	
	CString str1, str2;
	str1.Format("x : %d", x);
	str2.Format("y : %d", y);

	CDC dcMemoryNew;
	dcMemoryNew.CreateCompatibleDC(pDC);
	memset(bmibuf, 0, sizeof(bmibuf));
	BITMAPINFO* pbmi = (BITMAPINFO*)bmibuf;   
	pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
	pbmi->bmiHeader.biWidth = PIC_W;
	pbmi->bmiHeader.biHeight = PIC_H;
	pbmi->bmiHeader.biPlanes = 1;
	pbmi->bmiHeader.biBitCount = 24;
	pbmi->bmiHeader.biCompression = BI_RGB;
	
	HBITMAP g_hBmp;
	BYTE * g_pBits;
	g_hBmp = ::CreateDIBSection(dcMemoryNew, pbmi, DIB_RGB_COLORS, (void **)&g_pBits, 0, 0);
	dcMemoryNew.SelectObject(g_hBmp);


	
	if (iKZ == 0)
	{
		dcMemoryNew.BitBlt(0, 0, w, h, &dcMemory, iShowx, iShowy, SRCCOPY);
		pDC->BitBlt(0, 0, w, h, &dcMemory, iShowx, iShowy, SRCCOPY);
	} 
	else
	{
		iShowx += 180;
		iShowy += 144;
		dcMemoryNew.StretchBlt(0, 0, w, h, &dcMemory, iShowx, iShowy, w/2, h/2,SRCCOPY);
		pDC->StretchBlt(0, 0, w, h, &dcMemory, iShowx, iShowy, w/2, h/2,SRCCOPY);
	}
	
	dcMemoryNew.SelectObject(&g_picfont);
	dcMemoryNew.SetTextColor(RGB(0,0,0));
	dcMemoryNew.SetBkMode(TRANSPARENT);
	dcMemoryNew.TextOut(140, 0, str1);
	dcMemoryNew.TextOut(140, 30, str2);

	pDC->SelectObject(&g_picfont);
	pDC->SetTextColor(RGB(0,0,0));
	pDC->SetBkMode(TRANSPARENT);
	pDC->TextOut(140, 0, str1);
	pDC->TextOut(140, 30, str2);




	CPCI_Transfer_Data(g_pBits);
 	DeleteObject(g_hBmp); 
 	DeleteDC(dcMemoryNew);
	
}

对于以上代码踩过的两个坑

1. 参考别的博客从g_pBits中拿像素和用GetPixel拿的像素不一样,又是一顿google和bing. 之后想着先显示出来看看,一看显示的图成镜像了,小开心,这说明还有戏,经过理工男的直觉咔咔整成这样了,显示 正常.虽然整到凌晨一点多,但是开心的像个孩子去睡觉了.

 

			R = g_pBits[(PIC_H-1-y) * PIC_W * 3+ x * 3 + 2];
			G = g_pBits[(PIC_H-1-y) * PIC_W * 3+ x * 3 + 1];
			B = g_pBits[(PIC_H-1-y) * PIC_W * 3+ x * 3];
			

2. 之前排查视频卡闪烁的问题,不经意间将DeleteObject(g_hBmp)和DeleteDC(dcMemoryNew)注释掉了,噩梦开始了.在晚上联机测试我的方案时,就是以上代码,程序跑上几十秒就崩溃了,我就索性将局部变量大点的改成全局变量,不好使,由于是晚上九点多了加上四五个人等着我,实在没精神,收工. 第二天一早,感觉就是程序占用内存过大导致崩溃.程序运行起来,打开任务管理器,程序占用的内存呼呼的往上升,当打到1500M左右崩溃了,崩在g_pBits取值Access Violation.后来仔细审查代码,将注释打开,程序保持在2.7M左右,搞定.

切记: 

 	DeleteObject(g_hBmp); 
 	DeleteDC(dcMemoryNew);

说的很啰嗦, 望见谅

 

鸣谢: https://blog.csdn.net/zerocnd/article/details/4503939

 

 

 

 

 

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值