为什么我的代码不呈现灰阶效果

问题描述:

这是我的代码为什么我的代码不呈现灰阶效果

// GrayScale.cpp : Defines the entry point for the application. 
// 

#include "stdafx.h" 
#include "GrayScale.h" 

#define MAX_LOADSTRING 100 

// Global Variables: 
HINSTANCE hInst;        // current instance 
TCHAR szTitle[MAX_LOADSTRING];     // The title bar text 
TCHAR szWindowClass[MAX_LOADSTRING];   // the main window class name 

// Forward declarations of functions included in this code module: 
ATOM    MyRegisterClass(HINSTANCE hInstance); 
BOOL    InitInstance(HINSTANCE, int); 
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); 
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM); 
BOOL    LoadBitmapFromBMPFile(LPTSTR, HBITMAP *); 

int APIENTRY _tWinMain(HINSTANCE hInstance, 
        HINSTANCE hPrevInstance, 
        LPTSTR lpCmdLine, 
        int  nCmdShow) 
{ 
    UNREFERENCED_PARAMETER(hPrevInstance); 
    UNREFERENCED_PARAMETER(lpCmdLine); 

    // TODO: Place code here. 
    MSG msg; 
    HACCEL hAccelTable; 

    // Initialize global strings 
    LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); 
    LoadString(hInstance, IDC_GRAYSCALE, szWindowClass, MAX_LOADSTRING); 
    MyRegisterClass(hInstance); 

    // Perform application initialization: 
    if (!InitInstance (hInstance, nCmdShow)) 
    { 
     return FALSE; 
    } 

    hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_GRAYSCALE)); 

    // Main message loop: 
    while (GetMessage(&msg, NULL, 0, 0)) 
    { 
     if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) 
     { 
      TranslateMessage(&msg); 
      DispatchMessage(&msg); 
     } 
    } 

    return (int) msg.wParam; 
} 



// 
// FUNCTION: MyRegisterClass() 
// 
// PURPOSE: Registers the window class. 
// 
// COMMENTS: 
// 
// This function and its usage are only necessary if you want this code 
// to be compatible with Win32 systems prior to the 'RegisterClassEx' 
// function that was added to Windows 95. It is important to call this function 
// so that the application will get 'well formed' small icons associated 
// with it. 
// 
ATOM MyRegisterClass(HINSTANCE hInstance) 
{ 
    WNDCLASSEX wcex; 

    wcex.cbSize = sizeof(WNDCLASSEX); 

    wcex.style   = CS_HREDRAW | CS_VREDRAW; 
    wcex.lpfnWndProc = WndProc; 
    wcex.cbClsExtra  = 0; 
    wcex.cbWndExtra  = 0; 
    wcex.hInstance  = hInstance; 
    wcex.hIcon   = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_GRAYSCALE)); 
    wcex.hCursor  = LoadCursor(NULL, IDC_ARROW); 
    wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); 
    wcex.lpszMenuName = MAKEINTRESOURCE(IDC_GRAYSCALE); 
    wcex.lpszClassName = szWindowClass; 
    wcex.hIconSm  = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); 

    return RegisterClassEx(&wcex); 
} 

// 
// FUNCTION: InitInstance(HINSTANCE, int) 
// 
// PURPOSE: Saves instance handle and creates main window 
// 
// COMMENTS: 
// 
//  In this function, we save the instance handle in a global variable and 
//  create and display the main program window. 
// 
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) 
{ 
    HWND hWnd; 

    hInst = hInstance; // Store instance handle in our global variable 

    hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, 
     CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); 

    if (!hWnd) 
    { 
     return FALSE; 
    } 

    ShowWindow(hWnd, nCmdShow); 
    UpdateWindow(hWnd); 

    return TRUE; 
} 

