亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

C++基于Directx MMX實(shí)現(xiàn)的圖像灰度轉(zhuǎn)換代碼

 更新時(shí)間:2014年08月11日 12:04:05   投稿:shichen2014  
這篇文章主要介紹了C++基于Directx MMX實(shí)現(xiàn)的圖像灰度轉(zhuǎn)換代碼,需要的朋友可以參考下

本文實(shí)例講述了基于Directx MMX 編寫的實(shí)現(xiàn)圖像灰度處理的方法,要編譯此程序需DirectX SDK5.0,代碼中所需要的ddutil.h與ddutil.cpp文件,請(qǐng)自行下載加入工程。在WindowNT4.0+SP3環(huán)境中編譯通過,代碼已經(jīng)過整理,包含有注釋。如下所示:

#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//加權(quán)平均值法
#define TITLE "灰度轉(zhuǎn)換" //窗口標(biāo)題
#define CLASSNAME "Gray" //窗口類名
#define WIDTH 640
#define HEIGHT 480
#define COLORS 8
#define STEP 1
#define SCANLINE 16
HINSTANCE hInst; //應(yīng)用程序?qū)嵗浔?
HWND hWndMain; //主窗口句柄
LPDIRECTDRAW      lpDD;      // DirectDraw對(duì)象
LPDIRECTDRAWSURFACE   lpDDSPrimary;  // 主頁面
LPDIRECTDRAWSURFACE   lpDDSBack;   // 后臺(tái)緩沖區(qū)
LPDIRECTDRAWSURFACE   lpDDSPic1;   // 離屏頁面1
LPDIRECTDRAWPALETTE   lpDDPal;    // 調(diào)色板
BOOL          bActive;    // 應(yīng)用程序是否活躍?
int Key=0;
bool Contrast=false;
bool Gray=false;
//函數(shù)聲明
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 );
 //獲取調(diào)色板
 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;
 }
 }
 //更新調(diào)色板
 lpDDPal->SetEntries(0,0,256,Pal);
}
//灰度轉(zhuǎn)換函數(shù)--本程序的關(guān)鍵
//函數(shù):ConvertToGrayScale
//參數(shù):Method為轉(zhuǎn)換灰度的方式,值可為:
// MAXIMUM_GRAY=最大值法,MEAN_GRAY=平均值法,
// WEIGHT_GRAY=加權(quán)平均值法
// Color目前只能為8即只能處理8位調(diào)色板方式
//返值:無
void ConvertToGrayScale(unsigned short Method,unsigned short Color)
{
 BYTE Convert; 
 int i;
 switch(Color)
 {
 case 8:
 LPPALETTEENTRY Pal = (LPPALETTEENTRY) LocalAlloc( LPTR, sizeof( PALETTEENTRY ) * 256 );
 //獲取調(diào)色板
 lpDDPal->GetEntries(0,0,256,Pal);
 switch(Method)
 {
 case MAXIMUM_GRAY:
  //最大值法轉(zhuǎn)換
  for(i=0; i<256; i++)
  {
  //計(jì)算的公式為: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:
  //平均值法轉(zhuǎn)換
  for(i=0; i<256; i++)
  {
  //計(jì)算的公式為: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:
  //加權(quán)平均值法轉(zhuǎn)換
  for(i=0; i<256; i++)
  {
  //計(jì)算的公式為:R=G=B=(R*0.3+G*0.59+B*0.11)
  //為不使用浮點(diǎn)乘法,現(xiàn)公式為:
  //R=G=B=(R*3+G*6+B)/10
  //些許的誤差可以不計(jì)
  Convert=( Pal[i].peRed * 3 + Pal[i].peGreen *6 + Pal[i].peBlue ) / 10; 
  Pal[i].peRed=Pal[i].peGreen=Pal[i].peBlue=Convert;
  } 
  break;  
 }
 //更新調(diào)色板
 lpDDPal->SetEntries(0,0,256,Pal);
 break;
 }
}
//**********************************
//函數(shù):FreeObject
//功能:釋放所有DirectDraw對(duì)象
void FreeObjects( void )
{
  if( lpDD != NULL )//釋放DirectDraw對(duì)象
  {
    if( lpDDSPrimary != NULL )//釋放主頁面
    {
      lpDDSPrimary->Release();
      lpDDSPrimary = NULL;
    }
    if( lpDDSPic1 != NULL )//釋放離屏頁面1
    {
      lpDDSPic1->Release();
      lpDDSPic1 = NULL;
    }
    if( lpDDPal != NULL )//釋放調(diào)色板
    {
      lpDDPal->Release();
      lpDDPal = NULL;
    }
    lpDD->Release();
    lpDD = NULL;
  }
} 
//************************************
//函數(shù):RestoreAll
//功能:頁面丟失后,恢復(fù)頁面內(nèi)存
HRESULT RestoreAll( void )
{
  HRESULT   ddrval;
 //恢復(fù)主頁面,這也將恢復(fù)換頁鏈中的所有頁面
  ddrval = lpDDSPrimary->Restore();
 //恢復(fù)離屏頁面
  ddrval = lpDDSPic1->Restore();
 //重新繪制頁面圖象
 InitSurfaces();
  return ddrval;
}
//**************************************
//函數(shù):WindowProc
//功能:主窗口的消息處理過程
LRESULT CALLBACK WinProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
  switch( message )
  {
  case WM_SETCURSOR:
 SetCursor(NULL);
 return TRUE;

  case WM_ACTIVATEAPP://應(yīng)用程序激活消息
    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;
  }

 //調(diào)用缺省的過程處理過程
  return DefWindowProc(hWnd, message, wParam, lParam);
}
//*********************************
//函數(shù):InitWindow()
//功能:創(chuàng)建主窗口。
BOOL InitWindow( HINSTANCE hInstance, int nCmdShow )
{
  WNDCLASS wc; //窗口類結(jié)構(gòu)
 //填充窗口類結(jié)構(gòu)
  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;
 //注冊(cè)窗口類
  RegisterClass( &wc );
  //創(chuàng)建主窗口
  hWndMain= CreateWindowEx(
 0,
 CLASSNAME, //窗口的類名稱,必須與上面的wc.lpszClassName一致
 TITLE, //窗口的標(biāo)題名
 WS_POPUP,
 0,
 0,
 GetSystemMetrics( SM_CXSCREEN ),
 GetSystemMetrics( SM_CYSCREEN ),
 NULL,
 NULL,
 hInstance,
 NULL );
  if( !hWndMain ) 
 return FALSE;
 //顯示并更新窗口
  ShowWindow( hWndMain, nCmdShow );
 return TRUE;
}
//*********************************
//函數(shù):InitDDraw()
//功能:初始化DirectDraw環(huán)境,創(chuàng)建換頁鏈(主頁面,一個(gè)后臺(tái)緩沖區(qū))
// 以及創(chuàng)建一個(gè)定時(shí)器。
BOOL InitDDraw(void)
{
  DDSURFACEDESC    ddsd;
  DDSCAPS       ddscaps;
  HRESULT       ddrval;

  //創(chuàng)建DirectDraw對(duì)象
 ddrval = DirectDrawCreate( NULL, &lpDD, NULL );
  if( ddrval != DD_OK )
    return FALSE;
  //取得全屏獨(dú)占模式
  ddrval = lpDD->SetCooperativeLevel( hWndMain, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN );
  if( ddrval != DD_OK )
    return FALSE;
  //設(shè)置顯示器顯示模式為640x480x8
  ddrval = lpDD->SetDisplayMode( WIDTH, HEIGHT, COLORS);
  if( ddrval != DD_OK )
    return FALSE;
  //填充換頁鏈結(jié)構(gòu)
  ddsd.dwSize = sizeof( ddsd );
  ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
  ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE |
             DDSCAPS_FLIP |
             DDSCAPS_COMPLEX;
 //后臺(tái)緩沖區(qū)數(shù)量為1
  ddsd.dwBackBufferCount = 1;
 //創(chuàng)建換頁鏈,包括了主頁面及其后臺(tái)緩沖區(qū)
  ddrval = lpDD->CreateSurface( &ddsd, &lpDDSPrimary, NULL );
  if( ddrval != DD_OK )
    return FALSE;
  //獲得指向后臺(tái)緩沖區(qū)的頁面指針
 ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
  ddrval = lpDDSPrimary->GetAttachedSurface(&ddscaps, &lpDDSBack);
  if( ddrval != DD_OK )
    return FALSE;
 //創(chuàng)建離屏頁面
 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;
 //調(diào)用頁面初始化函數(shù)
 if( !InitSurfaces() )
    return FALSE;
  return TRUE;
}
//**********************************
//函數(shù):WinMain()
//功能:應(yīng)用程序入口
int PASCAL WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow)
{
  MSG msg;
 hInst=hInstance;
 //初始化主窗口
 if (!InitWindow( hInstance, nCmdShow))
  return FALSE;
 //初始化DirectDraw環(huán)境
 if (!InitDDraw())
 {
 MessageBox(hWndMain, "初始化DirectDraw過程中出錯(cuò)!", "Error", MB_OK);
 FreeObjects();
 DestroyWindow(hWndMain);
 return FALSE;
 }
 //進(jìn)入消息循環(huán)
 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)
{
  //從磁盤文件中載入調(diào)色板
 lpDDPal = DDLoadPalette(lpDD, "back.bmp");
 //將調(diào)色板設(shè)置給主頁面
  if (lpDDPal)
 {
    lpDDSPrimary->SetPalette( lpDDPal );
 return TRUE;
 }
 return FALSE;
}
//****************************
//函數(shù):InitSurfaces()
//功能:初始化頁面圖象
BOOL InitSurfaces( void )
{
  HBITMAP hbm;
 InitPalette();
  //從磁盤文件中將我們所需要的圖象載入到一個(gè)hbm位圖對(duì)象中
  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位圖對(duì)象
  DeleteObject(hbm);
  return TRUE;
}
//更新屏幕
void UpdateFrame( void )
{
 HRESULT ddrval;
 //計(jì)算刷新率
 static int fps=0, frame=0, nt=0, ot=0;
 frame++;
 nt=timeGetTime(); 
 if (nt > ot+1000)
 {
 ot=nt;
 fps=frame;
 frame=0;
 }
 //清屏后臺(tái)緩沖區(qū)
 DDBLTFX ddBltFx;
 ddBltFx.dwSize = sizeof(DDBLTFX);
 ddBltFx.dwFillColor = DDColorMatch(lpDDSBack, RGB(0,0,0));
 lpDDSBack->Blt(NULL, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &ddBltFx);
 //調(diào)用灰度的實(shí)現(xiàn)函數(shù)
 if(true==Gray)
 {
 ConvertToGrayScale(Key,COLORS);
 Gray=false;
 }
 //增加對(duì)比度
 if(true==Contrast)
 {
 ChangeContrast(2);
 }

 RECT srect, drect;
 MakeRect(&srect, 0, 0, WIDTH, HEIGHT);
 MakeRect(&drect, 0, 0, WIDTH, HEIGHT);
 //將背景圖象Blit到后臺(tái)緩沖區(qū)
 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,"圖象特效----灰度轉(zhuǎn)換");
 TextOut(hdc, 30, 400, temp, strlen(temp));
 lpDDSBack->ReleaseDC(hdc);
  // 換頁
  while( 1 )
  {
    ddrval = lpDDSPrimary->Flip( NULL, DDFLIP_WAIT );//調(diào)用換頁函數(shù)
    if( ddrval == DD_OK )//成功則退出while循環(huán)
      break;
    else if( ddrval == DDERR_SURFACELOST )//如果頁面丟失,則恢復(fù)頁面,再繼續(xù)while循環(huán)
      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;
}

