新开一贴,研究画图的问题
看了画图大家都比较关心,于是我将我写了几个EXE,分别测试Ce下的刷图函数的
大家可以下载一下,然后测试
http://download.csdn.net/detail/hudaweikevin/4260273
代码我贴在下面,大家看一下这样写有没有问题
#define WIDETH_PIXEL_UNIT 800
#define HEIGHT_PIXEL_UNIT 480
int nBitsPixel= 16;
void DDCreate24BitmapInfo(PBITMAPINFO pbminfo,int dx,int dy)
{
ZeroMemory(pbminfo, sizeof(BITMAPINFO));
// setup bitmap info
pbminfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
pbminfo->bmiHeader.biWidth = dx;
pbminfo->bmiHeader.biHeight = dy;
pbminfo->bmiHeader.biPlanes = 1;
pbminfo->bmiHeader.biBitCount = 24;
pbminfo->bmiHeader.biCompression = BI_RGB;
pbminfo->bmiHeader.biSizeImage = dx * dy * 3;// 图片缓冲区大小
return;
}
void
DDCreate16BitmapInfo(PBITMAPINFO pbminfo,int dx,int dy)
{
ZeroMemory(pbminfo, sizeof(BITMAPINFO));
// setup bitmap info
pbminfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
pbminfo->bmiHeader.biWidth = dx;
pbminfo->bmiHeader.biHeight = dy;
pbminfo->bmiHeader.biPlanes = 1;
pbminfo->bmiHeader.biBitCount = 16;
pbminfo->bmiHeader.biCompression = BI_RGB;
pbminfo->bmiHeader.biSizeImage = dx * dy * 2;// 图片缓冲区大小
return;
}
void Cpaint_time_testDlg::OnBnClickedButton1()
{
// TODO: Add your control notification handler code here
HDC hdc = ::GetDC(m_hWnd);
BITMAPINFO bmi;
if(nBitsPixel == 16)
DDCreate16BitmapInfo(&bmi,WIDETH_PIXEL_UNIT,HEIGHT_PIXEL_UNIT);
else
DDCreate24BitmapInfo(&bmi,WIDETH_PIXEL_UNIT,HEIGHT_PIXEL_UNIT);
UCHAR * pdata=(UCHAR *)malloc(WIDETH_PIXEL_UNIT*HEIGHT_PIXEL_UNIT*3);
UCHAR temp=0;
int sum=0;
for (int i=0;i<10;i++)
{
memset(pdata,temp,WIDETH_PIXEL_UNIT*HEIGHT_PIXEL_UNIT);
temp=temp+0x44;
memset(pdata+WIDETH_PIXEL_UNIT*HEIGHT_PIXEL_UNIT,temp,WIDETH_PIXEL_UNIT*HEIGHT_PIXEL_UNIT);
temp=temp+0x44;
if(nBitsPixel == 24)
{
memset(pdata+WIDETH_PIXEL_UNIT*HEIGHT_PIXEL_UNIT*2,temp,WIDETH_PIXEL_UNIT*HEIGHT_PIXEL_UNIT);
temp=temp+0x44;
}
int startTime=GetTickCount();
StretchDIBits(hdc,0,0,WIDETH_PIXEL_UNIT,HEIGHT_PIXEL_UNIT,0,0,WIDETH_PIXEL_UNIT,HEIGHT_PIXEL_UNIT,pdata,&bmi,DIB_RGB_COLORS,SRCCOPY);
//SetDIBitsToDevice(hdc,0,0,WIDETH_PIXEL_UNIT,HEIGHT_PIXEL_UNIT,0,0,0,HEIGHT_PIXEL_UNIT,pdata,&bmi,DIB_RGB_COLORS);
int endTime=GetTickCount();
//Sleep(1000);
sum = sum + (endTime -startTime);
}
::ReleaseDC(m_hWnd,hdc) ;
CString result=L"";
result.Format(L"%d",sum/10);
SetDlgItemText(IDC_EDIT1,result);
free(pdata);
}
另外三个测试函数,大概就是替换了
SetDIBitsToDevice(hdc,0,0,WIDETH_PIXEL_UNIT,HEIGHT_PIXEL_UNIT,0,0,0,HEIGHT_PIXEL_UNIT,pdata,&bmi,DIB_RGB_COLORS);
StretchBlt(hdc,0,0,WIDETH_PIXEL_UNIT,HEIGHT_PIXEL_UNIT,hdcMem,0,0,WIDETH_PIXEL_UNIT,HEIGHT_PIXEL_UNIT,SRCCOPY);
BitBlt(hdc,0,0,WIDETH_PIXEL_UNIT,HEIGHT_PIXEL_UNIT,hdcMem,0,0,SRCCOPY);
另外我也贴一下我的测试结果:
测试环境 (A)
1024*600的16位深度 RGB16(ms) RGB24(ms)
DM3730,主频800
————————————————————————————————
1024*480 stretchDIBBits 94 stretchDIBBits 101
SetDIBitsToDevice 94 SetDIBitsToDevice 81
StretchBlt 94 StretchBlt 81
BitBlt 94 BitBlt 81
——————————————————————————————————————
800*480 stretchDIBBits 75 stretchDIBBits 79
SetDIBitsToDevice 75 SetDIBitsToDevice 65
StretchBlt 75 StretchBlt 65
BitBlt 75 BitBlt 65
——————————————————————————————————————
640*320 stretchDIBBits 39 stretchDIBBits 40
SetDIBitsToDevice 39 SetDIBitsToDevice 34
StretchBlt 39 StretchBlt 34
BitBlt 39 BitBlt 34
测试环境 (B)
800*480的16位深度 RGB16(ms) RGB24(ms)
DM3730,主频800
————————————————————————————————
1024*480 stretchDIBBits 65 stretchDIBBits 65
SetDIBitsToDevice 65 SetDIBitsToDevice 56
StretchBlt 65 StretchBlt 56
BitBlt 65 BitBlt 56
——————————————————————————————————————
800*480 stretchDIBBits 65 stretchDIBBits 65
SetDIBitsToDevice 65 SetDIBitsToDevice 56
StretchBlt 65 StretchBlt 56
BitBlt 65 BitBlt 56
——————————————————————————————————————
640*320 stretchDIBBits 38 stretchDIBBits 37
SetDIBitsToDevice 38 SetDIBitsToDevice 34
StretchBlt 38 StretchBlt 34
BitBlt 38 BitBlt 34
我没有其它平台,所以不知道其它平台会不会也这么慢,另外昨天跟EI稍微聊了一下,我们一致认为内存的拷贝也是一个重要的影响因素,我之前有做过测试内核空间的内存与用户空间内存的拷贝,1024*600*3大约是44MS,今天到时再做一个具体的测试,然后发上来。
希望大家测试自己的,然后再给一个结果上来大家分享一下,再个看我这些测试代码合不合理,不合理我们再来调整一下,最后整合了下,看是否有更好的效率提升手段。
[解决办法]
void
DDCreate16BitmapInfo(PBITMAPINFO pbminfo,int dx,int dy)
{
ZeroMemory(pbminfo, sizeof(BITMAPINFO));
// setup bitmap info
pbminfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
pbminfo->bmiHeader.biWidth = dx;
pbminfo->bmiHeader.biHeight = dy;
pbminfo->bmiHeader.biPlanes = 1;
pbminfo->bmiHeader.biBitCount = 16;
pbminfo->bmiHeader.biCompression = BI_RGB;
pbminfo->bmiHeader.biSizeImage = dx * dy * 2;// 图片缓冲区大小
return;
}
代码有问题,就算模拟器也比这个快,800x480全屏刷新大概30ms吧
首先要明确你的DIB和DDB格式一致,并且不缩放的时候速度是最快的
平台是16位色深度,也就是ddb是16位色的,一般是RGB565
所以16位色bmp的代码应该这样写
voidDDCreate16BitmapInfo(PBITMAPINFO pbminfo,int dx,int dy){ZeroMemory(pbminfo, sizeof(BITMAPINFO)); // setup bitmap info pbminfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); pbminfo->bmiHeader.biWidth = dx; pbminfo->bmiHeader.biHeight = dy; pbminfo->bmiHeader.biPlanes = 1; pbminfo->bmiHeader.biBitCount = 16; pbminfo->bmiHeader.biCompression = BI_BITFIELDS;pbminfo->bmiHeader.biSizeImage = 0;// pbminfo 需要分配额外的空间来存放掩码pbminfo->bmiColors[0].rgbBlue = 0; pbminfo->bmiColors[0].rgbGreen = 0xF8; pbminfo->bmiColors[0].rgbRed = 0; pbminfo->bmiColors[0].rgbReserved = 0; pbminfo->bmiColors[1].rgbBlue = 0xE0; pbminfo->bmiColors[1].rgbGreen = 0x07; pbminfo->bmiColors[1].rgbRed = 0; pbminfo->bmiColors[1].rgbReserved = 0; pbminfo->bmiColors[2].rgbBlue = 0x1F; pbminfo->bmiColors[2].rgbGreen = 0; pbminfo->bmiColors[2].rgbRed = 0; pbminfo->bmiColors[2].rgbReserved = 0; return;}
[解决办法]