我使用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