感興趣的朋友可以調(diào)試運(yùn)行一下本文實(shí)例,相信會(huì)對(duì)大家進(jìn)行C++項(xiàng)目開發(fā)起到一定的幫助作用。

相關(guān)文章

  • EasyC++模板重載

    EasyC++模板重載

    這篇文章主要介紹了C++模板重載,重載的模板的函數(shù)特征,也就是入?yún)⒌臄?shù)量和類型必須有所不同,下面我們講舉例說明此內(nèi)容,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2021-12-12
  • C++構(gòu)造函數(shù)和析構(gòu)函數(shù)的使用與講解

    C++構(gòu)造函數(shù)和析構(gòu)函數(shù)的使用與講解

    今天小編就為大家分享一篇關(guān)于C++構(gòu)造函數(shù)和析構(gòu)函數(shù)的使用與講解,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2018-12-12
  • C++?AVL樹插入新節(jié)點(diǎn)后的四種調(diào)整情況梳理介紹

    C++?AVL樹插入新節(jié)點(diǎn)后的四種調(diào)整情況梳理介紹

    AVL樹是高度平衡的而二叉樹,它的特點(diǎn)是AVL樹中任何節(jié)點(diǎn)的兩個(gè)子樹的高度最大差別為1,本文主要給大家介紹了C++如何實(shí)現(xiàn)AVL樹,需要的朋友可以參考下
    2022-08-08
  • 理解C++編程中的std::function函數(shù)封裝

    理解C++編程中的std::function函數(shù)封裝

    這篇文章主要介紹了理解C++編程中的std::function函數(shù)封裝,std::function是C++11標(biāo)準(zhǔn)中的新特性,需要的朋友可以參考下
    2016-04-04
  • vscode實(shí)現(xiàn)本地代碼自動(dòng)同步到遠(yuǎn)程機(jī)器的步驟

    vscode實(shí)現(xiàn)本地代碼自動(dòng)同步到遠(yuǎn)程機(jī)器的步驟

    這篇文章主要介紹了vscode實(shí)現(xiàn)本地代碼自動(dòng)同步到遠(yuǎn)程機(jī)器的步驟,本文分步驟給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-06-06
  • C/C++題解LeetCode1295統(tǒng)計(jì)位數(shù)為偶數(shù)的數(shù)字

    C/C++題解LeetCode1295統(tǒng)計(jì)位數(shù)為偶數(shù)的數(shù)字

    這篇文章主要為大家介紹了C/C++題解LeetCode1295統(tǒng)計(jì)位數(shù)為偶數(shù)的數(shù)字示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • 如何在C++中通過模板去除強(qiáng)制轉(zhuǎn)換

    如何在C++中通過模板去除強(qiáng)制轉(zhuǎn)換

    本文講解的是如何在C++中通過模板去除強(qiáng)制轉(zhuǎn)換,在編程工作中應(yīng)盡量少使用強(qiáng)制類型轉(zhuǎn)換,模板有助于我們實(shí)現(xiàn)這一目的,需要的朋友可以參考下
    2015-07-07
  • 淺析結(jié)束程序函數(shù)exit, _exit,atexit的區(qū)別

    淺析結(jié)束程序函數(shù)exit, _exit,atexit的區(qū)別

    在一個(gè)程序中最多可以用atexit()注冊(cè)32個(gè)處理函數(shù),這些處理函數(shù)的調(diào)用順序與其注冊(cè)的順序相反,也即最先注冊(cè)的最后調(diào)用,最后注冊(cè)的最先調(diào)用
    2013-09-09
  • c++下使用windows api遍歷指定文件夾及其子文件夾中的文件

    c++下使用windows api遍歷指定文件夾及其子文件夾中的文件

    這篇文章主要介紹了c++下使用windows api遍歷指定文件夾及其子文件夾中的文件實(shí)現(xiàn)代碼,一般都是通過c++自帶的函數(shù)實(shí)現(xiàn)
    2021-07-07
  • C++回溯算法中的全排列問題分析探討

    C++回溯算法中的全排列問題分析探討

    遞歸中遇到一個(gè)問題全排列的問題,我看見回溯特別神奇,特此記錄一下。對(duì)比一下深度優(yōu)先搜索與廣度優(yōu)先搜索,個(gè)人感覺這里的回溯像是一種遞歸樹中的深度優(yōu)先搜索的算法,他不斷構(gòu)造往下延伸的深度,使其達(dá)到完全編列
    2023-03-03

最新評(píng)論