728x90
반응형

 파일 입출력

#include <iostream>
#pragma warning(disable: 4996)


int main()
{
	FILE* rf = fopen("0000.JSF", "rb"); // 인수값이 두개 들어간다. // rb: 바이너리로 읽겠다.
		//rfpt, wfpt 변수 정석
	if (rf == NULL)
	{
		printf("Open Error");
		return 0;
	}
	
	printf("성공");
	
	fclose(rf);
}

 

코드 한줄화_1

if (rf == NULL){printf("Open Error"); return 0;}

 

코드 한줄화_2

FILE* rf;  
		//rfpt, wfpt 변수 정석
	if ((rf = fopen("0000.JSF", "rb")) == NULL)
	{
		printf("Open Error");
		return 0;
	}

 

파일의 헤더를 배열로 잡을것인가 포안터로 잡을것인가 선택

	BYTE FileHeader[250]; // 메모리250byte 확보
	BYTE *FileHeader = new BYTE[250]; // 값을 자주 변겸할 때

 

알아둬야할 문법

fread(FileHeader, 1, 250, rf); // 90% 사용
fread(&FileHeader[0], 1, 250, rf); // 10% 사용
BYTE *FileHeader = new BYTE[1];
fread(FileHeader, 1, 250, rf); // 90% 사용
fread(&FileHeader, 1, 250, rf); // 컴파일은 되지만 잘못된 문법  [0]이 빠짐
	// unsigned int ImageNumber; // 음수가 들어올 가능성이 없기 때문에 unsigned
	// unsigned로 이용할때는 BYTE, WORD, DWORD
	DWORD ImageNumber;
	//fread(&ImageNumber, 4, 1, rf); // 4바이트씩 1번 읽어라
	fread(&ImageNumber, sizeof(DWORD), 1, rf);
	printf("ImageNumber: %d\n", ImageNumber);​

 

압축사이즈, 가로, 세로 해상도

	DWORD CompressSize;
	fread(&CompressSize, sizeof(DWORD), 1, rf);

	WORD width, height;
	fread(&width, sizeof(WORD), 1, rf); //73
	fread(&height, sizeof(WORD), 1, rf); //56
	printf("width: %d height: %d\n", width, height);
	WORD width24, height24; // 24는 24bit를 의미함
	width24 = width * 3; // 점 1개당 3byte 필요
	height24 = height;
	printf("width24: %d height24: %d\n", width24, height24);

 

압축사이즈, 가로, 세로 해상도 구조체 (위와 같은 코드 )

	// 위 코드 보다 더 좋은 코드
	typedef struct tagJSFImageInfo {
		DWORD CompressSize;
		WORD width, height;
	}JSFImageInfo;

	JSFImageInfo st;
	fread(&st, sizeof(JSFImageInfo), 1, rf);

 

4byte 정렬을 위한 코드 (변수 선언시 연산 속도가 빠름)

 

 

	WORD q = width24 / 4; // 219 /4 = 몫이 나온다
	WORD r = width24 % 4; // 291 % 4 = 나머지가 나온다
	if (r != 0)
	{
		width24 = (q + 1) * 4;
	}
    printf("width24: %d height24: %d\n", width24, height);

 

출력코드

	FILE* wf = fopen("0000.bmp", "wb");
	if (wf == NULL)
	{
		printf("Write Open Error");
		return 0;
	}
	fwrite(&bfh, sizeof(BITMAPFILEHEADER), 1, wf);
	fwrite(&bif, sizeof(BITMAPINFOHEADER), 1, wf);
	fwrite(&Image24, 1, size24, wf);
	fclose(wf);

 

전체코드

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#pragma warning(disable: 4996)

