亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C++ > 正文

C++基于Directx MMX實現的圖像灰度轉換代碼

2020-01-26 15:25:08
字體:
來源:轉載
供稿:網友

本文實例講述了基于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 16HINSTANCE hInst; //應用程序實例句柄HWND hWndMain; //主窗口句柄LPDIRECTDRAW      lpDD;      // DirectDraw對象LPDIRECTDRAWSURFACE   lpDDSPrimary;  // 主頁面LPDIRECTDRAWSURFACE   lpDDSBack;   // 后臺緩沖區LPDIRECTDRAWSURFACE   lpDDSPic1;   // 離屏頁面1LPDIRECTDRAWPALETTE   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; //創建離屏頁面 ZeroMemory(&ddsd, sizeof(ddsd));  ddsd.dwSize = sizeof(ddsd);  ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT |DDSD_WIDTH;  ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;  ddsd.dwWidth = WIDTH;  ddsd.dwHeight = HEIGHT;  if (lpDD->CreateSurface(&ddsd, &lpDDSPic1, NULL) != DD_OK) return FALSE; //調用頁面初始化函數 if( !InitSurfaces() )    return FALSE;  return TRUE;}//**********************************//函數:WinMain()//功能:應用程序入口int PASCAL WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow){  MSG msg; hInst=hInstance; //初始化主窗口 if (!InitWindow( hInstance, nCmdShow))  return FALSE; //初始化DirectDraw環境 if (!InitDDraw()) { MessageBox(hWndMain, "初始化DirectDraw過程中出錯!", "Error", MB_OK); FreeObjects(); DestroyWindow(hWndMain); return FALSE; } //進入消息循環 while(1) { if(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) {  if(!GetMessage(&msg, NULL, 0, 0 ))  return msg.wParam;  TranslateMessage(&msg);   DispatchMessage(&msg); } else if(bActive) {  UpdateFrame(); } else WaitMessage(); }  return msg.wParam;} BOOL InitPalette(void){  //從磁盤文件中載入調色板 lpDDPal = DDLoadPalette(lpDD, "back.bmp"); //將調色板設置給主頁面  if (lpDDPal) {    lpDDSPrimary->SetPalette( lpDDPal ); return TRUE; } return FALSE;}//****************************//函數:InitSurfaces()//功能:初始化頁面圖象BOOL InitSurfaces( void ){  HBITMAP hbm; InitPalette();  //從磁盤文件中將我們所需要的圖象載入到一個hbm位圖對象中  hbm = (HBITMAP)LoadImage(hInst, "back.bmp", IMAGE_BITMAP,  0, 0, LR_CREATEDIBSECTION|LR_LOADFROMFILE);  if (hbm == NULL) return FALSE; DDCopyBitmap(lpDDSPic1, hbm, 0, 0, WIDTH, HEIGHT); //釋放hbm位圖對象  DeleteObject(hbm);  return TRUE;}//更新屏幕void UpdateFrame( void ){ HRESULT ddrval; //計算刷新率 static int fps=0, frame=0, nt=0, ot=0; frame++; nt=timeGetTime();  if (nt > ot+1000) { ot=nt; fps=frame; frame=0; } //清屏后臺緩沖區 DDBLTFX ddBltFx; ddBltFx.dwSize = sizeof(DDBLTFX); ddBltFx.dwFillColor = DDColorMatch(lpDDSBack, RGB(0,0,0)); lpDDSBack->Blt(NULL, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &ddBltFx); //調用灰度的實現函數 if(true==Gray) { ConvertToGrayScale(Key,COLORS); Gray=false; } //增加對比度 if(true==Contrast) { ChangeContrast(2); } RECT srect, drect; MakeRect(&srect, 0, 0, WIDTH, HEIGHT); MakeRect(&drect, 0, 0, WIDTH, HEIGHT); //將背景圖象Blit到后臺緩沖區 lpDDSBack->Blt(&drect, lpDDSPic1, &srect, DDBLT_WAIT, NULL); //打印刷新率fps HDC hdc; char temp[50]; lpDDSBack->GetDC(&hdc); SetBkMode(hdc, TRANSPARENT); SetTextColor(hdc, RGB(0,255,255));  sprintf(temp, "fps=%d", fps); TextOut(hdc, 0, 0, temp, strlen(temp)); sprintf(temp,"圖象特效----灰度轉換"); TextOut(hdc, 30, 400, temp, strlen(temp)); lpDDSBack->ReleaseDC(hdc);  // 換頁  while( 1 )  {    ddrval = lpDDSPrimary->Flip( NULL, DDFLIP_WAIT );//調用換頁函數    if( ddrval == DD_OK )//成功則退出while循環      break;    else if( ddrval == DDERR_SURFACELOST )//如果頁面丟失,則恢復頁面,再繼續while循環      RestoreAll();    else  break; }}void MakeRect(RECT *rect, long left, long top, long right, long bottom){ rect->left=left; rect->top=top; rect->right=right; rect->bottom=bottom;}

