화면 전체를 가득 메우는 픽셀연산은 느립니다.
마우스로 드래그하는 시스템을 구성하여 당겨 흔들어 보면
알 수 있습니다. 오늘 그것을 빠르게 구성해 봅시다.
1. 느린 이유
용량이 많은 작업인 것은 어쩔 수 없습니다.
그것을 제외하고 이유는 보통 3가지입니다.
(클리핑을 통해 더 빨리 만든다던지, 처음작업시 이미지를 구성해서
매번 뿌린다던지의 꽁수는 각 작업상의 상황에 따른 것이니 논외로 합니다.)
1) 픽셀함수호출시간 2) for의 조건문과 픽셀접근계산 3) RGB를 분리했다 결합하는 연산
1번은 픽셀처리의 for문안에 절대 다른 함수를 호출해서는 안됩니다.
GetPixel, SetPixel은 독약입니다. 이유는 매 픽셀 "함수호출시간 + 클리핑계산 + 비트수맞춤"입니다.
2번은 memcpy식의 루프로 바꿉니다.
// 보통의 코드
RGBQUID* offset = 시작주소;
INT width = 이미지가로길이, height = 이미지세로길이;
INT row = 4배수정렬된 가로점의 갯수; // 바이트수가 아님
///////////////////////////////////////////////
for(int y = CY, yend = CY + CH; y < yend; ++y)
for(int x = CX, xend = CX + CW; x < xend; ++x)
{
offset[x + row * (height - y - 1)] = 0x00BBGGRR;
}
// memcpy식 코드
RGBQUID* offset = 시작주소;
INT width = 이미지가로길이, height = 이미지세로길이;
INT row = 4배수정렬된 가로점의 갯수; // 바이트수가 아님
INT jump = width & 0xF, xoff = 0, xoffend = 0;
///////////////////////////////////////////////
for(int yoff = CX + row * (height - CY - 1), yoffend = yoff - row * CH; yoffend < yoff; y -= row)
{
xoff = yoff;
xoffend = yoff + width;
switch(jump)
while(xoff < xoffend)
{
case 0x0: offset[xoff++] = 0x00BBGGRR; // 매크로함수로 깔끔하게 바꿀 수 있겠죠? ^^;
case 0x1: offset[xoff++] = 0x00BBGGRR;
case 0x2: offset[xoff++] = 0x00BBGGRR;
case 0x3: offset[xoff++] = 0x00BBGGRR;
case 0x4: offset[xoff++] = 0x00BBGGRR;
case 0x5: offset[xoff++] = 0x00BBGGRR;
case 0x6: offset[xoff++] = 0x00BBGGRR;
case 0x7: offset[xoff++] = 0x00BBGGRR;
case 0x8: offset[xoff++] = 0x00BBGGRR;
case 0x9: offset[xoff++] = 0x00BBGGRR;
case 0xa: offset[xoff++] = 0x00BBGGRR;
case 0xb: offset[xoff++] = 0x00BBGGRR;
case 0xc: offset[xoff++] = 0x00BBGGRR;
case 0xd: offset[xoff++] = 0x00BBGGRR;
case 0xe: offset[xoff++] = 0x00BBGGRR;
case 0xf: offset[xoff++] = 0x00BBGGRR;
}
}
3번은 비트연산으로 대체합니다.
// RGBQUID형 A와 B의 평균값 C
C = ((A >> 1) & 0x007f7f7f) + ((B >> 1) & 0x007f7f7f);
// RGBQUID형 A의 B시프트(0~7) 마스크 M 사전제작
M = 0xff808080;
while(B--) M |= M >> 1;
M = ~M;
// RGBQUID형 A의 B시프트(0~7) 페이드아웃 C
C = (A >> B) & M;
// RGBQUID형 A의 B시프트(0~7) 페이드인 C
C = ~((~A >> B) & M);
기본 로직만 이해하면 얼마든지 응용이 가능하겠죠?
댓글
댓글 쓰기