通过本文主要向大家介绍了mmx,mmx轮毂,35mmx45mm,35mmx45mm是几寸,48mmx33mm等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com
本文实例讲述了基于Directx MMX 编写的实现图像灰度处理的方法,要编译此程序需DirectX SDK5.0,代码中所需要的ddutil.h与ddutil.cpp文件,请自行下载加入工程。在WindowNT4.0+SP3环境中编译通过,代码已经过整理,包含有注释。如下所示:
#include <windows.h> #include <windowsx.h> #include <stdio.h> #include <ddraw.h> #include <math.h> #include "ddutil.h" #define MEAN_GRAY 0//平均值法 #define MAXIMUM_GRAY 1//最大值法 #define WEIGHT_GRAY 2//加权平均值法 #define TITLE "灰度转换" //窗口标题 #define CLASSNAME "Gray" //窗口类名 #define WIDTH 640 #define HEIGHT 480 #define COLORS 8 #define STEP 1 #define SCANLINE 16 HINSTANCE hInst; //应用程序实例句柄 HWND hWndMain; //主窗口句柄 LPDIRECTDRAW lpDD; // DirectDraw对象 LPDIRECTDRAWSURFACE lpDDSPrimary; // 主页面 LPDIRECTDRAWSURFACE lpDDSBack; // 后台缓冲区 LPDIRECTDRAWSURFACE lpDDSPic1; // 离屏页面1 LPDIRECTDRAWPALETTE lpDDPal; // 调色板 BOOL bActive; // 应用程序是否活跃? int Key=0; bool Contrast=false; bool Gray=false; //函数声明 void FreeObjects( void ); BOOL InitDDraw(void); BOOL InitPalette(void); BOOL InitSurfaces(void); void UpdateFrame(void); void MakeRect(RECT *rect, long left, long top, long right, long bottom); void IncreaseContrast(BYTE *pByte,const int Low,const int Hight, const float Grad) { if(*pByte<=Low) *pByte=0; else if((Low<*pByte)&&(*pByte<Hight)) *pByte=(BYTE)((*pByte-Low)/Grad); else *pByte=255; } void ChangeContrast(int nDelta) { LPPALETTEENTRY Pal = (LPPALETTEENTRY) LocalAlloc( LPTR, sizeof( PALETTEENTRY ) * 256 ); //获取调色板 lpDDPal->GetEntries(0,0,256,Pal); int Low,High; float Grad; for(int i=0; i<256; i++) { if(nDelta>=0) { Low=0+nDelta; High=255-nDelta; Grad=((float)(High-Low))/255; IncreaseContrast(&Pal[i].peRed ,Low,High,Grad); IncreaseContrast(&Pal[i].peGreen ,Low,High,Grad); IncreaseContrast(&Pal[i].peBlue ,Low,High,Grad); } else { Pal[i].peRed=(BYTE)((int)(Pal[i].peRed/Grad))-nDelta; Pal[i].peGreen=(BYTE)((int)(Pal[i].peGreen/Grad))-nDelta; Pal[i].peBlue=(BYTE)((int)(Pal[i].peBlue/Grad))-nDelta; } } //更新调色板 lpDDPal->SetEntries(0,0,256,Pal); } //灰度转换函数--本程序的关键 //函数:ConvertToGrayScale //参数:Method为转换灰度的方式,值可为: // MAXIMUM_GRAY=最大值法,MEAN_GRAY=平均值法, // WEIGHT_GRAY=加权平均值法 // Color目前只能为8即只能处理8位调色板方式 //返值:无 void ConvertToGrayScale(unsigned short Method,unsigned short Color) { BYTE Convert; int i; switch(Color) { case 8: LPPALETTEENTRY Pal = (LPPALETTEENTRY) LocalAlloc( LPTR, sizeof( PALETTEENTRY ) * 256 ); //获取调色板 lpDDPal->GetEntries(0,0,256,Pal); switch(Method) { case MAXIMUM_GRAY: //最大值法转换 for(i=0; i<256; i++) { //计算的公式为:R=G=B=max(R,G,B) Convert=( max(max(Pal[i].peRed ,Pal[i].peGreen),Pal[i].peBlue)); Pal[i].peRed=Pal[i].peGreen=Pal[i].peBlue=Convert; } break; case MEAN_GRAY: //平均值法转换 for(i=0; i<256; i++) { //计算的公式为:R=G=B=(R+G+B)/3 Convert=((Pal[i].peRed +Pal[i].peGreen+Pal[i].peBlue)/3); Pal[i].peRed=Pal[i].peGreen=Pal[i].peBlue=Convert; } break; case WEIGHT_GRAY: //加权平均值法转换 for(i=0; i<256; i++) { //计算的公式为:R=G=B=(R*0.3+G*0.59+B*0.11) //为不使用浮点乘法,现公式为: //R=G=B=(R*3+G*6+B)/10 //些许的误差可以不计 Convert=( Pal[i].peRed * 3 + Pal[i].peGreen *6 + Pal[i].peBlue ) / 10; Pal[i].peRed=Pal[i].peGreen=Pal[i].peBlue=Convert; } break; } //更新调色板 lpDDPal->SetEntries(0,0,256,Pal); break; } } //********************************** //函数:FreeObject //功能:释放所有DirectDraw对象 void FreeObjects( void ) { if( lpDD != NULL )//释放DirectDraw对象 { if( lpDDSPrimary != NULL )//释放主页面 { lpDDSPrimary->Release(); lpDDSPrimary = NULL; } if( lpDDSPic1 != NULL )//释放离屏页面1 { lpDDSPic1->Release(); lpDDSPic1 = NULL; } if( lpDDPal != NULL )//释放调色板 { lpDDPal->Release(); lpDDPal = NULL; } lpDD->Release(); lpDD = NULL; } } //************************************ //函数:RestoreAll //功能:页面丢失后,恢复页面内存 HRESULT RestoreAll( void ) { HRESULT ddrval; //恢复主页面,这也将恢复换页链中的所有页面 ddrval = lpDDSPrimary->Restore(); //恢复离屏页面 ddrval = lpDDSPic1->Restore(); //重新绘制页面图象 InitSurfaces(); return ddrval; } //************************************** //函数:WindowProc //功能:主窗口的消息处理过程 LRESULT CALLBACK WinProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ) { switch( message ) { case WM_SETCURSOR: SetCursor(NULL); return TRUE; case WM_ACTIVATEAPP://应用程序激活消息 bActive = wParam; break; case WM_KEYDOWN://击键消息 switch( wParam ) { case VK_ESCAPE: PostMessage(hWnd, WM_CLOSE, 0, 0); break; case VK_F1: Gray=true; Key=MEAN_GRAY; InitPalette(); break; case VK_F2: Gray=true; Key=MAXIMUM_GRAY; InitPalette(); break; case VK_F3: Gray=true; Key=WEIGHT_GRAY; InitPalette(); break; case VK_F4: Gray=false; Key=0; InitPalette(); break; case VK_F5: Contrast=!Contrast; if(false==Contrast) { InitPalette(); } break; case VK_F6: break; } break; case WM_DESTROY://销毁窗口消息 FreeObjects(); PostQuitMessage(0); break; } //调用缺省的过程处理过程 return DefWindowProc(hWnd, message, wParam, lParam); } //********************************* //函数:InitWindow() //功能:创建主窗口。 BOOL InitWindow( HINSTANCE hInstance, int nCmdShow ) { WNDCLASS wc; //窗口类结构 //填充窗口类结构 wc.style = 0; wc.lpfnWndProc = WinProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon( hInstance, IDI_APPLICATION ); wc.hCursor = LoadCursor( NULL, IDC_ARROW ); wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);//选择黑色刷做为窗口背景 wc.lpszMenuName = NULL; wc.lpszClassName = CLASSNAME; //注册窗口类 RegisterClass( &wc ); //创建主窗口 hWndMain= CreateWindowEx( 0, CLASSNAME, //窗口的类名称,必须与上面的wc.lpszClassName一致 TITLE, //窗口的标题名 WS_POPUP, 0, 0, GetSystemMetrics( SM_CXSCREEN ), GetSystemMetrics( SM_CYSCREEN ), NULL, NULL, hInstance, NULL ); if( !hWndMain ) return FALSE; //显示并更新窗口 ShowWindow( hWndMain, nCmdShow ); return TRUE; } //********************************* //函数:InitDDraw() //功能:初始化DirectDraw环境,创建换页链(主页面,一个后台缓冲区) // 以及创建一个定时器。 BOOL InitDDraw(void) { DDSURFACEDESC ddsd; DDSCAPS ddscaps; HRESULT ddrval; //创建DirectDraw对象 ddrval = DirectDrawCreate( NULL, &lpDD, NULL ); if( ddrval != DD_OK ) return FALSE; //取得全屏独占模式 ddrval = lpDD->SetCooperativeLevel( hWndMain, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN ); if( ddrval != DD_OK ) return FALSE; //设置显示器显示模式为640x480x8 ddrval = lpDD->SetDisplayMode( WIDTH, HEIGHT, COLORS); if( ddrval != DD_OK ) return FALSE; //填充换页链结构 ddsd.dwSize = sizeof( ddsd ); ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX; //后台缓冲区数量为1 ddsd.dwBackBufferCount = 1; //创建换页链,包括了主页面及其后台缓冲区 ddrval = lpDD->CreateSurface( &ddsd, &lpDDSPrimary, NULL ); if( ddrval != DD_OK ) return FALSE; //获得指向后台缓冲区的页面指针 ddscaps.dwCaps = DDSCAPS_BACKBUFFER; ddrval = lpDDSPrimary->GetAttachedSurface(&ddscaps, &lpDDSBack); if( ddrval != DD_OK ) return FALSE; //创建离屏