어쩌다가.. Windows API 프로그래밍을 해야 할 일이 생겼다.
물론. 그냥 재미 삼아 하는거지만 ㅎㅎ

off screen DC 에 그려지는 픽셀 데이터를 빼 와서
JNI을 통해서 Java 쪽에 넘겨 주어야 하는 일이 발생했다.


이것저것 하다가. 분명히 색깔은 가지고 오는데,
비율이 안 맞는것이다. ㅠ_ㅠ

ㅎㅎㅎㅎ 알고 봤더니 -_- width와 height 인자를 반대로 주고 있었다는.. ㅋㅋㅋㅋ

이제 그 부분을 고친 뒤에, 수행을 해 봤는데. 이거 너무나 느린것이다.


1. Java 에서 int[]을 만들어서 C 를 호출한다.
2. C 에서는 DC에 그림을 그린다.
3. C 에서 DC에 그려진 그림의 각 픽셀을 int[] 에 저장한다.
4. Java 측으로 돌아와서 int[] 을 정보를 가지고 1pixel씩 그림을 그려준다.

900 * 900 에 대해서 위의 작업을 해 주는데, 무려 2.2초씩이나 걸리는것이다.

처음에는 900 * 900 의 픽셀들에 일일이 값을 셋팅하고,
자바에서 다시 그림을 그려주는 작업이 시간이 많이 걸릴거라 생각하고,
더 이상 퍼포먼스를 높일 수 없겠군아~ 라고 생각을 했으나..
확인 결과 이게 왠일 -_-;;


C 측의 GetPixel 에서 시간이 2초 정도 걸리는것이다. -_-;;;;;

혹시나 DC 가 아니고 BitMap 에 그려진 정보를 바로 볼 수는 없을까? 라는 생각에
msdn을 열나 뒤져 봤지만, 윈도우 개발자가 아닌지라 -_-;;;
구글을 열나 뒤져 봤지만, 윈도우 개발자가 아닌지라 -_-;;;


결국 소멤(삼성소프트웨어멤버쉽)에 댕기는 친구에게,
"이러이러 하니 어쩌면 좋겠느냐~" 했더니 -_-
단 20초만에 -_-;; 사이트를 불러주는 자식 -_-; 그것도 한국어 사이트로 -_-;;

구글에서 -_- GetPixel 로 검색해 봤단다 -_-;;



물론 나도 해 봤다. GetPixel , GetPixel slow, DC GetPixel 등등으로..
( 난 영문으로 -_-;;;;; )


한국에도 좋은 자료가 많이 있군아~ 라는 생각을 깊이 했다. -_-;;;



암튼 GetPixel 에 대해서 좀 알아 보자.

COLORREF GetPixel(
  HDC hdc,    // handle to DC
  int nXPos,  // x-coordinate of pixel
  int nYPos   // y-coordinate of pixel
);

너무나도 단순한 함수이다.
해당 DC의 x, y 위치에 있는 픽셀을 COLORREF ( DWORD - 즉 unsigned int ( 32 bit ) ) 로
반환 해 주는 함수 이다.

하지만 이 놈이 느린 이유가 있다.

1. DC 에 선택되어 있는 비트맵 구조를 알아 온다.
2. 해당 비트맵 버퍼를 알아 온다.
3. 비트맵 버퍼를 파싱하여 x, y 위치에 있는 Pixel 정보를 얻오온다.

http://www.gosu.net/GosuWeb/Article-detail.aspx?ArticleCode=185
( 안타깝게도 고수 닷넷은 가입을 하고 로그인 해야만 문서를 볼 수 있다. )

위의 과정 중에서 하나의 이미지에 대해서 작업할 경우
1, 2, 그리고 3번의 일부분은 최초 단 한번만 수행하고,
이미 구해진 정보를 활용하도록하면 초 스피드로 처리할 수 있다는 게 핵심이다.


해당 링크에 가 보면 class 형태로 만들어져 있는 코드가 있고,
그것을 그대로 활용하기만 하면 문제 없이 사용할 수 있다.

하지만!!!
사용하는 Type 들이 CDC 를 사용한다던지 -_-;
CBitmap 를 사용한더던지 하는 -_-; 정말로 -_- 재미 없는
MFC 코드를 쓰고 있다는것이.. 걸림돌이었다. -_-;;


