81.3 소스코드에서 이해가 잘 되지 않는 부분이 있습니다.
, L EH님이 작성픽셀 데이터를 ASCII 문자로 변환하는 부분에서 2가지가 이해되지 않습니다.
(질문은 주석형태로 달았습니다.)
// 픽셀 데이터는 아래 위가 뒤집혀서 저장되므로 아래쪽부터 반복 // 세로 크기만큼 반복 for (int y = height - 1; y >= 0; y--) // 첫 번째 질문 : height에 왜 -1을 하는지 이해가 되지 않습니다. { // 가로 크기만큼 반복 for (int x = 0; x < width; x++) { // 일렬로 된 배열에 접근하기 위해 인덱스를 계산 // (x * 픽셀 크기)는 픽셀의 가로 위치 // (y * (세로 크기 * 픽셀 크기))는 픽셀이 몇 번째 줄인지 계산
// 두 번째 질문 :
픽셀의 가로 위치는 x* PIXEL_SIZE로 이해가 되는데 픽셀이 몇 번째 줄인지에 대한 계산은 왜 y * (width * PIXEL_SIZE)가 되는지 이해가 안됩니다. // 남는 공간 * y는 줄별로 누적된 남는 공간 int index = (x * PIXEL_SIZE) + (y * (width * PIXEL_SIZE)) + (padding * y); // 현재 픽셀의 주소를 RGBTRIPLE 포인터로 변환하여 RGBTRIPLE 포인터에 저장 RGBTRIPLE *pixel = (RGBTRIPLE *)&image[index]; // RGBTRIPLE 구조체로 파랑, 초록, 빨강값을 가져옴 unsigned char blue = pixel->rgbtBlue; unsigned char green = pixel->rgbtGreen; unsigned char red = pixel->rgbtRed; // 파랑, 초록, 빨강값의 평균을 구하면 흑백 이미지를 얻을 수 있음 unsigned char gray = (red + green + blue) / PIXEL_SIZE; // 흑백값에 ASCII 문자의 개수를 곱한 뒤 256으로 나누면 흑백값에 따라 // ASCII 문자의 인덱스를 얻을 수 있음 char c = ascii[gray * sizeof(ascii) / 256]; // 비트맵 이미지에서는 픽셀의 가로, 세로 크기가 똑같지만 // 보통 ASCII 문자는 세로로 길쭉한 형태이므로 정사각형 모양과 비슷하게 보여주기 위해 // 같은 문자를 두 번 저장해줌 fprintf(fpTxt, "%c%c", c, c); // 텍스트 파일에 문자 출력 } fprintf(fpTxt, "\n"); // 가로 픽셀 저장이 끝났으면 줄바꿈을 해줌 } fclose(fpTxt); // 텍스트 파일 닫기 free(image); // 픽셀 데이터를 저장한 동적 메모리 해제
Re: 81.3 소스코드에서 이해가 잘 되지 않는 부분이 있습니다.
, 도장_ 관리자님이 작성그림의 포맷이 1024*768이면
768이 height 값일 것입니다.
이 경우에 루프는 0~767까지 반복해야 합니다.
C 언어는 0부터 카운팅합니다.
만일 768까지 루프를 반복하면 범위를 벗어나기 때문에 프로그램 오류로 중단될 것입니다.
그림 크기가 1024*768이면 가로가 1024입니다.
height = 0, 첫 번째 줄은 1024 바이트가 차지합니다. width 값도 0~1023까지입니다.
height = 1, 두 번째 줄도 1024 바이트가 차지합니다. width 값은 1024~2047까지입니다.
height = y이고, 세로 방향인데, 층수라고 생각하면 됩니다.
이제 계산식이 이해가 될 겁니다.
이미지가 칼라이므로 R,G,B가 각각 1바이트이니 가로는 3배수로 계산해야 합니다.
3바이트 = 1 픽셀을 표현하고 있죠.