본문 바로가기
코스웨어/12년 내장형하드웨어

[WINAPI] 10월 23일 수업소스+결과(BIPMAP 영상처리(?)) - by.LDH

by 알 수 없는 사용자 2012. 10. 23.
728x90
반응형

#include<windows.h>
#include<stdio.h>
#pragma comment(lib,"user32.lib")
#define ID_EDIT 100
enum emb_rgb
{
  EMB_RED ,
  EMB_GRN ,
  EMB_BLU ,

  EMB_END,
};

LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
HINSTANCE g_hInst;
LPCTSTR lpszClass=TEXT("Bitmap viewer");
void MyTextOut(HDC hdc,int x,int y,LPCTSTR Text);

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR IpazCmdParam, int nCmdShow)
{
  HWND hWnd;
  MSG Message;
  WNDCLASS WndClass;
  g_hInst=hInstance;

  WndClass.cbClsExtra=0;
  WndClass.cbWndExtra=0;
  WndClass.hbrBackground=CreateSolidBrush(RGB(255,255,255));
  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,
                  100,
                  100,
                  1000,
                  800,
                  NULL,
                  (HMENU)NULL,
                  hInstance,
                  NULL);
                  
  ShowWindow(hWnd,nCmdShow);

  while(GetMessage(&Message,NULL,0,0))
  {
    TranslateMessage(&Message);
    DispatchMessage(&Message);
  }
  return(int)Message.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage, WPARAM wParam,LPARAM IParam)
{
  TCHAR fileName[]=L"1.bmp";
  HDC hdc;
  PAINTSTRUCT ps;
  DWORD iret;    
  HANDLE hfile;          //CreateFile 핸들
  static char cimage[1024*1024];  //파일을 저장할 문자열 변수
  static char string[100];    //상수를 저장할 문자열변수
  static BITMAPFILEHEADER *bfp;   //bmp파일의 첫번째 구조체
  static BITMAPINFOHEADER *bip;  //bmp파일의 두번째 구조체
  static int iRGBcnt[EMB_END][256];
  unsigned char *imageP;          //bmp파일의 이미지를 창에 뿌릴 변수
  int iXcnt;
  int iYcnt;
  HPEN MyPen;
  HPEN BlockPen;

  
  switch(iMessage)
  {
  case WM_CREATE:
    hfile = CreateFile(fileName,GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
    if(INVALID_HANDLE_VALUE != hfile) 
    {
      ReadFile(hfile,cimage,sizeof(cimage),&iret,NULL);       //bmp파일을 cimage로 읽는다.
      CloseHandle(hfile);
      bfp = (BITMAPFILEHEADER *)cimage;               //첫번째 구조체 BITMAPFILEHEADER 가 cimage를 가르킨다
      bip = (BITMAPINFOHEADER *)(cimage+ sizeof(BITMAPFILEHEADER));//두번째 구조체 BITMAPFILEHEADER 가 cimage를 가르킨다
      //wsprintf(string,TEXT("파일의 크기: [ %d ]Byte"),bfp->bfSize);//bmp파일의 크기 출력

      
      
      
    }
    else
    {
      SendMessage(hWnd,WM_DESTROY,0,0);    //파일을 못 읽어올시 WM_DESTROY 강제호출
    }

    {
      int imul = (bip->biHeight)*(bip->biHeight);
      int imax = 0;

      imageP = cimage + (bfp->bfOffBits);    
      for(iYcnt=0; bip->biHeight > iYcnt; iYcnt++)    
      {
        for(iXcnt=0; bip->biWidth > iXcnt; iXcnt++)  
        {
          ++iRGBcnt[EMB_RED][*imageP];    //빨간색의 개수
          ++iRGBcnt[EMB_GRN][*(imageP+1)];  //초록색의 개수
          ++iRGBcnt[EMB_BLU][*(imageP+2)];  //파란색의 개수

          
          imageP = imageP + 3;      
        }
        imageP = imageP + (bip->biWidth %4);
      }
      imageP = cimage + (bfp->bfOffBits);
      /* 각 색의 제일 큰 값 */
      for(iYcnt=0255 > iYcnt; iYcnt++)    //bmp파일의 "높이"
      {
        if (imax < iRGBcnt[EMB_RED][iYcnt])
        {
          imax = iRGBcnt[EMB_RED][iYcnt];
        }
        if (imax < iRGBcnt[EMB_GRN][iYcnt])
        {
          imax = iRGBcnt[EMB_GRN][iYcnt];
        }
        if (imax < iRGBcnt[EMB_BLU][iYcnt])
        {
          imax = iRGBcnt[EMB_BLU][iYcnt];
        }
        
      }
      if(imax > 256)
      {
        imax = 256;
      }
      for(iYcnt=0255 > iYcnt; iYcnt++)    //bmp파일의 "높이"
      {
        
        iRGBcnt[EMB_RED][iYcnt] %= imax;  //빨간색의 개수
        iRGBcnt[EMB_GRN][iYcnt] %= imax;  //초록색의 개수
        iRGBcnt[EMB_BLU][iYcnt] %= imax;  //파란색의 개수
      }
      
    }

    return 0;

  case WM_PAINT:
    if(0 == bfp)                //WM_CREATE 에서 파일을 못읽어올시 SendMessage call 전에 WM_PAINT 가 실행되는걸 막아준다
    {
      return 0;
    }
      hdc = BeginPaint(hWnd,&ps);
      
    
      //MyTextOut(hdc,10,10,string);      //비트맵 파일크기

      imageP = cimage + (bfp->bfOffBits);    //bmp데이타의 offset(시작주소)를 imageP로 넘긴다.
      for(iYcnt=0; bip->biHeight > iYcnt; iYcnt++)    //bmp파일의 "높이"
      {
        for(iXcnt=0; bip->biWidth > iXcnt; iXcnt++)  //bmp파일의 "너비"
        {
          /* 사진이 거꾸로 출력되기떄문에 y축 밑에서부터 그리기위해 710 - 를 넣어준다 */
          SetPixel(hdc,iXcnt, bip->biHeight-iYcnt,RGB(*(imageP+2),*(imageP+1),*imageP)); //오른쪽
          //SetPixel(hdc,bip->biWidth+(bip->biWidth+1-iXcnt),bip->biHeight-iYcnt,RGB(*(imageP+2),*(imageP+1),*imageP));//왼쪽
          //SetPixel(hdc,bip->biWidth+(bip->biWidth+1-iXcnt),bip->biHeight+iYcnt+3,RGB(*(imageP+2),*(imageP+1),*imageP));//왼쪽 아래
          //SetPixel(hdc,iXcnt, iYcnt+bip->biHeight+3,RGB(*(imageP+2),*(imageP+1),*imageP)); //오른쪽 아래
          imageP = imageP + 3;      //RGB 3바이트 씩 이동
        }
        imageP = imageP + (bip->biWidth %4);
      }
      /*RED 값 */
      BlockPen=CreatePen(PS_SOLID,1,RGB(0,0,0));
      MyPen=CreatePen(PS_SOLID,1,RGB(255,0,0));
      SelectObject(hdc,BlockPen);
      MoveToEx  (hdc,bip->biWidth+20        ,0 ,NULL);
      LineTo    (hdc,bip->biWidth+20        ,256);
      LineTo    (hdc,bip->biWidth+20 + 255      ,256);
      SelectObject(hdc,MyPen);
      for(iXcnt = 0;iXcnt < 256;++iXcnt)
      {
        MoveToEx  (hdc,bip->biWidth+20 + 1 + iXcnt    ,255-iRGBcnt[EMB_RED][iXcnt] ,NULL);
        LineTo    (hdc,bip->biWidth+20 + 1 + iXcnt    ,255);
      }
      DeleteObject(MyPen);
      

      /*GREEN 값 */
      MyPen=CreatePen(PS_SOLID,1,RGB(0,255,0));
      SelectObject(hdc,BlockPen);
      MoveToEx  (hdc,bip->biWidth + 40 + 255    ,0,NULL);
      LineTo    (hdc,bip->biWidth+ 40 + 255      ,256);
      LineTo    (hdc,bip->biWidth+ 40 + 255 + 255  ,256);
      SelectObject(hdc,MyPen);
      for(iXcnt = 0;iXcnt < 256;++iXcnt)
      {
        MoveToEx  (hdc,bip->biWidth+40 + 255 + 1 + iXcnt    ,255-iRGBcnt[EMB_GRN][iXcnt] ,NULL);
        LineTo    (hdc,bip->biWidth+40 + 255 + 1 + iXcnt    ,255);
      }
      DeleteObject(MyPen);



      /*BLUE 값 */
      MyPen=CreatePen(PS_SOLID,1,RGB(0,0,255));
      SelectObject(hdc,BlockPen);
      MoveToEx  (hdc,bip->biWidth+20        ,255 + 20 ,NULL);
      LineTo    (hdc,bip->biWidth+20        ,255 + 20 + 256);
      LineTo    (hdc,bip->biWidth+20+255      ,255 + 20 + 256);
      SelectObject(hdc,MyPen);
      for(iXcnt = 0;iXcnt < 256;++iXcnt)
      {
        MoveToEx  (hdc,bip->biWidth+20 + 1 + iXcnt    ,(255+20+256)-iRGBcnt[EMB_BLU][iXcnt] ,NULL);
        LineTo    (hdc,bip->biWidth+20 + 1 + iXcnt    ,255 + 20 + 256);
      }
      DeleteObject(MyPen);
      DeleteObject(BlockPen);
      EndPaint(hWnd,&ps);
    
    return 0;
  case WM_DESTROY:
    PostQuitMessage(0);
    return 0;
  }
  return (DefWindowProc(hWnd,iMessage,wParam,IParam));
}
void MyTextOut(HDC hdc,int x,int y,LPCTSTR Text)//MyTextOut 함수 정의하여 문자열을 편하게 출력하자
{
  TextOut(hdc,x,y,Text,lstrlen(Text));
}

void Line(HDC hdc, int x1, int y1, int x2, int y2)
{
  MoveToEx(hdc,x1,y1,NULL);
  LineTo(hdc,x2,y2);
}






주석이 부족할수도있습니당...ㄷㄷ


728x90