感興趣的朋友可以調試運行一下本文實例,相信會對大家進行C++項目開發起到一定的幫助作用。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久久久久久999| 欧美成人激情视频免费观看| 在线播放精品一区二区三区| 日韩第一页在线| 日韩精品在线电影| 欧美视频一区二区三区…| www.亚洲免费视频| 亚洲最大福利视频| 中文字幕日韩综合av| 欧美激情视频网站| 欧美日韩亚洲视频一区| 久久久精品999| 亚洲欧洲中文天堂| 欧美电影免费观看高清| 亚洲视频在线免费观看| 国产一区二区三区三区在线观看| 中文字幕av一区二区三区谷原希美| 久久久视频免费观看| 欧美久久精品午夜青青大伊人| 国产亚洲欧洲在线| 成人两性免费视频| 韩国精品久久久999| 国产精品美女免费视频| 北条麻妃一区二区三区中文字幕| 欧美人在线视频| 欧美富婆性猛交| 国产精品678| 精品动漫一区二区三区| 国产在线拍揄自揄视频不卡99| 欧美日韩综合视频| 国产精品视频大全| 国产亚洲精品久久久| 国产精品第一页在线| 日韩激情片免费| 一区二区三区 在线观看视| 欧美成人一二三| 欧美亚洲在线观看| 亚洲精品视频在线播放| 亚洲毛茸茸少妇高潮呻吟| 日本伊人精品一区二区三区介绍| 亚洲高清av在线| 欧美视频二区36p| 亚洲一区二区精品| 久久精品电影一区二区| 久久免费视频网| 91精品成人久久| 亚洲专区在线视频| 亚洲成av人影院在线观看| 欧美网站在线观看| 精品女同一区二区三区在线播放| 国产日本欧美视频| 91免费人成网站在线观看18| 97精品一区二区三区| 欧美大码xxxx| 国产z一区二区三区| 久久人人爽人人爽爽久久| 成人在线观看视频网站| 色狠狠久久aa北条麻妃| 人人做人人澡人人爽欧美| 久久久国产精品视频| 日韩精品在线免费观看视频| 亚洲精品一区中文| 66m—66摸成人免费视频| 日韩精品在线观看一区二区| 久久亚洲精品视频| 色噜噜狠狠色综合网图区| 欧美成人性生活| 精品人伦一区二区三区蜜桃免费| 亚洲人成绝费网站色www| 91网站在线看| 日韩电影中文字幕在线| 精品国产一区二区三区久久狼5月| 精品成人乱色一区二区| 亚洲综合精品伊人久久| 俺去亚洲欧洲欧美日韩| 久久久久久综合网天天| 91精品国产色综合| 欧美一二三视频| 国产精品久久av| 中文字幕亚洲色图| 亚洲国内精品视频| 亚洲美女免费精品视频在线观看| 国产精品一区二区电影| 欧美做爰性生交视频| 久久综合电影一区| 久久免费在线观看| 国产精品第一第二| 亚洲视频欧美视频| 久久久久久久999精品视频| 欧美成人免费播放| 成人免费看吃奶视频网站| 色樱桃影院亚洲精品影院| 8x海外华人永久免费日韩内陆视频| 26uuu另类亚洲欧美日本一| 亚洲人成网站色ww在线| 国产精品欧美一区二区三区奶水| 国产日韩欧美电影在线观看| 久久99视频精品| 欧美午夜性色大片在线观看| 欧美性色xo影院| 国产98色在线| 亚洲www在线观看| 精品国产鲁一鲁一区二区张丽| 国产精品久久电影观看| 自拍视频国产精品| 欧美激情欧美激情在线五月| 国产精品嫩草影院一区二区| 精品女厕一区二区三区| 国产suv精品一区二区三区88区| 国产精品成人播放| 欧美日韩国产精品| 国产99在线|中文| 红桃视频成人在线观看| 91色精品视频在线| 国产精品入口免费视| 91精品啪在线观看麻豆免费| 欧美日韩一区二区三区在线免费观看| 国产综合视频在线观看| 美女精品视频一区| 欧美激情第6页| 日韩欧美在线一区| 久久躁狠狠躁夜夜爽| 国产精品网址在线| 日韩网站在线观看| www.久久久久久.com| 亚洲女成人图区| 国产精品永久免费在线| 国产精品美腿一区在线看| 清纯唯美日韩制服另类| 久久精品国产69国产精品亚洲| 亚洲人线精品午夜| 欧美老少配视频| 亚洲精品98久久久久久中文字幕| 日本欧美一二三区| 国产精品网站大全| 岛国av一区二区三区| 国产成人一区二区三区电影| 亚洲久久久久久久久久久| 91精品国产91久久久久福利| 久久视频在线看| 国产精品偷伦一区二区| 欧美精品精品精品精品免费| 精品视频—区二区三区免费| 欧美孕妇与黑人孕交| 日韩精品在线观看网站| 伊人亚洲福利一区二区三区| 欧美成人剧情片在线观看| 国产精品私拍pans大尺度在线| 国产精品欧美日韩久久| 国产精品久久久久久久午夜| 国产精品入口夜色视频大尺度| 国产精品专区第二| 日韩欧美在线第一页| 精品激情国产视频| 中文字幕av一区| 久久99久久久久久久噜噜| 国产精品久久久久久久久久久久久久| 欧美成年人视频网站| 91精品久久久久久久久久久| 4444欧美成人kkkk| 2019精品视频| 久久亚洲国产成人| 久久精品美女视频网站| 国产精品久久久久久久久免费看|