// 
// FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM) 
// 
// PURPOSE: Processes messages for the main window. 
// 
// WM_COMMAND - process the application menu 
// WM_PAINT - Paint the main window 
// WM_DESTROY - post a quit message and return 
// 
// 
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 
{ 
    int wmId, wmEvent; 
    PAINTSTRUCT ps; 
    HDC hdc; 
    HBITMAP hBMP; 

    switch (message) 
    { 
    case WM_COMMAND: 
     wmId = LOWORD(wParam); 
     wmEvent = HIWORD(wParam); 
     // Parse the menu selections: 
     switch (wmId) 
     { 
     case IDM_ABOUT: 
      DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); 
      break; 
     case IDM_EXIT: 
      DestroyWindow(hWnd); 
      break; 
     default: 
      return DefWindowProc(hWnd, message, wParam, lParam); 
     } 
     break; 
    case WM_PAINT: 

    PAINTSTRUCT ps; 
    HBITMAP  hBitmap, hOldBitmap; 
    HDC   hdc, hMemDC; 
    BITMAP  bm; 

    hdc = BeginPaint(hWnd, &ps); 

    if(LoadBitmapFromBMPFile(L"C://sample.bmp", &hBitmap)) 
    { 
     GetObject(hBitmap, sizeof(BITMAP), &bm); 
     hMemDC = CreateCompatibleDC(hdc); 
     hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap); 
     RealizePalette(hdc); 

     RGBQUAD rgbColors[256]; 
     UINT cColors = GetDIBColorTable(hdc, 0, 256, rgbColors); 
     for (UINT iColor = 0; iColor < cColors; iColor++) { 
     BYTE b = (BYTE)((30 * rgbColors[iColor].rgbRed + 
         59 * rgbColors[iColor].rgbGreen + 
         11 * rgbColors[iColor].rgbBlue)/100); 
     rgbColors[iColor].rgbRed = b; 
     rgbColors[iColor].rgbGreen = b; 
     rgbColors[iColor].rgbBlue = b; 
     } 
     SetDIBColorTable(hMemDC, 0, cColors, rgbColors); 

     BitBlt(hdc, 0, 0, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY); 

     SelectObject(hMemDC, hOldBitmap); 
     DeleteObject(hBitmap); 
    } 
     EndPaint(hWnd, &ps); 
     break; 
    case WM_DESTROY: 
     PostQuitMessage(0); 
     break; 
    default: 
     return DefWindowProc(hWnd, message, wParam, lParam); 
    } 
    return 0; 
} 

// Message handler for about box. 
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) 
{ 
    UNREFERENCED_PARAMETER(lParam); 
    switch (message) 
    { 
    case WM_INITDIALOG: 
     return (INT_PTR)TRUE; 

    case WM_COMMAND: 
     if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) 
     { 
      EndDialog(hDlg, LOWORD(wParam)); 
      return (INT_PTR)TRUE; 
     } 
     break; 
    } 
    return (INT_PTR)FALSE; 
} 

BOOL LoadBitmapFromBMPFile(LPTSTR szFileName, HBITMAP *phBitmap) 
    { 
    BITMAP bm; 
    *phBitmap = NULL; 

    // Use LoadImage() to get the image loaded into a DIBSection 
    *phBitmap = (HBITMAP)LoadImage(NULL, szFileName, IMAGE_BITMAP, 0, 0, 
       LR_CREATEDIBSECTION | LR_DEFAULTSIZE | LR_LOADFROMFILE); 
    if(*phBitmap == NULL) 
    return FALSE; 
    return TRUE; 
    } 

我以前的想法从http://blogs.msdn.com/b/oldnewthing/archive/2006/11/15/1081320.aspx呈现灰阶但显然没有颜色的反射,因为它看起来像原来的图像。

+0

我想这只会在源位图是8bpp时才起作用。 – 2014-09-04 08:47:49

+0

噢,这是糟糕的因为我使用位图深度为24的位图。猜猜我必须谷歌不同的代码 – 2014-09-04 08:50:04

要将加载的HBITMAP转换为灰度,您还可以修改像素本身。我摘录如下功能从代码更大块我写了前段时间:

BOOL convert2GrayScale(HBITMAP hBitmap) 
{ 
    BOOL result = FALSE; 
    DIBSECTION dib; 
    unsigned char *pPixel; 
    unsigned char *pEnd; 
    int gray; 


    if (GetObject(data->hGrayScale, sizeof(dib), (LPVOID)&dib) > 0) 
    { 
     result = TRUE; // assume success from now on... 

     pPixel = dib.dsBm.bmBits; 
     pEnd = &(pPixel[dib.dsBmih.biSizeImage]); 
     while (pPixel < pEnd) 
     { 
      switch (dib.dsBmih.biBitCount) 
      { 
//   case 8: 
//    todo... 
//    break; 

//   case 16: 
//    todo... 
//    break; 

      case 24: 
       /* average RGB value of pixel */ 
       gray = (int)pPixel[0] + (int)pPixel[1] + (int)pPixel[2];    
       gray /= 3; 

       /* modify RGB of current pixel */ 
       *pPixel++ = (unsigned char)gray; 
       *pPixel++ = (unsigned char)gray; 
       *pPixel++ = (unsigned char)gray; 
       break; 

      default: 
       result = FALSE; 
       pPixel = pEnd; // unsupported format ... leave everything as it is! 
       break; 
      } 
     } 
    } 

    return (result); 
} 

有一定更好的转换从彩色 - >灰度左右,但对于一个示范平均RGB值做这项工作。请注意(目前)此实现只能转换24位位图。

一个附加说明: 您可以不希望在每次接收WM_PAINT消息时加载位图...根据用户的操作,您的窗口每秒可能会收到许多这些消息。加载位图一次(WM_CREATE)并将其保存在某处(例如,在与窗口关联的分配结构中 - >SetWindowLongPtr(.., GWLP_USERDATA, ..))。