网页功能: 加入收藏 设为首页 网站搜索  
一种计算机图形边沿平滑处理算法
发表日期:2007-01-16作者:[转贴] 出处:  

  所给代码只用于说明算法,不要直接使用,使用时需增加各种边界检测代码。例子图象只包含直线,但对曲线一样适用,且适合实时处理。主要思想集中在dot()函数中。对算法进行文字说明需要制作一些说明图片,暂时无法完成,以后可能会加上。

  效果图象

  灰度索引位图

#define imageWidth 320
#define imageHeight 240

BYTE grayBuf[64*64];

//灰度索引数组,存贮的内容见灰度索引位图,既可以由文件读取,也可以由软件生成

//画点函数,由其它函数调用,提供浮点坐标,buf为图象缓冲区
void dot(BYTE *buf,float fx,float fy)   
{
     int j,k;
     int x,y,dx,dy,dx1,dy1;
     BYTE *p = buf,bt;
     x = (int)fx , y = (int)fy;
     dx = (int)(((float)x - fx)*16);
     dy = (int)(((float)y - fy)*16);
     p += y*imageWidth+x;
     for(j=-3;j<4;j++)                  // 画一个7*7的正方形区域
     {     for(k=-3;k<4;k++)
          {
                dx1 = k*16+dx;
                dy1 = j*16+dy;
                if(dx1 < 0)
                dx1 = -dx1;
                if(dy1 < 0)
                dy1 = -dy1;
                bt = grayBuf[dy1*64+dx1];
                if(*p > bt)
                    *p = bt;
                p++;
           }
           p += imageWidth-7;
     }
}

 

void line(BYTE *buf,int x1,int y1,int x2,int y2)    // 画线函数,采用浮点计算,算法相当简单
{
     int dx,dy,i;
     float fx,fy,fdx,fdy;
     if(x1 > x2)
         dx = x1 - x2;
     else
         dx = x2 - x1;
     if(y1 > y2)
         dy = y1 - y2;
     else
         dy = y2 - y1;
     fdx = (float)(x2 - x1);
     fdy = (float)(y2 - y1);
     fx = (float)x1;
     fy = (float)y1;
     if(dx > dy)
     {
          fdx = fdx/dx;
          fdy = fdy/dx;
          for(i=0;i<dx;i++)
          {
               dot(buf,fx,fy);
               fx += fdx;
               fy += fdy;
          }
     }
     else
     {
          fdx = fdx/dy;
          fdy = fdy/dy;
          for(i=0;i<dy;i++)
          {
               dot(buf,fx,fy);
               fx += fdx;
               fy += fdy;
          }
     }
}

void show()                                    // 使用directX,将workBuf中的内容显示在屏幕上
{
     DDSURFACEDESC       ddsd;
     HRESULT             ddrval;
     ddsd.dwSize = sizeof(ddsd);
     BYTE *p1,*p2;
     CGif89a gif("e:\\gray.gif",TRUE);
     if(!gif)
         return;
     LPCFRAME fm = gif.getNextFrame();
     LPCGLOBAL_INFO gi = gif.getGlobalInfo();
     p1 = fm->dataBuf;
     p2 = grayBuf;
     for(int j=0;j<fm->imageHeight;j++)
     {    for(int k=0;k<fm->imageWidth;k++)
          {
              *p2++ = gi->gColorTable[(*p1++)*3];
          }
     }

     workBuf = new unsigned char[320*240];
     if(workBuf == NULL)
          return;
     memset(workBuf,255,320*240);

// dot(workBuf,100.0,100);
// dot(workBuf,110.2,100);
// dot(workBuf,120.3,100);
// dot(workBuf,130.4,100);

     line(workBuf,20,20,300,60);
     line(workBuf,20,40,300,160);
     line(workBuf,20,60,200,220);
     line(workBuf,20,80,80,220);

     DDBLTFX ddbltfx;
     ddbltfx.dwSize = sizeof(ddbltfx);
     ddbltfx.dwFillColor = 0x0000;
     lpDDSBack->Blt(NULL,NULL,NULL,DDBLT_COLORFILL|DDBLT_WAIT, &ddbltfx);
     while ((ddrval = lpDDSBack->Lock(NULL, &ddsd, 0, NULL)) == DDERR_WASSTILLDRAWING)
         ;
     if( ddrval == DD_OK )
     {
          UINT imgX,imgY,dspX,dspY,dspWidth,dspHeight,j,k;
          WORD *p;
          if(imageWidth > 800)
              dspWidth = 800,dspX = 0,imgX = (imageWidth-800)/2;
          else
              dspWidth = imageWidth,imgX = 0,dspX = (800-imageWidth)/2;
          if(imageHeight > 600)
              dspHeight = 600,dspY = 0,imgY = (imageHeight-600)/2;
          else
              dspHeight = imageHeight,imgY = 0,dspY = (600-imageHeight)/2;
          p = (WORD*)ddsd.lpSurface;
          p2 = workBuf;
          p += 800*dspY+dspX;
          p2 += imageWidth*imgY+imgX;
          for(j=0;j<dspHeight;j++)
          {
               for(k=0;k<dspWidth;k++)
               {
                   p[k] = (*RGBto16bit)(p2[k],p2[k],p2[k]);
               }
               p += 800;
               p2 += imageWidth;
          }
          lpDDSBack->Unlock(NULL);
     }
     while( 1 )
     {
           ddrval = lpDDSPrimary->Flip( NULL, 0 );
           if( ddrval == DD_OK )
           {
               break;
           }
           if( ddrval == DDERR_SURFACELOST )
           {
                ddrval = lpDDSPrimary->Restore();
                if( ddrval != DD_OK )
                    break;
           }
           if( ddrval != DDERR_WASSTILLDRAWING )
                break;
     }
     delete[] workBuf;
}

 

我来说两句】 【加入收藏】 【返加顶部】 【打印本页】 【关闭窗口
中搜索 一种计算机图形边沿平滑处理算法
本类热点文章
  DirectShow应用——支持Windows Media格..
  DirectShow PIN 連接教學
  游戏UI设计1
  PSD格式文件的读取
  将RGB值转换为灰度值的简单算法
  貼圖 filtering 與 MIP map 簡介
  读取万能图片以及DShow的另类用法
  TGA图像文件格式资料
  DirectShow初探
  PNG格式
  DirectShow应用——支持DVD播放
  DirectShow的中文资料之建立一个捕捉程序
最新分类信息我要发布 
最新招聘信息

关于我们 / 合作推广 / 给我留言 / 版权举报 / 意见建议 / 广告投放  
Copyright ©2003-2024 Lihuasoft.net webmaster(at)lihuasoft.net
网站编程QQ群   京ICP备05001064号 页面生成时间:0.00382