ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 영상처리 winapi 소스
    프로그래밍 언어/WinApi 2014. 10. 10. 10:20


    --------------------------

    기상 방송 같은 효과

    --------------------------


    ------- 기상 방송을 보면 아나운서가 파란 뒷 배경에서 설명하는데

    방송에서는 아나운서 뒤에 기상 그림이 나온다.

    이런 영상 효과를 내는 예제 소스이다. 웹캠이 연결되어 있어야하고

    같은 디렉토리 내에 image.bmp 파일이 있어야한다.


    #include <windows.h>

    #include "vfw.h"

    #pragma comment(lib, "vfw32.lib")


    #define BITMAP_MAXSIZE (1024*768*3+10)


    LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);

    HINSTANCE g_hInst;

    HWND HWndMain;

    LPCTSTR lpszClass=TEXT("WiseCat");


    int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance

    ,LPSTR lpszCmdParam,int nCmdShow)

    {

    HWND hWnd;

    MSG Message;

    WNDCLASS WndClass;

    g_hInst = hInstance;


    WndClass.cbClsExtra=0;

    WndClass.cbWndExtra=0;

    WndClass.hbrBackground=(HBRUSH)(COLOR_WINDOW+1);

    WndClass.hCursor=LoadCursor(NULL,IDC_ARROW);

    WndClass.hIcon=LoadIcon(NULL,IDI_APPLICATION);

    WndClass.hInstance=hInstance;

    WndClass.lpfnWndProc=WndProc;

    WndClass.lpszClassName=lpszClass;

    WndClass.lpszMenuName=NULL;

    WndClass.style=CS_HREDRAW | CS_VREDRAW;

    RegisterClass(&WndClass);


    hWnd=CreateWindow(  lpszClass

    ,lpszClass

    ,WS_OVERLAPPEDWINDOW

    ,CW_USEDEFAULT

    ,CW_USEDEFAULT

    ,CW_USEDEFAULT,CW_USEDEFAULT

    ,NULL

    ,(HMENU)NULL

    ,hInstance

    ,NULL);        

    ShowWindow(hWnd,nCmdShow);


    while(GetMessage(&Message,NULL,0,0))

    {

    TranslateMessage(&Message);

    DispatchMessage(&Message);

    }


    return (int)Message.wParam;

    }


    LRESULT CALLBACK FramInfo(HWND, LPVIDEOHDR);


    HWND vfw;

    BITMAPINFO Bm;

    HDC hdc;

    BITMAPFILEHEADER * stpBFH;

    BITMAPINFOHEADER * stpBIH;

    unsigned char * BMbuf;

    unsigned int uiPad;


    LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)

    {

    HANDLE hFile;

    PAINTSTRUCT ps;

    static unsigned int uiX;

    static unsigned int uiY;

    DWORD dwRead;


    switch(iMessage)

    {

    case WM_CREATE:

    HWndMain = hWnd;


    // Bitmap 열고 처리 //시작---------------------------------------------

    hFile = CreateFile(TEXT("image.bmp"),

    GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

    if(INVALID_HANDLE_VALUE != hFile)

    {

    BMbuf = (unsigned char *)malloc(BITMAP_MAXSIZE);

    ReadFile(hFile, BMbuf, BITMAP_MAXSIZE, &dwRead, NULL);

    CloseHandle(hFile);


    stpBFH = (BITMAPFILEHEADER *)BMbuf;

    stpBIH = (BITMAPINFOHEADER *)(BMbuf + sizeof(BITMAPFILEHEADER));


    uiX = (unsigned int)(stpBIH->biWidth);

    uiPad = uiX%4;

    uiY = (unsigned int)(stpBIH->biHeight);

    }

    // Bitmap 열고 처리 //끝-----------------------------------------------


    // 웹캠 설정 // 시작------------------------

    vfw = capCreateCaptureWindow(  TEXT("CAM")

    ,WS_CHILD | WS_VISIBLE

    ,0

    ,0

    ,400

    ,300

    ,hWnd

    ,NULL);


    capDriverConnect(vfw,0);

    capGetVideoFormat(vfw,&Bm,sizeof(Bm));

    Bm.bmiHeader.biWidth  = 320;

    Bm.bmiHeader.biHeight = 240;

    capSetVideoFormat(vfw,&Bm,sizeof(Bm));

    //capDlgVideoFormat(m_capwnd); 

    capSetCallbackOnFrame(vfw, FramInfo);

    capPreviewRate(vfw, 1);

    capPreview(vfw, FALSE);

    // 웹캠 설정 // 끝--------------------------

    return 0;


    case WM_PAINT:

    hdc = BeginPaint(hWnd,&ps);

    EndPaint(hWnd,&ps);

    return 0;


    case WM_DESTROY:

    free(BMbuf);

    PostQuitMessage(0);

    return 0;

    }

    return(DefWindowProc(hWnd,iMessage,wParam,lParam));

    }


    LRESULT CALLBACK FramInfo(HWND hWnd, LPVIDEOHDR lpData)

    {

    static int iCntX;

    static int iCntY;

    static int Jump;

    unsigned char * ucpPixel;


    // 원본 영상 그리기 // 시작-------------------------------

    hdc = GetDC(HWndMain);

    StretchDIBits(hdc  , 0

    , 0

    , Bm.bmiHeader.biWidth

    , Bm.bmiHeader.biHeight

    , 0

    , 0

    , Bm.bmiHeader.biWidth

    , Bm.bmiHeader.biHeight

    , lpData->lpData

    , &Bm

    , DIB_RGB_COLORS

    , SRCCOPY);

    // 원본 영상 그리기 // 끝---------------------------------


    // 영상 정보 편집 // 시작--------------------------------------------

    ucpPixel = BMbuf + stpBFH->bfOffBits - 3;

    Jump= 0;

    for(iCntY = 0; iCntY < Bm.bmiHeader.biHeight ; ++iCntY)  

    {        

    for(iCntX = 0; iCntX  < Bm.bmiHeader.biWidth  ; ++iCntX, Jump += 3)

    {

    ucpPixel = ucpPixel + 3;

    if(lpData->lpData[Jump + 2] > 100)

    {

    continue;

    }

    else if(lpData->lpData[Jump + 1] > 100)

    {

    continue;

    }

    else if(lpData->lpData[Jump + 0] > 50)

    {

    lpData->lpData[Jump] = *(ucpPixel + 0);  // Blue

    lpData->lpData[Jump + 2] = *(ucpPixel + 2);  // Red

    lpData->lpData[Jump + 1] = *(ucpPixel + 1);  // Green

    }

    }

    ucpPixel = ucpPixel + uiPad;

    }

    // 영상 정보 편집 // 끝----------------------------------------------


    // 편집된 영상 그리기 // 시작----------------------------

    StretchDIBits(hdc  , Bm.bmiHeader.biWidth +20

    , 0

    , Bm.bmiHeader.biWidth

    , Bm.bmiHeader.biHeight

    , 0

    , 0

    , Bm.bmiHeader.biWidth

    , Bm.bmiHeader.biHeight

    , lpData->lpData

    , &Bm

    , DIB_RGB_COLORS

    , SRCCOPY);

    // 편집된 영상 그리기 // 끝------------------------------


    ReleaseDC(HWndMain, hdc);


    return 0;

    }

    /*

    #include <windows.h>

    #include <Vfw.h>

    #pragma comment (lib,"vfw32.lib")


    #define BITMAP_MAXSIZE (1024*768*3+10)


    LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);

    HINSTANCE g_hInst;

    HWND hWndMain;

    LPCTSTR lpszClass=TEXT("Class");

    //WinMain 시작


    int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance

    ,LPSTR lpszCmdParam,int nCmdShow)

    {

    HWND hWnd;

    MSG Message;

    WNDCLASS WndClass;

    g_hInst=hInstance;

    //1. 윈도우 속성값 등록

    WndClass.cbClsExtra=0;

    WndClass.cbWndExtra=0;

    WndClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);

    WndClass.hCursor=LoadCursor(NULL,IDC_ARROW);

    WndClass.hIcon=LoadIcon(NULL, IDI_APPLICATION);

    WndClass.hInstance=hInstance;

    WndClass.lpfnWndProc=WndProc;

    WndClass.lpszClassName=lpszClass;

    WndClass.lpszMenuName=NULL;

    WndClass.style=CS_HREDRAW | CS_VREDRAW;

    RegisterClass(&WndClass);  //주소에 Write


    //2. 윈도우 생성

    hWnd=CreateWindow(lpszClass,lpszClass,WS_OVERLAPPEDWINDOW,

    CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,

    NULL, (HMENU)NULL,hInstance,NULL);

    ShowWindow(hWnd,nCmdShow); //화면에 뿌려줌


    //3. 메시지 처리(무한 반복)

    while (GetMessage(&Message,NULL,0,0))

    {

    TranslateMessage(&Message);

    DispatchMessage(&Message);

    }

    return (int)Message.wParam;

    }


    LRESULT CALLBACK FramInfo(HWND hVFW, LPVIDEOHDR VideoHdr);

    HBITMAP hBit;

    BITMAPINFO Bm;

    BITMAPFILEHEADER * stpBFH;

    BITMAPINFOHEADER * stpBIH;

    unsigned char * BMbuf;

    unsigned int uiPad;


    LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)

    {

    HDC hdc;

    HWND hVFW;

    PAINTSTRUCT ps;

    HANDLE hFile;

    static unsigned int uiX;

    static unsigned int uiY;

    DWORD dwRead;


    switch(iMessage)

    {

    case WM_CREATE:

    hWndMain=hWnd;

    hdc=GetDC(hWndMain);


    // Bitmap 열기 //-------------------------------------------------------

    hFile = CreateFile(TEXT("image.bmp"),

    GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

    if(INVALID_HANDLE_VALUE != hFile)

    {

    BMbuf = (unsigned char *)malloc(BITMAP_MAXSIZE);

    ReadFile(hFile, BMbuf, BITMAP_MAXSIZE, &dwRead, NULL);

    CloseHandle(hFile);


    stpBFH = (BITMAPFILEHEADER *)BMbuf;

    stpBIH = (BITMAPINFOHEADER *)(BMbuf + sizeof(BITMAPFILEHEADER));


    uiX = (unsigned int)(stpBIH->biWidth);

    uiPad = uiX%4;

    uiY = (unsigned int)(stpBIH->biHeight);

    }

    // Bitmap 그리기 //끝-----------------------------------------------


    hVFW=capCreateCaptureWindow(TEXT("VFW"),WS_CHILD | WS_VISIBLE , 0,0,320,240,hWnd,0);

    capDriverConnect(hVFW,0);

    capPreviewRate(hVFW,10);

    capGetVideoFormat(hVFW,&Bm, sizeof(Bm));

    Bm.bmiHeader.biWidth = 320;

    Bm.bmiHeader.biHeight = 240;

    capSetVideoFormat(hVFW, &Bm, sizeof(Bm));

    capPreview(hVFW,TRUE);


    hBit = CreateCompatibleBitmap(hdc, Bm.bmiHeader.biWidth,Bm.bmiHeader.biHeight);


    if (capSetCallbackOnFrame(hVFW,FramInfo) == FALSE)

    {

    return FALSE;

    }

    ReleaseDC(hWndMain, hdc);

    return 0;

    case WM_PAINT:

    hdc = BeginPaint(hWnd, &ps);

    EndPaint(hWnd, &ps);

    return 0;

    case WM_DESTROY:

    free(BMbuf);

    PostQuitMessage(0);

    return 0;

    }

    return(DefWindowProc(hWnd, iMessage, wParam, lParam));

    }

    LRESULT CALLBACK FramInfo(HWND hVFW, LPVIDEOHDR VideoHdr)

    {

    HDC hdc;

    HDC hMemDC;

    HBITMAP OldBitmap;

    int iCntX;

    int iCntY;

    int Jump;

    int avr;

    unsigned char * ucpPixel;


    hdc = GetDC(hWndMain);

    hMemDC = CreateCompatibleDC(hdc);

    OldBitmap = (HBITMAP)SelectObject(hMemDC, hBit);


    ucpPixel = BMbuf + stpBFH->bfOffBits;

    Jump=0;

    for (iCntY=0 ; iCntY < Bm.bmiHeader.biHeight ; ++iCntY)

    {

    //for (iCntX=0 ; iCntX < Bm.bmiHeader.biWidth ; ++iCntX)

    for (iCntX=Bm.bmiHeader.biWidth-1 ; 0 <= iCntX ; --iCntX)

    {


    // 특정 색 전환

    if(VideoHdr->lpData[Jump+2] > 150)// && VideoHdr->lpData[Jump+2] > 40)

    {

    if(VideoHdr->lpData[Jump+1] > 150)// && VideoHdr->lpData[Jump+1] > 70)

    {

    if(VideoHdr->lpData[Jump+0] > 150)// && VideoHdr->lpData[Jump+0] > 70)

    {

    VideoHdr->lpData[Jump+2] = *(ucpPixel+2);

    VideoHdr->lpData[Jump+1] = *(ucpPixel+1);

    VideoHdr->lpData[Jump+0] = *(ucpPixel+0);

    }

    }

    }


    //원영상

    SetPixel(hMemDC, iCntX,(Bm.bmiHeader.biHeight - iCntY)-1,

    RGB(VideoHdr->lpData[Jump+2], VideoHdr->lpData[Jump+1], VideoHdr->lpData[Jump]));

    //   SetPixel(hMemDC, iCntX,(Bm.bmiHeader.biHeight - iCntY)-1, RGB(0xC3&(VideoHdr->lpData[Jump+2]), 0xC3&(VideoHdr->lpData[Jump+1]), 0xC3&(VideoHdr->lpData[Jump])));

    // avr = (VideoHdr->lpData[Jump+2]+VideoHdr->lpData[Jump+1]+VideoHdr->lpData[Jump])/3;

    // if(avr < 200)

    // avr = 0;

    // SetPixel(hMemDC, iCntX,(Bm.bmiHeader.biHeight - iCntY)-1, RGB(avr, avr, avr));


    Jump+=3;

    ucpPixel = ucpPixel + 3;

    }

    ucpPixel = ucpPixel + uiPad;

    }


    //------------------------------------------------------------------------------

    BitBlt(hdc, 320,0,Bm.bmiHeader.biWidth,Bm.bmiHeader.biHeight,hMemDC,0,0,SRCCOPY);

    SelectObject(hMemDC,OldBitmap);

    ReleaseDC(hWndMain,hdc);

    return 0;

    }

    */


    결과





    왼쪽이 원본, 오른쪽이 특정 색은 다른 영상 이미지로 대체












    -------------------------

    웹캠 영상 처리

    -------------------------


    ------- 웹캠으로 촬영된 영상을 스트레칭, 평활화등 영상 처리한 소스이다.



    #include <windows.h>

    #include <Vfw.h>

    #pragma comment (lib,"vfw32.lib")


    #define BITMAP_MAXSIZE (1024*768*3+10)


    LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);

    HINSTANCE g_hInst;

    HWND hWndMain;

    LPCTSTR lpszClass=TEXT("Class");

    //WinMain 시작


    int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance

    ,LPSTR lpszCmdParam,int nCmdShow)

    {

    HWND hWnd;

    MSG Message;

    WNDCLASS WndClass;

    g_hInst=hInstance;

    //1. 윈도우 속성값 등록

    WndClass.cbClsExtra=0;

    WndClass.cbWndExtra=0;

    WndClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);

    WndClass.hCursor=LoadCursor(NULL,IDC_ARROW);

    WndClass.hIcon=LoadIcon(NULL, IDI_APPLICATION);

    WndClass.hInstance=hInstance;

    WndClass.lpfnWndProc=WndProc;

    WndClass.lpszClassName=lpszClass;

    WndClass.lpszMenuName=NULL;

    WndClass.style=CS_HREDRAW | CS_VREDRAW;

    RegisterClass(&WndClass);  //주소에 Write


    //2. 윈도우 생성

    hWnd=CreateWindow(lpszClass,lpszClass,WS_OVERLAPPEDWINDOW,

    CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,

    NULL, (HMENU)NULL,hInstance,NULL);

    ShowWindow(hWnd,nCmdShow); //화면에 뿌려줌


    //3. 메시지 처리(무한 반복)

    while (GetMessage(&Message,NULL,0,0))

    {

    TranslateMessage(&Message);

    DispatchMessage(&Message);

    }

    return (int)Message.wParam;

    }


    LRESULT CALLBACK FramInfo(HWND hVFW, LPVIDEOHDR VideoHdr);

    HBITMAP hBit;

    BITMAPINFO Bm;

    unsigned char * ucpPixel;

    BITMAPFILEHEADER * stpBFH;

    BITMAPINFOHEADER * stpBIH;

    unsigned char * BMbuf;

    unsigned int uiPad;


    LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)

    {

    HDC hdc;

    HWND hVFW;

    PAINTSTRUCT ps;

    HANDLE hFile;

    static unsigned int uiX;

    static unsigned int uiY;

    unsigned int uiXcount;

    unsigned int uiYcount;

    DWORD dwRead;

    HBITMAP OldBitmap;


    switch(iMessage)

    {

    case WM_CREATE:

    hWndMain=hWnd;

    hdc=GetDC(hWndMain);


    // Bitmap 열고 설정 //시작-----------------------------------------------------

    hFile = CreateFile(TEXT("image.bmp"),

    GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

    if(INVALID_HANDLE_VALUE != hFile)

    {

    BMbuf = (unsigned char *)malloc(BITMAP_MAXSIZE);

    ReadFile(hFile, BMbuf, BITMAP_MAXSIZE, &dwRead, NULL);

    CloseHandle(hFile);


    stpBFH = (BITMAPFILEHEADER *)BMbuf;

    stpBIH = (BITMAPINFOHEADER *)(BMbuf + sizeof(BITMAPFILEHEADER));


    uiX = (unsigned int)(stpBIH->biWidth);

    uiPad = uiX%4;

    uiY = (unsigned int)(stpBIH->biHeight);

    }

    // Bitmap 열고 설정 //끝-------------------------------------------------------


        // 웹캠 설정 // 시작----------------------------------------------------------------------

    hVFW=capCreateCaptureWindow(TEXT("VFW"),WS_CHILD | WS_VISIBLE , 0,0,320,240,hWnd,0);

    capDriverConnect(hVFW,0);

    capPreviewRate(hVFW,10);

    capGetVideoFormat(hVFW,&Bm, sizeof(Bm));

    Bm.bmiHeader.biWidth = 320;

    Bm.bmiHeader.biHeight = 240;

    capSetVideoFormat(hVFW, &Bm, sizeof(Bm));

    capPreview(hVFW,TRUE);


    hBit = CreateCompatibleBitmap(hdc, Bm.bmiHeader.biWidth,Bm.bmiHeader.biHeight);


    if (capSetCallbackOnFrame(hVFW,FramInfo) == FALSE)

    {

    return FALSE;

    }

        // 웹캠 설정 // 끝------------------------------------------------------------------------


    ReleaseDC(hWndMain, hdc);

    return 0;

    case WM_PAINT:

    hdc = BeginPaint(hWnd, &ps);

    EndPaint(hWnd, &ps);

    return 0;

    case WM_DESTROY:

    free(BMbuf);

    PostQuitMessage(0);

    return 0;

    }

    return(DefWindowProc(hWnd, iMessage, wParam, lParam));

    }

    LRESULT CALLBACK FramInfo(HWND hVFW, LPVIDEOHDR VideoHdr)

    {

    HDC hdc;

    HDC hMemDC;

    HBITMAP OldBitmap;

    int iCntX;

    int iCntY;

    int Jump;

    int avr;

    int Rhigh, Ghigh, Bhigh;

    int Rlow, Glow, Blow;

    unsigned int uiXcount;

    unsigned int uiYcount;

    unsigned int uiRcnt[256];

    unsigned int uiGcnt[256];

    unsigned int uiBcnt[256];

    unsigned int uiRhisto[256];  // 평활화로 사용할 변수

    unsigned int uiGhisto[256];  // 평활화로 사용할 변수

    unsigned int uiBhisto[256];  // 평활화로 사용할 변수


    hdc = GetDC(hWndMain);

    hMemDC = CreateCompatibleDC(hdc);

    OldBitmap = (HBITMAP)SelectObject(hMemDC, hBit);


    // 원본 영상 그리기 // 시작------------------------------------------------------

    ucpPixel = BMbuf + stpBFH->bfOffBits;

    Jump=0;

    for (iCntY=0 ; iCntY < Bm.bmiHeader.biHeight ; ++iCntY)

    {

    //for (iCntX=0 ; iCntX < Bm.bmiHeader.biWidth ; ++iCntX)    // 좌우 반전

    for (iCntX=Bm.bmiHeader.biWidth-1 ; 0 <= iCntX ; --iCntX)

    {

    // 영상 정보 수집 // 시작-------------

    ++uiRcnt[VideoHdr->lpData[Jump+2]];

    ++uiGcnt[VideoHdr->lpData[Jump+1]];

    ++uiBcnt[VideoHdr->lpData[Jump+0]];

    // 영상 정보 수집 // 끝---------------


    // 영상 출력

    SetPixel(hMemDC, iCntX,(Bm.bmiHeader.biHeight - iCntY)-1,

    RGB(VideoHdr->lpData[Jump+2], VideoHdr->lpData[Jump+1], VideoHdr->lpData[Jump]));


    // 영상 흑백으로 전환 // 시작----------------------------------------------------------------

    // avr = (VideoHdr->lpData[Jump+2]+VideoHdr->lpData[Jump+1]+VideoHdr->lpData[Jump])/3;

    // if(avr < 200)

    // avr = 0;

    // SetPixel(hMemDC, iCntX,(Bm.bmiHeader.biHeight - iCntY)-1, RGB(avr, avr, avr));

    // 영상 흑백으로 전환 // 끝------------------------------------------------------------------


    Jump+=3;    // 다음 픽셀

    ucpPixel = ucpPixel + 3;    // 다음 픽셀

    }

    ucpPixel = ucpPixel + uiPad;    // 패드만큼 다음 가리킴

    }

    // 원본 영상 그리기 // 끝--------------------------------------------------------


    // 영상 정보 처리 // 시작-----------------------------

    for(uiXcount = 0; 256 > uiXcount; ++uiXcount)

    {

    if(uiRcnt[uiXcount] != 0)

    {

    Rlow = uiXcount;

    break;

    }

    }

    for(uiXcount = 255; 0 <= uiXcount; --uiXcount)

    {

    if(uiRcnt[uiXcount] != 0)

    {

    Rhigh = uiXcount;

    break;

    }

    }


    for(uiXcount = 0; 256 > uiXcount; ++uiXcount)

    {

    if(uiGcnt[uiXcount] != 0)

    {

    Glow = uiXcount;

    break;

    }

    }

    for(uiXcount = 255; 0 <= uiXcount; --uiXcount)

    {

    if(uiGcnt[uiXcount] != 0)

    {

    Ghigh = uiXcount;

    break;

    }

    }


    for(uiXcount = 0; 256 > uiXcount; ++uiXcount)

    {

    if(uiBcnt[uiXcount] != 0)

    {

    Blow = uiXcount;

    break;

    }

    }

    for(uiXcount = 255; 0 <= uiXcount; --uiXcount)

    {

    if(uiBcnt[uiXcount] != 0)

    {

    Bhigh = uiXcount;

    break;

    }

    }


    // 누적

    uiXcount = 0;

    uiRhisto[uiXcount] = uiRcnt[uiXcount];

    uiGhisto[uiXcount] = uiGcnt[uiXcount];

    uiBhisto[uiXcount] = uiBcnt[uiXcount];

    for(uiXcount = 1; 256 > uiXcount; ++uiXcount)

    {

    uiRhisto[uiXcount] = (uiRhisto[uiXcount-1] + uiRcnt[uiXcount]);

    uiGhisto[uiXcount] = (uiGhisto[uiXcount-1] + uiGcnt[uiXcount]);

    uiBhisto[uiXcount] = (uiBhisto[uiXcount-1] + uiBcnt[uiXcount]);

    }


    // 계산

    for(uiXcount = 0; 256 > uiXcount; ++uiXcount)

    {

    uiRhisto[uiXcount] = (uiRhisto[uiXcount] * 255) / (Bm.bmiHeader.biHeight*Bm.bmiHeader.biWidth);

    uiGhisto[uiXcount] = (uiGhisto[uiXcount] * 255) / (Bm.bmiHeader.biHeight*Bm.bmiHeader.biWidth);

    uiBhisto[uiXcount] = (uiBhisto[uiXcount] * 255) / (Bm.bmiHeader.biHeight*Bm.bmiHeader.biWidth);

    }

    // 영상 정보 처리 // 끝-------------------------------


      // 편집된 영상 이미지 정보 수정 // 시작-------------------------------

    Jump=0;

    for (iCntY=0 ; iCntY < Bm.bmiHeader.biHeight ; ++iCntY)

    {

    for (iCntX=0 ; iCntX < Bm.bmiHeader.biWidth ; ++iCntX)

    {

    /*

    //평활화 + 스트레칭

    VideoHdr->lpData[Jump+2] = uiRhisto[(((VideoHdr->lpData[Jump+2])-Rlow) * 255) / (Rhigh - Rlow)];

    VideoHdr->lpData[Jump+1] = uiGhisto[(((VideoHdr->lpData[Jump+1])-Glow) * 255) / (Ghigh - Glow)];

    VideoHdr->lpData[Jump] = uiBhisto[(((VideoHdr->lpData[Jump+1])-Blow) * 255) / (Bhigh - Blow)];

    */


    //스트레칭

    VideoHdr->lpData[Jump+2] = (((VideoHdr->lpData[Jump+2])-Rlow) * 255) / (Rhigh - Rlow);

    VideoHdr->lpData[Jump+1] = (((VideoHdr->lpData[Jump+1])-Glow) * 255) / (Ghigh - Glow);

    VideoHdr->lpData[Jump] = (((VideoHdr->lpData[Jump+1])-Blow) * 255) / (Bhigh - Blow);


    /*

    //평활화

    VideoHdr->lpData[Jump+2] = uiRhisto[VideoHdr->lpData[Jump+2]];

    VideoHdr->lpData[Jump+1] = uiGhisto[VideoHdr->lpData[Jump+1]];

    VideoHdr->lpData[Jump] = uiBhisto[VideoHdr->lpData[Jump+1]];

    */

    //원영상

    //   SetPixel(hMemDC, iCntX,(Bm.bmiHeader.biHeight - iCntY)-1,

    // RGB(VideoHdr->lpData[Jump+2], VideoHdr->lpData[Jump+1], VideoHdr->lpData[Jump]));

    Jump+=3;

    }

    }

    // 편집된 영상 이미지 정보 수정 // 시작-------------------------------


    BitBlt(hdc, 320,0,Bm.bmiHeader.biWidth,Bm.bmiHeader.biHeight,hMemDC,0,0,SRCCOPY);

    SelectObject(hMemDC,OldBitmap);

    ReleaseDC(hWndMain,hdc);

    // Sleep(100);

    return 0;

    }



    /*

    // 선생님 소스

    #include <windows.h>

    #include "vfw.h"

    #pragma comment(lib, "vfw32.lib")


    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

    LRESULT CALLBACK FramInfo(HWND, LPVIDEOHDR);


    HINSTANCE g_hInst;

    HWND hWndMain;

    HWND hVFW;

    HWND Hwndmain;

    HBITMAP hBit;

    BITMAPINFO Bm;

    LPCTSTR lpszClass=TEXT("VFW");



    LRESULT CALLBACK WndProc( HWND hWnd

    , UINT iMessage

    , WPARAM wParam

    , LPARAM lParam)

    {

    HDC Hdc;


    switch(iMessage)

    {

    case WM_CREATE:

    Hwndmain = hWnd;

    Hdc  = GetDC(hWnd);

    hVFW = capCreateCaptureWindow(

    TEXT("VFW"),

    WS_CHILD | WS_VISIBLE,

    0,

    0,

    1,

    1,

    hWnd,

    0);

    capDriverConnect(hVFW, 0);

    capPreviewRate(hVFW, 1);

    capPreview(hVFW, TRUE);

    capGetVideoFormat(hVFW, &Bm, sizeof(Bm));

    hBit = CreateCompatibleBitmap( Hdc

    , Bm.bmiHeader.biWidth

    , Bm.bmiHeader.biHeight);

    if (capSetCallbackOnFrame(hVFW, FramInfo) == FALSE)

    {

    return FALSE;

    }

    ReleaseDC(hWnd, Hdc);

    return 0;


    case WM_DESTROY:

    PostQuitMessage(0);

    return 0;

    }

    return (DefWindowProc(hWnd, iMessage, wParam, lParam));

    }


    LRESULT CALLBACK FramInfo(HWND hVFW, LPVIDEOHDR VideoHdr)

    {

    HDC Hdc;

    HDC hMemDC;

    HBITMAP OldBitmap;


    Hdc = GetDC(Hwndmain);

    hMemDC = CreateCompatibleDC(Hdc);

    OldBitmap = (HBITMAP)SelectObject(hMemDC, hBit);


    BitBlt( Hdc

    , 0

    , 0

    , Bm.bmiHeader.biWidth

    , Bm.bmiHeader.biHeight

    , hMemDC

    , 0

    , 0

    , SRCCOPY);

    SelectObject(hMemDC,OldBitmap);

    DeleteDC(hMemDC);

    ReleaseDC(Hwndmain, Hdc);


    return 0;

    }

    */


    결과




    왼쪽이 원본 영상, 오른쪽이 평활화 & 스트레칭 처리된 영상이다.

    원본의 왼쪽에 어두워 잘 안보이는데,

    처리된 영상을 보면 어두운 부분이 보이게 처리된 것을 확인할 수 있다.











    ----------------

    이미지 평활화

    ----------------


    ------- 비트맵 이미지를 평활화 처리하는 소스


    #include <windows.h>


    #define BITMAP_MAXSIZE (1024*768*3+10)

    #define XOFFSET 280

    #define X_WIDTH_SIZE 100

    #define ALPA

    #define SCREEN_Y_SIZE 270*2

    #define SCROLL_SIZE 100*6


    LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);

    HINSTANCE g_hInst;

    LPCTSTR lpszClass=TEXT("First");


    int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance

     ,LPSTR lpszCmdParam,int nCmdShow)

    {

    HWND hWnd;

    MSG Message;

    WNDCLASS WndClass;

    g_hInst=hInstance;

    WndClass.cbClsExtra=0;

    WndClass.cbWndExtra=0;

    WndClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);

    WndClass.hCursor=LoadCursor(NULL,IDC_ARROW);

    WndClass.hIcon=LoadIcon(NULL,IDI_APPLICATION);

    WndClass.hInstance=hInstance;

    WndClass.lpfnWndProc=WndProc;

    WndClass.lpszClassName=lpszClass;

    WndClass.lpszMenuName=NULL;

    WndClass.style=CS_HREDRAW | CS_VREDRAW;

    RegisterClass(&WndClass);


    hWnd=CreateWindow(lpszClass,lpszClass,WS_OVERLAPPEDWINDOW | WS_VSCROLL,

    100,40,800,660,

    NULL,(HMENU)NULL,hInstance,NULL);

    ShowWindow(hWnd,nCmdShow);

    while (GetMessage(&Message,NULL,0,0)) {

    TranslateMessage(&Message);

    DispatchMessage(&Message);

    }

    return (int)Message.wParam;

    }


    unsigned char * BMbuf;

    unsigned int uiRcnt[256];

    unsigned int uiGcnt[256];

    unsigned int uiBcnt[256];

    unsigned int uiRcnt2[256];

    unsigned int uiGcnt2[256];

    unsigned int uiBcnt2[256];

    unsigned int uiRhisto[256];  // 평활화로 사용할 변수

    unsigned int uiGhisto[256];  // 평활화로 사용할 변수

    unsigned int uiBhisto[256];  // 평활화로 사용할 변수

    HBITMAP Screen;

    HBITMAP Histo;


    LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)

    {

    HDC hdc;

    static HDC MemDC;

    PAINTSTRUCT ps;

    HANDLE hFile;

    DWORD dwRead;

    TCHAR str[1024];

    static BITMAPFILEHEADER * stpBFH;

    static BITMAPINFOHEADER * stpBIH;

    static unsigned int uiX;

    static unsigned int uiY;

    unsigned int uiXcount;

    unsigned int uiYcount;

    unsigned char * ucpPixel;

    static unsigned int uiPad;

    HBITMAP OldBitmap;

    static int yPos;

    int yInc;

    int iBorW;

    HPEN OldPen, MyPen;

    switch (iMessage)

    {

    case WM_CREATE:

    SetScrollRange(hWnd, SB_VERT, 0, SCROLL_SIZE, TRUE);

    SetScrollPos(hWnd, SB_VERT, 0, TRUE);

    hFile = CreateFile(TEXT("image4.bmp"),

    GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);


    BMbuf = (unsigned char *)malloc(BITMAP_MAXSIZE);

    if(0 == BMbuf)

    {

    MessageBox(hWnd, TEXT("동적할당을 받을 수 없습니다."), TEXT("오류"), MB_OK);

    DestroyWindow(hWnd);

    }

    if(INVALID_HANDLE_VALUE != hFile)

    {

    ReadFile(hFile, BMbuf, BITMAP_MAXSIZE, &dwRead, NULL);

    CloseHandle(hFile);


    stpBFH = (BITMAPFILEHEADER *)BMbuf;

    stpBIH = (BITMAPINFOHEADER *)(BMbuf + sizeof(BITMAPFILEHEADER));


    // 정보 출력 //시작------------------------------------------------------

    wsprintf(str, TEXT("[%c][%c]"), BMbuf[0], BMbuf[1]);

    CreateWindow(TEXT("static"), TEXT("파일 타입 : "), WS_CHILD | WS_VISIBLE,

    0, 0, 130, 20, hWnd, (HMENU)-1, g_hInst, NULL);

    CreateWindow(TEXT("static"), str, WS_CHILD | WS_VISIBLE,

    130, 0, X_WIDTH_SIZE, 20, hWnd, (HMENU)-1, g_hInst, NULL);


    wsprintf(str, TEXT("[%d byte]"), stpBFH->bfSize);

    CreateWindow(TEXT("static"), TEXT("파일 크기 : "), WS_CHILD | WS_VISIBLE,

    0, 20, 130, 20, hWnd, (HMENU)-1, g_hInst, NULL);

    CreateWindow(TEXT("static"), str, WS_CHILD | WS_VISIBLE,

    130, 20, X_WIDTH_SIZE, 20, hWnd, (HMENU)-1, g_hInst, NULL);


    wsprintf(str, TEXT("[%u]"), stpBIH->biWidth);

    CreateWindow(TEXT("static"), TEXT("가로 크기 : "), WS_CHILD | WS_VISIBLE,

    0, 40, 130, 20, hWnd, (HMENU)-1, g_hInst, NULL);

    CreateWindow(TEXT("static"), str, WS_CHILD | WS_VISIBLE,

    130, 40, X_WIDTH_SIZE, 20, hWnd, (HMENU)-1, g_hInst, NULL);


    wsprintf(str, TEXT("[%u]"), stpBIH->biHeight);

    CreateWindow(TEXT("static"), TEXT("세로 크기 : "), WS_CHILD | WS_VISIBLE,

    0, 60, 130, 20, hWnd, (HMENU)-1, g_hInst, NULL);

    CreateWindow(TEXT("static"), str, WS_CHILD | WS_VISIBLE,

    130, 60, X_WIDTH_SIZE, 20, hWnd, (HMENU)-1, g_hInst, NULL);


    wsprintf(str, TEXT("[%08X]"), stpBFH->bfOffBits);

    CreateWindow(TEXT("static"), TEXT("bfOffbits : "), WS_CHILD | WS_VISIBLE,

    0, 80, 130, 20, hWnd, (HMENU)-1, g_hInst, NULL);

    CreateWindow(TEXT("static"), str, WS_CHILD | WS_VISIBLE,

    130, 80, X_WIDTH_SIZE, 20, hWnd, (HMENU)-1, g_hInst, NULL);


    wsprintf(str, TEXT("[%d bytes]"), stpBIH->biSize);

    CreateWindow(TEXT("static"), TEXT("헤더 크기 : "), WS_CHILD | WS_VISIBLE,

    0, 100, 130, 20, hWnd, (HMENU)-1, g_hInst, NULL);

    CreateWindow(TEXT("static"), str, WS_CHILD | WS_VISIBLE,

    130, 100, X_WIDTH_SIZE, 20, hWnd, (HMENU)-1, g_hInst, NULL);


    wsprintf(str, TEXT("[%d bytes]"), stpBIH->biSizeImage);

    CreateWindow(TEXT("static"), TEXT("그림 크기 : "), WS_CHILD | WS_VISIBLE,

    0, 120, 130, 20, hWnd, (HMENU)-1, g_hInst, NULL);

    CreateWindow(TEXT("static"), str, WS_CHILD | WS_VISIBLE,

    130, 120, X_WIDTH_SIZE, 20, hWnd, (HMENU)-1, g_hInst, NULL);


    wsprintf(str, TEXT("[%d pixel]"), stpBIH->biXPelsPerMeter);

    CreateWindow(TEXT("static"), TEXT("이미지 가로 크기 : "), WS_CHILD | WS_VISIBLE,

    0, 140, 130, 20, hWnd, (HMENU)-1, g_hInst, NULL);

    CreateWindow(TEXT("static"), str, WS_CHILD | WS_VISIBLE,

    130, 140, X_WIDTH_SIZE, 20, hWnd, (HMENU)-1, g_hInst, NULL);


    wsprintf(str, TEXT("[%d pixel]"), stpBIH->biYPelsPerMeter);

    CreateWindow(TEXT("static"), TEXT("이미지 세로 크기 : "), WS_CHILD | WS_VISIBLE,

    0, 160, 130, 20, hWnd, (HMENU)-1, g_hInst, NULL);

    CreateWindow(TEXT("static"), str, WS_CHILD | WS_VISIBLE,

    130, 160, X_WIDTH_SIZE, 20, hWnd, (HMENU)-1, g_hInst, NULL);

    // 정보 출력 //끝-----------------------------------------------------------

    uiX = (unsigned int)(stpBIH->biWidth);

    uiPad = uiX%4;

    uiY = (unsigned int)(stpBIH->biHeight);


    hdc = GetDC(hWnd);

    MemDC = CreateCompatibleDC(hdc);


    Screen = CreateCompatibleBitmap(hdc, uiX, uiY * 2);

    OldBitmap = (HBITMAP)SelectObject(MemDC, Screen);

    // Bitmap 그리기 //시작---------------------------------------------

    ucpPixel = BMbuf + stpBFH->bfOffBits;

    for(uiYcount = uiY; 0 < uiYcount; --uiYcount)

    {

    for(uiXcount = uiX; 0 < uiXcount; --uiXcount)

    {

    // 흑백 처리 // 시작--------------------------------------

    iBorW = ((*(ucpPixel+2)) + (*(ucpPixel+1)) + (*ucpPixel))/3;

    *(ucpPixel+2)= iBorW;

    *(ucpPixel+1)= iBorW;

    *(ucpPixel+0)= iBorW;

    // 흑백 처리 // 끝----------------------------------------

    ++uiRcnt[*(ucpPixel+2)];

    ++uiGcnt[*(ucpPixel+1)];

    ++uiBcnt[*ucpPixel];


    SetPixel(MemDC, uiXcount-1, uiYcount-1,

    RGB(*(ucpPixel+2), *(ucpPixel+1), *ucpPixel));

    ucpPixel = ucpPixel + 3;

    }

    ucpPixel = ucpPixel + uiPad;

    }



    // Bitmap 그리기 //끝-----------------------------------------------


    uiYcount = 0;

    for(uiXcount = 0; 256 > uiXcount; ++uiXcount)

    {

    if(uiYcount < uiRcnt[uiXcount])

    {

    uiYcount = uiRcnt[uiXcount];

    }

    if(uiYcount < uiGcnt[uiXcount])

    {

    uiYcount = uiGcnt[uiXcount];

    }

    if(uiYcount < uiBcnt[uiXcount])

    {

    uiYcount = uiBcnt[uiXcount];

    }

    }


    // 히스토그램 세로축 값 변환 //시작----------------------------------

    // 평활화 누적값 // 시작--------------------------------------------


    // 누적

    uiXcount = 0;

    uiRhisto[uiXcount] = uiRcnt[uiXcount];

    uiGhisto[uiXcount] = uiGcnt[uiXcount];

    uiBhisto[uiXcount] = uiBcnt[uiXcount];

    for(uiXcount = 1; 256 > uiXcount; ++uiXcount)

    {

    uiRhisto[uiXcount] = (uiRhisto[uiXcount-1] + uiRcnt[uiXcount]);

    uiGhisto[uiXcount] = (uiGhisto[uiXcount-1] + uiGcnt[uiXcount]);

    uiBhisto[uiXcount] = (uiBhisto[uiXcount-1] + uiBcnt[uiXcount]);

    }

    // 계산

    for(uiXcount = 0; 256 > uiXcount; ++uiXcount)

    {

    uiRhisto[uiXcount] = (uiRhisto[uiXcount] * 255) / (uiX*uiY);

    uiGhisto[uiXcount] = (uiGhisto[uiXcount] * 255) / (uiX*uiY);

    uiBhisto[uiXcount] = (uiBhisto[uiXcount] * 255) / (uiX*uiY);

    }


    //n[i]=sum[i]*(1/16)*7 


    // 평활화 누적값 // 끝----------------------------------------------


    for(uiXcount = 0; 256 > uiXcount; ++uiXcount)

    {

    uiRcnt[uiXcount] = (uiRcnt[uiXcount] * 255) / uiYcount;//(uiX*uiY);

    uiGcnt[uiXcount] = (uiGcnt[uiXcount] * 255) / uiYcount;//(uiX*uiY);

    uiBcnt[uiXcount] = (uiBcnt[uiXcount] * 255) / uiYcount;//(uiX*uiY);

    }

    // 히스토그램 세로축 값 변환 //끝------------------------------------


    // 편집된 Bitmap 그리기 //시작---------------------------------------------

    ucpPixel = BMbuf + stpBFH->bfOffBits;

    for(uiYcount = uiY*2; uiY < uiYcount; --uiYcount)

    {

    for(uiXcount = uiX; 0 < uiXcount; --uiXcount)

    {

    ++uiRcnt2[uiRhisto[*(ucpPixel+2)]];

    ++uiGcnt2[uiGhisto[*(ucpPixel+1)]];

    ++uiBcnt2[uiBhisto[*ucpPixel]];


    SetPixel(MemDC, uiXcount-1, uiYcount-1,

    RGB(uiRhisto[*(ucpPixel+2)], uiGhisto[*(ucpPixel+1)], uiBhisto[*ucpPixel]));

    ucpPixel = ucpPixel + 3;

    }

    ucpPixel = ucpPixel + uiPad;

    }

    // 편집된 Bitmap 그리기 //끝-----------------------------------------------


    uiYcount = 0;

    for(uiXcount = 0; 256 > uiXcount; ++uiXcount)

    {

    if(uiYcount < uiRcnt2[uiXcount])

    {

    uiYcount = uiRcnt2[uiXcount];

    }

    if(uiYcount < uiGcnt2[uiXcount])

    {

    uiYcount = uiGcnt2[uiXcount];

    }

    if(uiYcount < uiBcnt2[uiXcount])

    {

    uiYcount = uiBcnt2[uiXcount];

    }

    }


    for(uiXcount = 0; 256 > uiXcount; ++uiXcount)

    {

    uiRcnt2[uiXcount] = (uiRcnt2[uiXcount] * 255) / uiYcount;//(uiX*uiY);

    uiGcnt2[uiXcount] = (uiGcnt2[uiXcount] * 255) / uiYcount;//(uiX*uiY);

    uiBcnt2[uiXcount] = (uiBcnt2[uiXcount] * 255) / uiYcount;//(uiX*uiY);

    }


    //히스토그램 그리기 //시작-------------------------------------------

    Histo = CreateCompatibleBitmap(hdc, 260, SCREEN_Y_SIZE);

    SelectObject(MemDC, Histo);

    /*

    SetBkColor(MemDC, RGB(100,100,100));

    aaa = GetBkColor(MemDC);

    wsprintf(str, TEXT("[%08X]"), aaa);

    MessageBox(hWnd, str, TEXT("hi"), MB_OK);

    */

    // SCREEN 바탕 흰색으로 그리기// 시작--------------------------------

    for(uiYcount = 0; SCREEN_Y_SIZE > uiYcount; ++uiYcount)

    {

    for(uiXcount = 0; 260 > uiXcount; ++uiXcount)

    {

    SetPixel(MemDC, uiXcount, uiYcount, RGB(255, 255, 255));

    }

    }

    // SCREEN 바탕 흰색으로 그리기// 끝----------------------------------


    MyPen = CreatePen(PS_SOLID, 1, RGB(0, 0, 0));

    OldPen = (HPEN)SelectObject(MemDC, MyPen);

    MoveToEx(MemDC, 0, 0, NULL);

    LineTo(MemDC, 0, 256);

    LineTo(MemDC, 259, 256);


    MoveToEx(MemDC, 0, 270, NULL);

    LineTo(MemDC, 0, 270+256);

    LineTo(MemDC, 259, 270+256);

    // 빨강색 그래프

    MoveToEx(MemDC, 3, 256-uiRcnt[0], NULL);

    for(uiXcount = 1; 256 > uiXcount; ++uiXcount)

    {

    MyPen = CreatePen(PS_SOLID, 1, RGB(255, 0, 0));

    SelectObject(MemDC, MyPen);

    LineTo(MemDC, uiXcount+3, 256-uiRcnt[uiXcount]);

    }


    // 초록색 그래프

    MoveToEx(MemDC, 3, 256-uiGcnt[0], NULL);

    for(uiXcount = 1; 256 > uiXcount; ++uiXcount)

    {

    MyPen = CreatePen(PS_SOLID, 1, RGB(0, 255, 0));

    SelectObject(MemDC, MyPen);

    LineTo(MemDC, uiXcount+3, 256-uiGcnt[uiXcount]);

    }


    // 파랑색 그래프

    MoveToEx(MemDC, 3, 256-uiBcnt[0], NULL);

    for(uiXcount = 1; 256 > uiXcount; ++uiXcount)

    {

    MyPen = CreatePen(PS_SOLID, 1, RGB(0, 0, 255));

    SelectObject(MemDC, MyPen);

    LineTo(MemDC, uiXcount+3, 256-uiBcnt[uiXcount]);

    }




    MoveToEx(MemDC, 3, 270+256-uiRcnt2[0], NULL);

    for(uiXcount = 1; 256 > uiXcount; ++uiXcount)

    {

    MyPen = CreatePen(PS_SOLID, 1, RGB(255, 0, 0));

    SelectObject(MemDC, MyPen);

    LineTo(MemDC, uiXcount+3, 270+256-uiRcnt2[uiXcount]);

    }


    MoveToEx(MemDC, 3, 270+256-uiGcnt2[0], NULL);

    for(uiXcount = 1; 256 > uiXcount; ++uiXcount)

    {

    MyPen = CreatePen(PS_SOLID, 1, RGB(0, 255, 0));

    SelectObject(MemDC, MyPen);

    LineTo(MemDC, uiXcount+3, 270+256-uiGcnt2[uiXcount]);

    }


    MoveToEx(MemDC, 3, 270+256-uiBcnt2[0], NULL);

    for(uiXcount = 1; 256 > uiXcount; ++uiXcount)

    {

    MyPen = CreatePen(PS_SOLID, 1, RGB(0, 0, 255));

    SelectObject(MemDC, MyPen);

    LineTo(MemDC, uiXcount+3, 270+256-uiBcnt2[uiXcount]);

    }

    //히스토그램 그리기 //끝---------------------------------------------


    SelectObject(hdc, OldPen);

    SelectObject(MemDC, OldBitmap);

    DeleteDC(MemDC);

    DeleteObject(MyPen);

    ReleaseDC(hWnd, hdc);

    free(BMbuf);

    }

    else

    {

    MessageBox(hWnd, TEXT("파일을 열 수 없습니다."), TEXT("오류"), MB_OK);

    DestroyWindow(hWnd);

    }

    return 0;

    case WM_PAINT:

    hdc = BeginPaint(hWnd, &ps);

    MemDC = CreateCompatibleDC(hdc);

    OldBitmap = (HBITMAP)SelectObject(MemDC, Screen);


    BitBlt(hdc, XOFFSET, -yPos, uiX, uiY*2, MemDC, 0, 0, SRCCOPY);


    (HBITMAP)SelectObject(MemDC, Histo);


    BitBlt(hdc, 5, 180-yPos, 260, SCREEN_Y_SIZE, MemDC, 0, 0, SRCCOPY);


    SelectObject(MemDC, OldBitmap);

    DeleteDC(MemDC);

    EndPaint(hWnd, &ps);

    return 0;

    case WM_VSCROLL:

    yInc = 0;

    switch(LOWORD(wParam))

    {

    case SB_LINEUP:

    yInc = -40;

    break;

    case SB_LINEDOWN:

    yInc = 40;

    break;

    case SB_PAGEUP:

    yInc = -200;

    break;

    case SB_PAGEDOWN:

    yInc = 200;

    break;

    case SB_THUMBTRACK:

    yInc = HIWORD(wParam)-yPos;

    break;

    }

    if(yPos+yInc < 0)

    yInc = -yPos;

    if(yPos+yInc > SCROLL_SIZE)

    yInc = SCROLL_SIZE - yPos;


    yPos = yPos + yInc;

    ScrollWindow(hWnd, 0, -yInc, NULL, NULL);

    SetScrollPos(hWnd, SB_VERT, yPos, TRUE);

    return 0;

    case WM_KEYDOWN:

    yInc = 0;

    switch(wParam)

    {

    case VK_UP:

    yInc = -40;

    break;

    case VK_DOWN:

    yInc = 40;

    break;

    }

    if(yPos+yInc < 0)

    yInc = -yPos;

    if(yPos+yInc > SCROLL_SIZE)

    yInc = SCROLL_SIZE - yPos;


    yPos = yPos + yInc;

    ScrollWindow(hWnd, 0, -yInc, NULL, NULL);

    SetScrollPos(hWnd, SB_VERT, yPos, TRUE);

    return 0;

    case WM_DESTROY:

    DeleteObject(Screen);

    DeleteObject(Histo);

    PostQuitMessage(0);

    return 0;

    }

    return(DefWindowProc(hWnd,iMessage,wParam,lParam));

    }




    결과


    흑백이미지일 경우,

    위에 그림이 원본, 밑에 그림이 평활화된 이미지.





    색깔이미지일 경우,

    위에 그림이 원본, 밑에 그림이 평활화된 이미지.












    --------------------

    이미지 스트레칭

    --------------------


    ------- 비트맵 이미지를 스트레칭 처리하는 소스



    #include <windows.h>


    #define BITMAP_MAXSIZE (1024*768*3+10)

    #define XOFFSET 280

    #define X_WIDTH_SIZE 100

    #define ALPA

    #define SCREEN_Y_SIZE 270*2

    #define SCROLL_SIZE 100*6


    LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);

    HINSTANCE g_hInst;

    LPCTSTR lpszClass=TEXT("First");


    int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance

     ,LPSTR lpszCmdParam,int nCmdShow)

    {

    HWND hWnd;

    MSG Message;

    WNDCLASS WndClass;

    g_hInst=hInstance;

    WndClass.cbClsExtra=0;

    WndClass.cbWndExtra=0;

    WndClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);

    WndClass.hCursor=LoadCursor(NULL,IDC_ARROW);

    WndClass.hIcon=LoadIcon(NULL,IDI_APPLICATION);

    WndClass.hInstance=hInstance;

    WndClass.lpfnWndProc=WndProc;

    WndClass.lpszClassName=lpszClass;

    WndClass.lpszMenuName=NULL;

    WndClass.style=CS_HREDRAW | CS_VREDRAW;

    RegisterClass(&WndClass);


    hWnd=CreateWindow(lpszClass,lpszClass,WS_OVERLAPPEDWINDOW | WS_VSCROLL,

    100,40,800,660,

    NULL,(HMENU)NULL,hInstance,NULL);

    ShowWindow(hWnd,nCmdShow);

    while (GetMessage(&Message,NULL,0,0)) {

    TranslateMessage(&Message);

    DispatchMessage(&Message);

    }

    return (int)Message.wParam;

    }


    unsigned char * BMbuf;

    unsigned int uiRcnt[256];

    unsigned int uiGcnt[256];

    unsigned int uiBcnt[256];

    unsigned int uiRcnt2[256];

    unsigned int uiGcnt2[256];

    unsigned int uiBcnt2[256];

    unsigned int uiRStretch[256];  // 스트레칭으로 사용할 변수

    unsigned int uiGStretch[256];  // 스트레칭으로 사용할 변수

    unsigned int uiBStretch[256];  // 스트레칭으로 사용할 변수

    HBITMAP Screen;

    HBITMAP Stretch;


    LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)

    {

    HDC hdc;

    static HDC MemDC;

    PAINTSTRUCT ps;

    HANDLE hFile;

    DWORD dwRead;

    TCHAR str[1024];

    static BITMAPFILEHEADER * stpBFH;

    static BITMAPINFOHEADER * stpBIH;

    static unsigned int uiX;

    static unsigned int uiY;

    unsigned int uiXcount;

    unsigned int uiYcount;

    unsigned char * ucpPixel;

    static unsigned int uiPad;

    HBITMAP OldBitmap;

    static int yPos;

    int yInc;

    int iBorW;

    HPEN OldPen, MyPen;

    int Rhigh, Ghigh, Bhigh;

    int Rlow, Glow, Blow;

    switch (iMessage)

    {

    case WM_CREATE:

    SetScrollRange(hWnd, SB_VERT, 0, SCROLL_SIZE, TRUE);

    SetScrollPos(hWnd, SB_VERT, 0, TRUE);

    hFile = CreateFile(TEXT("image6.bmp"),

    GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);


    BMbuf = (unsigned char *)malloc(BITMAP_MAXSIZE);

    if(0 == BMbuf)

    {

    MessageBox(hWnd, TEXT("동적할당을 받을 수 없습니다."), TEXT("오류"), MB_OK);

    DestroyWindow(hWnd);

    }

    if(INVALID_HANDLE_VALUE != hFile)

    {

    ReadFile(hFile, BMbuf, BITMAP_MAXSIZE, &dwRead, NULL);

    CloseHandle(hFile);


    stpBFH = (BITMAPFILEHEADER *)BMbuf;

    stpBIH = (BITMAPINFOHEADER *)(BMbuf + sizeof(BITMAPFILEHEADER));


    // 정보 출력 //시작------------------------------------------------------

    wsprintf(str, TEXT("[%c][%c]"), BMbuf[0], BMbuf[1]);

    CreateWindow(TEXT("static"), TEXT("파일 타입 : "), WS_CHILD | WS_VISIBLE,

    0, 0, 130, 20, hWnd, (HMENU)-1, g_hInst, NULL);

    CreateWindow(TEXT("static"), str, WS_CHILD | WS_VISIBLE,

    130, 0, X_WIDTH_SIZE, 20, hWnd, (HMENU)-1, g_hInst, NULL);


    wsprintf(str, TEXT("[%d byte]"), stpBFH->bfSize);

    CreateWindow(TEXT("static"), TEXT("파일 크기 : "), WS_CHILD | WS_VISIBLE,

    0, 20, 130, 20, hWnd, (HMENU)-1, g_hInst, NULL);

    CreateWindow(TEXT("static"), str, WS_CHILD | WS_VISIBLE,

    130, 20, X_WIDTH_SIZE, 20, hWnd, (HMENU)-1, g_hInst, NULL);


    wsprintf(str, TEXT("[%u]"), stpBIH->biWidth);

    CreateWindow(TEXT("static"), TEXT("가로 크기 : "), WS_CHILD | WS_VISIBLE,

    0, 40, 130, 20, hWnd, (HMENU)-1, g_hInst, NULL);

    CreateWindow(TEXT("static"), str, WS_CHILD | WS_VISIBLE,

    130, 40, X_WIDTH_SIZE, 20, hWnd, (HMENU)-1, g_hInst, NULL);


    wsprintf(str, TEXT("[%u]"), stpBIH->biHeight);

    CreateWindow(TEXT("static"), TEXT("세로 크기 : "), WS_CHILD | WS_VISIBLE,

    0, 60, 130, 20, hWnd, (HMENU)-1, g_hInst, NULL);

    CreateWindow(TEXT("static"), str, WS_CHILD | WS_VISIBLE,

    130, 60, X_WIDTH_SIZE, 20, hWnd, (HMENU)-1, g_hInst, NULL);


    wsprintf(str, TEXT("[%08X]"), stpBFH->bfOffBits);

    CreateWindow(TEXT("static"), TEXT("bfOffbits : "), WS_CHILD | WS_VISIBLE,

    0, 80, 130, 20, hWnd, (HMENU)-1, g_hInst, NULL);

    CreateWindow(TEXT("static"), str, WS_CHILD | WS_VISIBLE,

    130, 80, X_WIDTH_SIZE, 20, hWnd, (HMENU)-1, g_hInst, NULL);


    wsprintf(str, TEXT("[%d bytes]"), stpBIH->biSize);

    CreateWindow(TEXT("static"), TEXT("헤더 크기 : "), WS_CHILD | WS_VISIBLE,

    0, 100, 130, 20, hWnd, (HMENU)-1, g_hInst, NULL);

    CreateWindow(TEXT("static"), str, WS_CHILD | WS_VISIBLE,

    130, 100, X_WIDTH_SIZE, 20, hWnd, (HMENU)-1, g_hInst, NULL);


    wsprintf(str, TEXT("[%d bytes]"), stpBIH->biSizeImage);

    CreateWindow(TEXT("static"), TEXT("그림 크기 : "), WS_CHILD | WS_VISIBLE,

    0, 120, 130, 20, hWnd, (HMENU)-1, g_hInst, NULL);

    CreateWindow(TEXT("static"), str, WS_CHILD | WS_VISIBLE,

    130, 120, X_WIDTH_SIZE, 20, hWnd, (HMENU)-1, g_hInst, NULL);


    wsprintf(str, TEXT("[%d pixel]"), stpBIH->biXPelsPerMeter);

    CreateWindow(TEXT("static"), TEXT("이미지 가로 크기 : "), WS_CHILD | WS_VISIBLE,

    0, 140, 130, 20, hWnd, (HMENU)-1, g_hInst, NULL);

    CreateWindow(TEXT("static"), str, WS_CHILD | WS_VISIBLE,

    130, 140, X_WIDTH_SIZE, 20, hWnd, (HMENU)-1, g_hInst, NULL);


    wsprintf(str, TEXT("[%d pixel]"), stpBIH->biYPelsPerMeter);

    CreateWindow(TEXT("static"), TEXT("이미지 세로 크기 : "), WS_CHILD | WS_VISIBLE,

    0, 160, 130, 20, hWnd, (HMENU)-1, g_hInst, NULL);

    CreateWindow(TEXT("static"), str, WS_CHILD | WS_VISIBLE,

    130, 160, X_WIDTH_SIZE, 20, hWnd, (HMENU)-1, g_hInst, NULL);

    // 정보 출력 //끝-----------------------------------------------------------

    uiX = (unsigned int)(stpBIH->biWidth);

    uiPad = uiX%4;

    uiY = (unsigned int)(stpBIH->biHeight);


    hdc = GetDC(hWnd);

    MemDC = CreateCompatibleDC(hdc);


    Screen = CreateCompatibleBitmap(hdc, uiX, uiY * 2);

    OldBitmap = (HBITMAP)SelectObject(MemDC, Screen);

    // Bitmap 그리기 //시작---------------------------------------------

    ucpPixel = BMbuf + stpBFH->bfOffBits;

    for(uiYcount = uiY; 0 < uiYcount; --uiYcount)

    {

    for(uiXcount = 0; uiX > uiXcount; ++uiXcount)

    {

    /*iBorW = ((*(ucpPixel+2)) + (*(ucpPixel+1)) + (*ucpPixel))/3;

    *(ucpPixel+2)= iBorW;

    *(ucpPixel+1)= iBorW;

    *(ucpPixel+0)= iBorW;*/

    ++uiRcnt[*(ucpPixel+2)];

    ++uiGcnt[*(ucpPixel+1)];

    ++uiBcnt[*ucpPixel];


    SetPixel(MemDC, uiXcount, uiYcount-1,

    RGB(*(ucpPixel+2), *(ucpPixel+1), *ucpPixel));

    ucpPixel = ucpPixel + 3;

    }

    ucpPixel = ucpPixel + uiPad;

    }



    // Bitmap 그리기 //끝-----------------------------------------------


    // 히스토그램 세로축 값 변환 //시작----------------------------------



    for(uiXcount = 0; 256 > uiXcount; ++uiXcount)

    {

    if(uiRcnt[uiXcount] != 0)

    {

    Rlow = uiXcount;

    break;

    }

    }

    for(uiXcount = 255; 0 <= uiXcount; --uiXcount)

    {

    if(uiRcnt[uiXcount] != 0)

    {

    Rhigh = uiXcount;

    break;

    }

    }

    // wsprintf(str, TEXT("Rhigh : %d, Rlow : %d"), Rhigh, Rlow);

    // MessageBox(hWnd, str, TEXT("test"), MB_OK);



    for(uiXcount = 0; 256 > uiXcount; ++uiXcount)

    {

    if(uiGcnt[uiXcount] != 0)

    {

    Glow = uiXcount;

    break;

    }

    }

    for(uiXcount = 255; 0 <= uiXcount; --uiXcount)

    {

    if(uiGcnt[uiXcount] != 0)

    {

    Ghigh = uiXcount;

    break;

    }

    }

    // wsprintf(str, TEXT("Ghigh : %d, Glow : %d"), Ghigh, Glow);

    // MessageBox(hWnd, str, TEXT("test"), MB_OK);



    for(uiXcount = 0; 256 > uiXcount; ++uiXcount)

    {

    if(uiBcnt[uiXcount] != 0)

    {

    Blow = uiXcount;

    break;

    }

    }

    for(uiXcount = 255; 0 <= uiXcount; --uiXcount)

    {

    if(uiBcnt[uiXcount] != 0)

    {

    Bhigh = uiXcount;

    break;

    }

    }

    // wsprintf(str, TEXT("Bhigh : %d, Blow : %d"), Bhigh, Blow);

    // MessageBox(hWnd, str, TEXT("test"), MB_OK);


    /*

    for(uiXcount = 0; 256 > uiXcount; ++uiXcount)

    {

    uiRStretch[uiXcount] = ((uiRcnt[uiXcount]-Rlow) * 255) / (Rhigh - Rlow);

    uiGStretch[uiXcount] = ((uiGcnt[uiXcount]-Glow) * 255) / (Ghigh - Glow);

    uiBStretch[uiXcount] = ((uiBcnt[uiXcount]-Blow) * 255) / (Bhigh - Blow);

    }*/



    uiYcount = 0;

    for(uiXcount = 0; 256 > uiXcount; ++uiXcount)

    {

    if(uiYcount < uiRcnt[uiXcount])

    {

    uiYcount = uiRcnt[uiXcount];

    }

    if(uiYcount < uiGcnt[uiXcount])

    {

    uiYcount = uiGcnt[uiXcount];

    }

    if(uiYcount < uiBcnt[uiXcount])

    {

    uiYcount = uiBcnt[uiXcount];

    }

    }


    for(uiXcount = 0; 256 > uiXcount; ++uiXcount)

    {

    uiRcnt[uiXcount] = (uiRcnt[uiXcount] * 255) / uiYcount;//(uiX*uiY);

    uiGcnt[uiXcount] = (uiGcnt[uiXcount] * 255) / uiYcount;//(uiX*uiY);

    uiBcnt[uiXcount] = (uiBcnt[uiXcount] * 255) / uiYcount;//(uiX*uiY);

    }

    // 히스토그램 세로축 값 변환 //끝------------------------------------


    // Bitmap 그리기 //시작---------------------------------------------

    ucpPixel = BMbuf + stpBFH->bfOffBits;

    for(uiYcount = uiY*2; uiY < uiYcount; --uiYcount)

    {

    for(uiXcount = 0; uiX > uiXcount; ++uiXcount)

    {

    *(ucpPixel+2) = (((*(ucpPixel+2))-Rlow) * 255) / (Rhigh - Rlow);

    *(ucpPixel+1) = (((*(ucpPixel+1))-Glow) * 255) / (Ghigh - Glow);

    *(ucpPixel+0) = (((*(ucpPixel+0))-Blow) * 255) / (Bhigh - Blow);


    ++uiRcnt2[*(ucpPixel+2)];

    ++uiGcnt2[*(ucpPixel+1)];

    ++uiBcnt2[*ucpPixel];


    SetPixel(MemDC, uiXcount, uiYcount-1,

    RGB(*(ucpPixel+2), *(ucpPixel+1), *ucpPixel));

    ucpPixel = ucpPixel + 3;

    }

    ucpPixel = ucpPixel + uiPad;

    }

    // Bitmap 그리기 //끝-----------------------------------------------


    uiYcount = 0;

    for(uiXcount = 0; 256 > uiXcount; ++uiXcount)

    {

    if(uiYcount < uiRcnt2[uiXcount])

    {

    uiYcount = uiRcnt2[uiXcount];

    }

    if(uiYcount < uiGcnt2[uiXcount])

    {

    uiYcount = uiGcnt2[uiXcount];

    }

    if(uiYcount < uiBcnt2[uiXcount])

    {

    uiYcount = uiBcnt2[uiXcount];

    }

    }


    for(uiXcount = 0; 256 > uiXcount; ++uiXcount)

    {

    uiRcnt2[uiXcount] = (uiRcnt2[uiXcount] * 255) / uiYcount;//(uiX*uiY);

    uiGcnt2[uiXcount] = (uiGcnt2[uiXcount] * 255) / uiYcount;//(uiX*uiY);

    uiBcnt2[uiXcount] = (uiBcnt2[uiXcount] * 255) / uiYcount;//(uiX*uiY);

    }


    //히스토그램 그리기 //시작-------------------------------------------

    Stretch = CreateCompatibleBitmap(hdc, 260, SCREEN_Y_SIZE);

    SelectObject(MemDC, Stretch);

    /*

    SetBkColor(MemDC, RGB(100,100,100));

    aaa = GetBkColor(MemDC);

    wsprintf(str, TEXT("[%08X]"), aaa);

    MessageBox(hWnd, str, TEXT("hi"), MB_OK);

    */

    // SCREEN 바탕 흰색으로 그리기// 시작--------------------------------

    for(uiYcount = 0; SCREEN_Y_SIZE > uiYcount; ++uiYcount)

    {

    for(uiXcount = 0; 260 > uiXcount; ++uiXcount)

    {

    SetPixel(MemDC, uiXcount, uiYcount, RGB(255, 255, 255));

    }

    }

    // SCREEN 바탕 흰색으로 그리기// 끝----------------------------------


    MyPen = CreatePen(PS_SOLID, 1, RGB(0, 0, 0));

    OldPen = (HPEN)SelectObject(MemDC, MyPen);

    MoveToEx(MemDC, 0, 0, NULL);

    LineTo(MemDC, 0, 256);

    LineTo(MemDC, 259, 256);


    MoveToEx(MemDC, 0, 270, NULL);

    LineTo(MemDC, 0, 270+256);

    LineTo(MemDC, 259, 270+256);

    // 빨강색 그래프

    MoveToEx(MemDC, 3, 256-uiRcnt[0], NULL);

    for(uiXcount = 1; 256 > uiXcount; ++uiXcount)

    {

    MyPen = CreatePen(PS_SOLID, 1, RGB(255, 0, 0));

    SelectObject(MemDC, MyPen);

    LineTo(MemDC, uiXcount+3, 256-uiRcnt[uiXcount]);

    }


    // 초록색 그래프

    MoveToEx(MemDC, 3, 256-uiGcnt[0], NULL);

    for(uiXcount = 1; 256 > uiXcount; ++uiXcount)

    {

    MyPen = CreatePen(PS_SOLID, 1, RGB(0, 255, 0));

    SelectObject(MemDC, MyPen);

    LineTo(MemDC, uiXcount+3, 256-uiGcnt[uiXcount]);

    }


    // 파랑색 그래프

    MoveToEx(MemDC, 3, 256-uiBcnt[0], NULL);

    for(uiXcount = 1; 256 > uiXcount; ++uiXcount)

    {

    MyPen = CreatePen(PS_SOLID, 1, RGB(0, 0, 255));

    SelectObject(MemDC, MyPen);

    LineTo(MemDC, uiXcount+3, 256-uiBcnt[uiXcount]);

    }



    MoveToEx(MemDC, 3, 270+256-uiRcnt2[0], NULL);

    for(uiXcount = 1; 256 > uiXcount; ++uiXcount)

    {

    MyPen = CreatePen(PS_SOLID, 1, RGB(255, 0, 0));

    SelectObject(MemDC, MyPen);

    LineTo(MemDC, uiXcount+3, 270+256-uiRcnt2[uiXcount]);

    }


    MoveToEx(MemDC, 3, 270+256-uiGcnt2[0], NULL);

    for(uiXcount = 1; 256 > uiXcount; ++uiXcount)

    {

    MyPen = CreatePen(PS_SOLID, 1, RGB(0, 255, 0));

    SelectObject(MemDC, MyPen);

    LineTo(MemDC, uiXcount+3, 270+256-uiGcnt2[uiXcount]);

    }


    MoveToEx(MemDC, 3, 270+256-uiBcnt2[0], NULL);

    for(uiXcount = 1; 256 > uiXcount; ++uiXcount)

    {

    MyPen = CreatePen(PS_SOLID, 1, RGB(0, 0, 255));

    SelectObject(MemDC, MyPen);

    LineTo(MemDC, uiXcount+3, 270+256-uiBcnt2[uiXcount]);

    }

    //히스토그램 그리기 //끝---------------------------------------------


    SelectObject(hdc, OldPen);

    SelectObject(MemDC, OldBitmap);

    DeleteDC(MemDC);

    DeleteObject(MyPen);

    ReleaseDC(hWnd, hdc);

    free(BMbuf);

    }

    else

    {

    MessageBox(hWnd, TEXT("파일을 열 수 없습니다."), TEXT("오류"), MB_OK);

    DestroyWindow(hWnd);

    }

    return 0;

    case WM_PAINT:

    hdc = BeginPaint(hWnd, &ps);

    MemDC = CreateCompatibleDC(hdc);

    OldBitmap = (HBITMAP)SelectObject(MemDC, Screen);


    BitBlt(hdc, XOFFSET, -yPos, uiX, uiY*2, MemDC, 0, 0, SRCCOPY);


    (HBITMAP)SelectObject(MemDC, Stretch);


    BitBlt(hdc, 5, 180-yPos, 260, SCREEN_Y_SIZE, MemDC, 0, 0, SRCCOPY);


    SelectObject(MemDC, OldBitmap);

    DeleteDC(MemDC);

    EndPaint(hWnd, &ps);

    return 0;

    case WM_VSCROLL:

    yInc = 0;

    switch(LOWORD(wParam))

    {

    case SB_LINEUP:

    yInc = -40;

    break;

    case SB_LINEDOWN:

    yInc = 40;

    break;

    case SB_PAGEUP:

    yInc = -200;

    break;

    case SB_PAGEDOWN:

    yInc = 200;

    break;

    case SB_THUMBTRACK:

    yInc = HIWORD(wParam)-yPos;

    break;

    }

    if(yPos+yInc < 0)

    yInc = -yPos;

    if(yPos+yInc > SCROLL_SIZE)

    yInc = SCROLL_SIZE - yPos;


    yPos = yPos + yInc;

    ScrollWindow(hWnd, 0, -yInc, NULL, NULL);

    SetScrollPos(hWnd, SB_VERT, yPos, TRUE);

    return 0;

    case WM_KEYDOWN:

    yInc = 0;

    switch(wParam)

    {

    case VK_UP:

    yInc = -40;

    break;

    case VK_DOWN:

    yInc = 40;

    break;

    }

    if(yPos+yInc < 0)

    yInc = -yPos;

    if(yPos+yInc > SCROLL_SIZE)

    yInc = SCROLL_SIZE - yPos;


    yPos = yPos + yInc;

    ScrollWindow(hWnd, 0, -yInc, NULL, NULL);

    SetScrollPos(hWnd, SB_VERT, yPos, TRUE);

    return 0;

    case WM_DESTROY:

    DeleteObject(Screen);

    DeleteObject(Stretch);

    PostQuitMessage(0);

    return 0;

    }

    return(DefWindowProc(hWnd,iMessage,wParam,lParam));

    }



    결과



    위에 이미지가 원본영상으로 전체적으로 어둡다.

    밑에 이미지가 스트레칭 처리된 이미지로 밝아졌다.





    전체적으로 밝기만 올렸을 경우,





Designed by Tistory.