그래서 -_- 그냥 static 컴파일 해 버릴려고 막 마음을 가질 무렵 -_-;
아까 도움을 주었던 친구가 CDC와 CBitmap을 쓰던 놈을 -_-
Windows API만 가지고 사용할 수 있도록 -_-
HDC등으로 변경해 주었다. ㅋㅋㅋ
( 결국 -_- 내가 한일은 거의 없다는 거다. ㅎㅎ )

위의 링크에서 제공되는 것도 문제가 좀 있기는 하다.
16컬러 이하의 이미지 일때 처리가 되지 않는 등의 문제가 있다고는 한다.
( 맞는지는 모르겠는데 DC에 적용된 Bitmap이 16컬러 이하인 경우를 이야기 하는것 같다. )
( 하지만 요즘에 16컬러 이하를 쓰는 사람은 없다고 보는게 옳을듯 하다 -_-; )




결론 1.
GetPixel 이 너무 느려서 못 써 먹을때에는 위의 링크를 이용하도록 하자.

결론 2.
900 * 900 이미지에 대해 개선전 2.2초대가 걸리던 것이 -_- 개선 후 0.2초대가 걸린다 -_-;


현재 Java 측 코드가 무식하게 -_-
BufferedImage를 만든뒤에 거기의 Graphics에 -_-
1 pixel 씩 drawline 하고 있다. -_-;;
이것도 개선해야 하는데 -_- 개선할 여지가 안 보인다. -_-;;;


암튼
주말에 몸이 안 좋아서 계속 쉬었는데.. 그래도 마냥 논것 같지 않아서. 다행이다 싶다. ㅎㅎ

신고
  1. 유겸애비 2006.12.11 06:49 신고

    축하해요. 내가 맛난거 사주지요

    • Chan 2006.12.11 09:57 신고

      하하 ;; 아직까지 문제가 있긴있다는 ;; ㅎㅎ;;
      투명도 처리가 ;; ㅎㅎ ;;

  2. 옷장수 2006.12.11 09:17 신고

    그렇게, 피곤해서 이사나 제대로 하겠소? ㅋㅋ

    • Chan 2006.12.11 09:57 신고

      짐은 옷, 이불, 놋북이 끝인지라. ㅎㅎ;;

  3. SnowBoy 2006.12.11 10:03 신고

    저는 16bit이하로 쓰는 경우가 자주 있어요 흐흐,,윈도우즈 터미널 서비스 클라이언트로 붙으면 대략 난감.. ^^;;;;

    • Chan 2006.12.11 10:19 신고

      ㅋㅋㅋㅋ 16컬러 입니다. ㅋㅋㅋㅋ
      비트로 따지면 4bit?? ㅋㅋㅋㅋ

  4. 타오 2006.12.11 16:10 신고

    조만간 win32 jni 작업을 해야할지도 모르는데 잘됐삼! 헬프미!

    • Chan 2006.12.12 00:42 신고

      ㅋㅋ 실력 좋으면서 무슨 부탁을.. ㅎㅎ
      저도 -_- 복사해서 붙여넣는 수준이라. ㅋㅋ

  5. 16비트는 계산을... 2010.10.30 04:51 신고

    16비트 컬러의 경우(16색상 말고)는 저 코드 써봣는데
    잘못된 값을 얻어오더군요...
    코드작성자분이 뭔가 계산을 잘못한듯.

    • Chan 2010.10.31 23:28 신고

      오우~ 글 감사합니다.
      최근에도 이 글이 검색어로 많이 노출이 되는데.
      좋은 정보가 되었네요 ^^

      감사합니다.

  6. ;;;; 2011.07.17 13:09 신고

    저.. 혹시 그.. API로 된 소스코드좀 주실수 있으신가요;;
    C++ Class는 배워본적이 없는지라 전혀 이해가 안갈뿐더러
    CDC에서 막혀서 이틀째이러고있는데;;
    다른곳을 아무리 검색해봐도 나오는건 전부 Class를 쓰거나 CDC를쓰더군요;;

    그래서 한번

    MyBit=CreateCompatibleBitmap(desktop,1,1);
    OldBit=(HBITMAP)SelectObject(mdesktop,MyBit);

    BitBlt(mdesktop,0,0,1,1,desktop,x,y,SRCCOPY);//고속복사
    GetBitmapBits(MyBit,data_size,&pattern);//비트맵 얻어옴
    이런식으로 만들어봤는데;;; 속도가;;
    그리고 활성화된 게임같은창같은곳에 가져가면 0xffffff만 나오는;;;;

    어떡해 못보내주시나요?
    vain430@naver.com으로..

+ Recent posts