关于双缓存防闪烁的问题我用StretchDIBits在OnDraw函数里输出的图像

daniel_wang_1983 2008-04-18 09:59:41
图像输出没有问题,但是由于图像太大,在拉滚动条时,图像显示的很慢,实时性不太好。高手能不能根据我的程序的实际情况
提供一些帮助,最好是修改我的代码,或提供相应的代码!像素数据放在BYTE wDataBuffer[1024*2048];里



void CMyViewView::DrawBMP(CDC *pDC)
{
ReadText();
//8位位图调色板个数为256,每个RGBQUAD有4个元素,所以调色板所占内存空间为256×4
unsigned full_size = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)* 256;
//为BITMAPINFO结构分配内存
BITMAPINFO *bmp = (BITMAPINFO *) new unsigned char[full_size];
bmp-> bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmp-> bmiHeader.biWidth = 2048;
bmp-> bmiHeader.biHeight = 1024;
bmp-> bmiHeader.biPlanes = 1;
bmp-> bmiHeader.biBitCount = 8; //8位位图
bmp-> bmiHeader.biCompression = 0;
bmp-> bmiHeader.biSizeImage = 0;
bmp-> bmiHeader.biXPelsPerMeter = 0;
bmp-> bmiHeader.biYPelsPerMeter = 0;
bmp-> bmiHeader.biClrUsed = 0;
bmp-> bmiHeader.biClrImportant = 0;

//建立256级灰度调色板
for(int i=0;i<256;i++)
{
bmp-> bmiColors[i].rgbBlue = i;
bmp-> bmiColors[i].rgbGreen= i;
bmp-> bmiColors[i].rgbRed = i;
bmp-> bmiColors[i].rgbReserved=0;
}

//用RGB色与自定义调色板配对
// HBITMAP h_bitmap = ::CreateDIBSection(pDC-> m_hDC,bmp,DIB_RGB_COLORS,(LPVOID*)&wDataBuffer,NULL,0);
::StretchDIBits(pDC->m_hDC,0,0,2048,1024,0,0,2048,1024, wDataBuffer,(LPBITMAPINFO)bmp,DIB_RGB_COLORS,SRCCOPY);
delete []bmp;
}


void CMyViewView::OnDraw(CDC* pDC)
{
CMyViewDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
ReadText();
DrawBMP(pDC);
// delete wDataBuffer;
}

void CMyViewView::OnInitialUpdate()
{
CScrollView::OnInitialUpdate();

CSize sizeTotal;
// TODO: calculate the total size of this view
// ReadText();
sizeTotal.cx =2048;
sizeTotal.cy =1024;
SetScrollSizes(MM_TEXT, sizeTotal);
// SetScaleToFitSize(sizeTotal);
// delete wDataBuffer;
}
...全文
307 点赞 收藏 2
写回复
2 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
lop5712 2008-04-20
在OnDraw中已调用过ReadText,在DrawMap中再次调用ReadText,请确认ReadText是否消耗CPU。
另在DrawMap中每次即时new一个BITMAPINFO的做法非常不好,new对速度的影响是很大的,不过楼主这里只是调用一次问题也不大,不过对于楼主这种情况,更建议使用局部结构定义来消除在堆上分配内存,即类似下面书写:
void CMyViewView::DrawBMP( CDC *pDC )
{
ReadText();

struct TEMP_BITMAPINFO : public BITMAPINFO
{
RGBQUAD ColorsBuffer[255];

TEMP_BITMAPINFO( ULONG width, ULONG height )
{
bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
bmiHeader.biWidth = width;
bmiHeader.biHeight = height;
bmiHeader.biPlanes = 1;
bmiHeader.biBitCount = 8;
bmiHeader.biCompression = 0;
bmiHeader.biSizeImage = 0;
bmiHeader.biXPelsPerMeter = 0;
bmiHeader.biYPelsPerMeter = 0;
bmiHeader.biClrUsed = 0;
bmiHeader.biClrImportant = 0;

for( DWORD i = 0; i < 256; i++ )
{
bmiColors[ i ].rgbBlue = static_cast< BYTE >( i );
bmiColors[ i ].rgbGreen = static_cast< BYTE >( i );
bmiColors[ i ].rgbRed = static_cast< BYTE >( i );
bmiColors[ i ].rgbReserved = 0;
}
}
};
static TEMP_BITMAPINFO s_BitmapInfo( 2048, 1024 );

::StretchDIBits( pDC->m_hDC, 0, 0, 2048, 1024, 0, 0, 2048, 1024, NULL, &s_BitmapInfo, DIB_RGB_COLORS, SRCCOPY );
}
因为楼主对BITMAPINFO的初始化在每次DrawMap中的调用都一致,因此没必要每次DrawMap时都执行,使用局部静态保持只初始化一次。

不过楼主的绘制速度慢应该主要是因为位图太大,而不是简单的一次new。并且楼主又使用StretchDIBits这个超慢函数绘制,并且看得出来楼主并不需要拉伸,那么就不应该使用StretchDIBits,而应该直接使用BitBlt。构造一个设备无关位图,直接BitBlt速度可以极大提升。另外由于楼主是小窗口滚动显示图象,则应该每次即时获得滚动条位置和显示大小,手工计算出显示位置以调用BitBlts,而不是每次都进行2048*1024的大面积内存赋值(两次内存赋值的速度比一次整数乘法计算还慢,如果缓冲命中失败则更慢)。
回复
daniel_wang_1983 2008-04-20
大家多多指教啊!求救啊!
回复
相关推荐
发帖
VC/MFC
创建于2007-09-28

1.5w+

社区成员

VC/MFC相关问题讨论
申请成为版主
帖子事件
创建了帖子
2008-04-18 09:59
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……