DrawDIBDraw显示图像颠倒的解决方法

来源:互联网 发布:dsdt editor mac 1.3 编辑:程序博客网 时间:2024/04/28 01:51

1.问题分析:

        Windows系统显示图像有视口和窗口两个概念,视口就是展现在显示器的区域,窗口就是源图像的位置,窗口一般是加载到windows系统的图片文件。视口一般是CRect定义的,坐标原点位于左上角。而窗口坐标即图片文件坐标在左下角,DrawDIBDraw也就是从左下角开始读数据,所以当视口和窗口的坐标不变的时候,视口中的图像是颠倒的,原因就是图片文件的最下层显示在了视口的最上层。

2.解决方法:

       把视口的坐标原点调整到与窗口坐标即图片文件坐标一致,都移到左下角。

3.程序实现: 

       以下代码红色字体即为调整视口坐标的代码,

       A.    int iMapMode= pDC->SetMapMode(MM_ANISOTROPIC);

              设置模式

       B.     pDC->SetViewportExt(1,-1);

               设置视口范围,前一个参数表示横坐标,后一个参数表示纵坐标,正数表示范围不变,负数表示翻转。这里(1,-1)表示视口坐标范围横坐标不变,纵坐标翻转,由原来的从上向下,变成从下向上。

       C.     pDC->SetViewportOrg(rcDraw.left,rcDraw.bottom);

                设置视口原点坐标,用left和bottom作为原点,也就是把坐标原点移到左下角。

       D.    DrawDibDraw(hdd,hdc1,0, 0, rcDraw.Width(),rcDraw.Height(), &pBitmapInfo->bmiHeader,data,

                          0,0,img_draw.cols,img_draw.rows, DDF_SAME_DRAW|DDF_SAME_HDC);

                坐标原点还按原来来写,都是0,0。

       E.     pDC->SetMapMode(iMapMode);

               恢复原来模式

F. 源代码

void DrawImage(Matimg,CRect rcDraw,CDCpDC,HDRAWDIB hdd)

{       

                 ...

                  //HDRAWDIBhdd = DrawDibOpen();//移到initDlg()函数中,原因是它耗用90%的时间

                  HDC hdc1 =pDC->GetSafeHdc();

                   BOOL rst =DrawDibBegin(hdd,hdc1,rcDraw.Width(),rcDraw.Height(),&pBitmapInfo->bmiHeader,img_show.cols,img.rows,DDF_SAME_HDC);

                   DrawDibRealize(hdd,hdc1,FALSE);

                  LPVOID data =img_show.data;

                  intiMapMode = pDC->SetMapMode(MM_ANISOTROPIC);

                  pDC->SetViewportExt(1,-1);

                  pDC->SetViewportOrg(rcDraw.left,rcDraw.bottom);

                  DrawDibDraw(hdd,hdc1,0, 0,rcDraw.Width(),rcDraw.Height(),&pBitmapInfo->bmiHeader,data,

                          0,0, img_show.cols,img_show.rows,DDF_SAME_DRAW|DDF_SAME_HDC);

                  pDC->SetMapMode(iMapMode);

                  DrawDibEnd(hdd);

                  DrawDibClose(hdd);

                  ...     

}

4.     DrawDIBDraw和StrentchBlt效率比较

    单个函数比较,前者较后者几乎提高3倍速度,但DrawDibOpen()函数非常慢,如果把它和DrawDIBDraw放在一个函数内,几乎占用90%的时间,所以这个函数要在外部执行。对于实时系统,连续不断执行DrawDIBDraw时,要把(HDRAWDIB hdd = DrawDibOpen())这句代码移到函数外,只执行一次,把HDRAWDIB参数传进来即可。


参考链接:http://bbs.csdn.net/topics/390168489

原创粉丝点击