본문 바로가기

공부/컴퓨터

[Windows API] DC에서 GetPixel 이 너무 느릴때..

반응형

어쩌다가.. 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 하고 있다. -_-;;
이것도 개선해야 하는데 -_- 개선할 여지가 안 보인다. -_-;;;


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

반응형