참조 사이트 http://myhome.naver.com/eryners/programming_1.htm
| ||
(1) 파일 구성도 그림1) 8비트 그림2) 8비트 이상 (2) 파일헤더(FileHeader) - 파일크기(s), 파일 형태(t), 등등의 정보를 가지고 있는 구조체입니다. (2) 정보헤더(InfoHeader) - 가로크기(w), 세로크기(h), 비트 수(b) 등등의 정보를 가지고 있는 구조체입니다. (3) 팔레트(Palette) - 컴퓨터에서 사용되는 모든 색은 R,G,B 조합으로 만들어 진다는 것을 알고 계실 것 입니다. 8비트(256 색) 컬러에서는 256가지 색 밖에 사용할 수 없는데 그 많고 많은 색 중에서 256가지 색을 어떻게 알아낼 수 있을까요?? 답은 팔레트(Palette)입니다. 8비트 컬러는 픽셀 자체가 색상 정보를 가지고 있지 않기 때문에... 팔레트를 필요로 합니다. (4) 이미지 데이터 - 실제 이미지 데이터는 그림1,그림2와 같이 거꾸로 저장되어 있는 것이 특징입니다. 2. 컬러별 특징 (1) 8비트 컬러 - 8비트 컬러는 각 픽셀이 8비트 즉 1바이트의 R,G,B 값 중에 하나를 가지며, 픽셀 자 체가 색상 정보를 가지고 있지 않기 때문에 팔레트를 필요로 합니다. 256색을 가지고 하나의 그림을 표현해야 하기때문에 색에 대한 많은 제약을 받지만 출력할 때 빠른 속 도가 장점입니다. (2) 24비트 컬러 - 24비트 컬러는 각 픽셀이 24비트 즉 3바이트의 R,G,B 조합의 값으로 이루어져 있 는데 각 R,G,B 값들이 1바이트씩 가지고 있습니다. 픽셀 자체가 색상 정보를 가지고 있기 때문에 8비트처럼 팔레트를 필요로 하지 않습니다. 16만 가지 이상의 색(255 * 255 * 255)을 사용해서 하나의 그림을 표현 하므로, 색에 대한 제약은 거의 받지 않지만 8비트보다 데이터의 용량이 커지고 출력할 때 느리다 는 단점이 있습니다. 3. 주위 사항들 (1) 회전(Rotate) - BMP 파일의 이미지 데이터는 메모리 상에서 위의 그림들처럼, 거꾸로 저장되어 있는데 출력될 때에는 거꾸로 뒤집혀서 출력되기 때문에 우리가 실제 느낄 수는 없 는 것 입니다. 이 이야기가 무슨 이야기냐 하면.... 윈도우에서는 좌표 (0,0)은 좌측 상단의 처음을 의미 하지만, BITMAP에서의 좌표 (0,0)은 좌측 상단이 아닌 좌측 하단의 처음이 되기 때문에 이미지 데이터가 위에서 아래가 아닌 아래에서 위로 즉 뒤집혀서 저장되어 있는 것 입니다. (2) 4의 배수 - BMP파일의 가로(width) 크기는 되도록 4의 배수의 법칙을 적용하여 4의 배수로 저장 하셔야 합니다. 꼭 필수는 아니지만 그러기를 권장합니다. 그 이유는 비디오 메모리 4의 배수의 체계를 가지고 있기 때문입니다. 그림 이란 것이 우리가 눈으로 보는 것처럼 가로(width), 세로(height)의 큰 사각형 처럼 저장되어 있는 것이 아니라... 선형 즉 연속적인 데이터로 저장되어 있어서 이 것을 화면에 출력해 주기 위해서는 가로(width) 크기에 맞게 끊어서 출력해 주어야 합니다. ------ 앞서도 이야기 했듯이 비디오 메모리가 4의 배수 체계를 가지고 있으니 4, 8, 12, 16, 20, 24, 28, 32...160... 320... 640... 1280바이트 등등이 될 수 있습니다. 가로(width) 의 크기가 5이고, 세로(height)의 크기가 6인 24비트의 BMP 파일을 화면에 출력 했 다면 결과는 어떻게 나올까요? 가로(width) 총 바이트 수(5 x 3= 15)가 4의 배수가 되지 않으니 화면에 제대로 된 그림이 출력되지 않겠네요. 여러분들의 이해를 돕기 위해 그림을 준비 했습니다. ********************************************************************* * 원본 그림(가로 15바이트) * 그림출력(4의 배수 미적용 ) - 비디오 메모리는 4의 배수 체계 때문에 15바이트가 아니라 16바이트가 됩니다. 먼저 15바이트의 빨간색을 출력한 후에 다음 라인으로 이동해서 노란색을 출력 해야 하지만, 가로(width) 총 바이트 수는 15바이트 뿐 이기때문에 엉뚱한 위치 에 출력될 수 밖에 없는 것 입니다. ㅡㅡ; * 그림 출력(4의 배수 적용) - 4의 배수를 적용해 가로(width)의 총 바이트 크기를 15가 아닌 16바이트로 해 주 었기 때문에 화면에 제대로 된 그림이 출력됩니다. ^^; * 4의 배수 법칙 - 가로(width)크기를 51로 해서 저장했을 경우 4의 배수 법칙에 의해 실제로는 52 크기만큼 해주어야 합니다. - 42 -> 44, 23 -> 24, 81 -> 84 ********************************************************************* ********************************************************************* 우리가 윈도우즈의 "그림판"이나, 어도비사의 "포토샵"에서 가로(width) 크기를 4의 배수로 하지 않아도 원하는 그림의 결과를 얻을 수 있는 이유는 그 프로그램들 자체 적에서 4의 배수로 만들어서 저장/읽기 해주기 때문입니다. 그런데..... 만약 우리가 BMP파일 저장/로드 기능이 있는 프로그램(Sprite Tool, Map Tool)을 만든다고 했 을 때에는 4의 배수 적용을 반드시 해 주어야만 합니다. 그렇지 않으면 원하는 결과 를 얻을 수 없겠죠. 밑에 저장/ 읽기 그림을 보시면서 이해해 보세요. ********************************************************************* * 저장(save)/읽기(load)하는 그림이 4의 배수가 적용이 되지않았을 때, 즉 가로(width)크기가 4의 배수가 아니 였을 경우... * 24비트 BMP 저장(Save) 4의 배수 적용 4의 배수 미적용 * 24비트 BMP 로드(Load) 4의 배수 적용 4의 배수 미적용 * 4의 배수 구하는 공식 4의 배수 = (가로크기 * (비트수/8) + 3) & ~3 제가 예전에 회사를 다닐 때의 기억이 떠오르네요. 그 게임은 PC용 아케이드 게임 이었고, 오락실용으로 컨버팅(converting)하는 작업을 하고 있었습니다. 오락실용 게임기에서는 4바이트(byte)가 기준이라 하여... 하는 수 없이 2바이트(byte) 화면 출력 알고리즘을 4바이트(byte)로 수정해서 화면에 출력해 보았습니다. 그런데 어떤 그림은 제대로 출력이 되고 또 어떤 그림은 찌그러져 출력이 되어서... 당황했던 적이 있었습니다. 나중에 알고 보니 그림의 가로(width) 크기가 4의 배수 가 되지않고 홀수인 그림들이 찌그러져 나오는 것 이더군요. ㅡㅡ; * 테스트 파일 파일명 : hero.spr 비 트 : 16비트 가 로 : 51 세 로 : 60 * 2바이트 화면 출력 알고리즘(16비트 컬러 기준) int nTargetWidth= ( SCREEN_WIDTH - m_ImageWidth); for(int y =0; y < m_ImageHeight; y++) { for(int x =0; x < m_ImageWidth; x++) { *pTarget++ = *pSource++; // pTarget, pSource는 2바이트 // pTarget는 실제 화면 포인터 // pSource는 그림데이터를 가리키는 포인터 } pTarget= pTarget + nTargetWidth; } * 4바이트 화면 출력 알고리즘(16비트 컬러 기준) int nTargetWidth= (SCREEN_WIDTH - m_ImageWidth) >>1; for(int y =0; y < m_ImageHeight; y++) { for(int x =0; x < m_ImageWidth/2; x++) { *pTarget++ = *pSource++; // pTarget, pSource는 4바이트 // pTarget는 실제 화면 포인터 // pSource는 그림데이터를 가리키는 포인터 } pTarget= pTarget + nTargetWidth; } 화면에 출력할 그림의 가로 크기가 51인 경우 51/2 = 25 이기에 이런 방식으로 출 력 하게 되면 실제 가로크기는 51(102 바이트)인데 반해... 지금 화면에 실제 그려 지는 가로 크기(25 x 4)는 50(100 바이트)까지 밖에 되지 않으므로... 이 남게 되는 1(2 바이트)때문에 실제 출력 시 그림이 찌그러져 나오는 것 이었습니다. 해결 방 법은... 그림의 가로크기(width)에 4의 배수 법칙을 적용해 52로 수정해주는 것 밖 에는 없었습니다. 프로그래밍을 하다 보면 BMP파일의 가로크기에 x2를 해주거나 /2를 해주어야 할 상황이 부득이하게 생기는데 이럴 때를 대비해서 가로 크기는 4의 배수로 해주는 것이 좋겠지요. (3) 컬러(color) 추출 - BMP 파일의 컬러저장 순서는 R,G,B가 아니라 B,G,R 형태로 저장 되어 있는 것 이 특징입니다. 이 순서가 왜 중요하냐 하면?? 그래픽 부분 프로그래밍을 하다 보 면 24비트를 BMP 파일을 16비트로 변환 해야 하거나, 32비트 DWORD형 컬러 값 을 16비트의 WORD형으로 변환해서 사용할 때가 많이 생기는데... 이처럼 컬러 데 이터를 추출해서 사용해야 할 때에 컬러(color)가 저장된 순서는 매우 중요합니다. B,G,R 순서를 무시한 채, R,G,B 순으로 데이터를 추출해서 그림을 출력해 보면 원 본 그림과 다른 엉뚱한 색이 출력되는 것을 보실 수 있을 것 입니다. * targetcolor은 32비트(DWORD) 컬러 데이터 BYTE r= (BYTE) (targetcolor), g= (BYTE) (targetcolor >>8), b= (BYTE) (targetcolor >>16); 밑에 여러분의 이해를 돕기 위해 24비트를 16비트로 만들어 주는 알고리즘과 16비 트를 24비트로 만들어 주는 알고리즘입니다. 알고리즘 by : full_tree@hanmail.net 1. 24비트 -> 16비트
|
프로그래밍/PSP
댓글