int main()
{
	FILE* rf;  
		//rfpt, wfpt 변수 정석
	if ((rf = fopen("0000.JSF", "rb")) == NULL)
	{
		printf("Open Error");
		return 0;
	}
	// 파일의 헤더를 배열로 잡을것인가 포안터로 잡을것인가 선택
	BYTE FileHeader[250]; // 메모리250byte 확보
	fread(FileHeader, 1, 250, rf); // 90% 사용 // 1바이트씩 250씩 읽어라
	printf("FiledHeader: %d\n", FileHeader[250]);
	// unsigned int ImageNumber; // 음수가 들어올 가능성이 없기 때문에 unsigned
	// unsigned로 이용할때는 BYTE, WORD, DWORD // DWORD = unsigned int, WORD = unsigned short, BYTE =
	DWORD ImageNumber; //이미지 개수 변수
	//fread(&ImageNumber, 4, 1, rf); // 4바이트씩 1번 읽어라
	fread(&ImageNumber, sizeof(DWORD), 1, rf); // 2번째 인수 = n Byte, 3번째 인수 = 2번째 인수를 몇번 읽으세요
	printf("ImageNumber: %d\n", ImageNumber); // 출력코드를 통해 값을 보는 습관을 가질것
	
	// 첫번째 그림의 정보가 시작된다.
	// for문장 예약. for (int i = 0; i < ImageNumber; i++)
	BYTE reserved[26]; // 26byte 예약
	fread(reserved, 1, 26, rf); // 1바이트씩 26번 읽는다.


	// 압축사이즈, 가로, 세로 해상도
	DWORD CompressSize; // 압축 사이즈 변수
	fread(&CompressSize, sizeof(DWORD), 1, rf);

	WORD width, height;
	fread(&width, sizeof(WORD), 1, rf);  //73 가로 (점의 개수)
	fread(&height, sizeof(WORD), 1, rf); //56 세로 (점의 개수)
	printf("width: %d height: %d\n", width, height);
	// 73, 56이 나오는 이유는 위에서 0000파일을 이미 헤더 250 과 리져브 26 바이트를 읽었기 때문에 
	// 0000파일에서 해상도 위치부터 읽기 시작한다


	WORD width24, height24; // 24는 24bit를 의미함
	width24 = width * 3; // 점 1개당 3byte 필요
	height24 = height;
	printf("width24: %d height24: %d\n", width24, height24);

	//변수를 만들어서 사용하는것이 연산속도가 빠르다.
	WORD q = width24 / 4; // 219 / 4 = 몫이 나온다
	WORD r = width24 % 4; // 219 % 4 = 나머지가 나온다
	if (r != 0)
	{
		width24 = (q + 1) * 4;
	}
	printf("width24: %d height24: %d\n", width24, height24);

	long size16 = width * 2 * height; // 가로픽셀개수 * 2 *세로해상도
	long size24 = width24 * height24;
	// size16: 8176(=73*2*56), size24: 12320
	printf("size16: %d size24: %d", size16, size24);
	
	BYTE* Image16 = new BYTE[size16];
	BYTE* Image24 = new BYTE[size24]; 
	memset(Image16, 0, size16);
	memset(Image24, 0, size24);

	for (int i = 0; i < height; i++) // 56번 반복
	{
		WORD idNum = 0; 
		fread(&idNum, 2, 1, rf); // 2바이트씩 1번 읽기
		printf("idNum: %d\n", idNum);
		// offset = y * w + x
		DWORD _OFFSET = (height - 1 - i) * width * 2;// 중복되는 변수 or 예약어를 피하기 위해서 _ 언더바 사용 // +0;
		// printf("%d\n", _OFFSET);
		switch (idNum)
		{
		case 0: // 공백인 경우 // 코드 처리를 하지 않는다 // 단, 배경색상을 변경하고 싶으면 코드를 작성한다.
			{

			}
			break;
		case 1: //라인이 채워진경우
		{
			fread(Image16 + _OFFSET, 2, width, rf);
		}
		break;

		default: // 세트를 가지고 있는 경우
		{
			WORD BlankNum, PixelNum;
			for (int j = 0; j < idNum - 1; j++)
			{
				fread(&BlankNum, 2, 1, rf);
				_OFFSET += (BlankNum * 2);
				fread(&PixelNum, 2, 1, rf);
				fread(Image16 + _OFFSET, 2, PixelNum, rf);
				_OFFSET += (PixelNum * 2);
			}
		}
		break;
		}
	}
	// WORD XXX = 0x0a0d;
	for (int i = 0, k = 0; i < height; i++)
	{
		for (int j = 0; j < width; j++, k++)
		{
			WORD data16 = *(WORD *)(Image16 + k * 2);
			BYTE R = (data16 & 0xf800) >> 8;
			BYTE G = (data16 & 0x07E0) >> 3;
			BYTE B = (data16 & 0x001f) << 3;

			*(Image24 + (i*width24) + (j * 3) + 2) = R;
			*(Image24 + (i*width24) + (j * 3) + 1) = G;
			*(Image24 + (i*width24) + (j * 3) + 0) = B;
		}
	}


	// 24bit bmp출력 파일을 작성한다
	BITMAPFILEHEADER bfh; //14byte 정보 저장
	bfh.bfType		= 19778; // bmp >> 19778 == 0x424D
	bfh.bfSize		= 12374; // 220 * 56 + 54 = 12374
	bfh.bfReserved1	= 0;
	bfh.bfReserved2	= 0;
	bfh.bfOffBits	= 54; // 고정(정적) static
 
	BITMAPINFOHEADER bif;
	bif.biSize				= 40;			// 인포헤더 사이즈
	bif.biWidth				= 73;
	bif.biHeight			= 56;
	bif.biPlanes			= 1;			// 그림 개수
	bif.biBitCount			= 24;			// 24bit color
	bif.biCompression		= 0;			// 압축안됨
	bif.biSizeImage			= 12374 - 54;	// 헤더파일 제외한 사이즈 가변적
	bif.biXPelsPerMeter		= 0;
	bif.biYPelsPerMeter		= 0;
	bif.biClrUsed			= 0;
	bif.biClrImportant		= 0;
	
	
	// 출력코드
	FILE* wf = fopen("0000.bmp", "wb");
	if (wf == NULL)
	{
		printf("Write Open Error\n");
		return 0;
	}
	fwrite(&bfh, sizeof(BITMAPFILEHEADER), 1, wf);
	fwrite(&bif, sizeof(BITMAPINFOHEADER), 1, wf);
	fwrite(Image24, 1, size24, wf); //생성 파일 크기 = 12374
	fclose(wf);


	delete[] Image16;  //메모리해제
	delete[] Image24;


	printf("성공");
	fclose(rf);
}

 

 

73 x 56 이미지 출력

728x90
반응형

+ Recent posts