728x90
반응형

[JSF을 이용한 파일 입출력 후 bmp파일을 전체 이미지에서 출력하는 예제]

#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, sizeof(DWORD), 1, rf); // 2번째 인수 = n Byte, 3번째 인수 = 2번째 인수를 몇번 읽으세요
	printf("imageNumber : %d\n", ImageNumber);
	
	/////////////////////////////
	int pictureNumber = 0;
	WORD width221;
	WORD height221;
	width221 = (128 * 3); // rgb 때문에 * 3
	height221 = 96;
	long size221 = (width221 * 16) * (height221 * 14); // 가로에는 16개 사진 , 세로에는 14개 사진
	BYTE* Image221 = new BYTE[size221];
	memset(Image221, 0, size221);
	// 첫번째 그림의 정보가 시작된다.
	// for문장 예약. for (int i = 0; i < ImageNumber; i++)	
	for (int a = 0; a < ImageNumber; a++)
	{
		BYTE reserver[26]; // 26byte 예약
		fread(reserver, 1, 26, rf); // 26byte 예약 // 메모리 시작주소
		
		// 압축사이즈, 가로, 세로 해상도
		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;
		printf("size16: %d size24: %d\n", size16, size24);
		// size16: 8176, size24: 12320
		
		BYTE* Image16 = new BYTE[size16];// 16bit형을 받는 메모리 사이즈 확보
		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 + 0 ;
			// 중복되는 변수 or 예약어를 피하기 위해서 _ 언더바 사용 // +0;
			DWORD _OFFSET = (height - 1 - i) * (width * 2);
			printf("%d\n", _OFFSET);
			
			switch (idNum) 
			{
			// 공백인 경우 // 코드 처리를 하지 않는다 
			// 단, 배경색상을 변경하고 싶으면 코드를 작성한다.
			case 0: 
			{ }break;
			
			case 1: // 라인이 채워진 경우
			{ 
				fread(Image16 + _OFFSET, 2, width, rf); // 2 byte씩 가로길이만큼 읽음
			}break;
						//WORD XXX = 0a0d;공백을 위한
			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;
			}
		}
		///////////////////////////////////////////////
		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;
				*(Image221 + (i * width221 * 16) + (96 * width221 * 16)*(13 - a / 16) + (width221*pictureNumber) + (j * 3) + 2) = R;
				*(Image221 + (i * width221 * 16) + (96 * width221 * 16)*(13 - a / 16) + (width221*pictureNumber) + (j * 3) + 1) = G;
				*(Image221 + (i * width221 * 16) + (96 * width221 * 16)*(13 - a / 16) + (width221*pictureNumber) + (j * 3) + 0) = B;
			}
			
		}
		pictureNumber++; // 이미지 번호 증가


		//24bit 출력 파일을 작성한다. 24bit bmp
		BITMAPFILEHEADER bfh;					// 14byte 정보 저장
		bfh.bfType = 19778;						// bmp >> 19778 == 0x424D
		bfh.bfSize = width24 * height24 + 54;	// 220 * 56 + 54 = 12374
		bfh.bfReserved1 = 0;
		bfh.bfReserved2 = 0;
		bfh.bfOffBits = 54;						// 고정(정적)(static) 그림정보 시작지점
		
		BITMAPINFOHEADER bif;
		bif.biSize = 40;						// 인포헤더 사이즈
		bif.biWidth = width;					//73
		bif.biHeight = height;					//56
		bif.biPlanes = 1;						// 그림 개수
		bif.biBitCount = 24;					// 24bit color
		bif.biCompression = 0;					// 압축 여부(0:압축x, 1: 압축O)
		bif.biSizeImage = width24 * height24; // 가변적 (순수한 이미지 사이즈)
		
		bif.biXPelsPerMeter = 0;
		bif.biYPelsPerMeter = 0;
		bif.biClrUsed = 0;
		bif.biClrImportant = 0;
		
		//출력코드
		/*char name[32] = "";
		sprintf(name, "%04d.bmp", a);
		FILE* wf = fopen(name, "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);
		delete[] Image16;
		delete[] Image24;
		*/
	}
	//전체 합쳐진 image 24bit 출력 파일을 작성한다.
	BITMAPFILEHEADER bfhResult;					// 14byte 정보 저장
	bfhResult.bfType = 19778;					// bmp >> 19778 -> 'BM'
	bfhResult.bfSize = size221 + 54;			// 220 * 56 + 54 = 12374
	bfhResult.bfReserved1 = 0;
	bfhResult.bfReserved2 = 0;
	bfhResult.bfOffBits = 54;					// 고정(정적)(static) 그림정보 시작지점
	BITMAPINFOHEADER bifResult;
	bifResult.biSize = 40;						// 인포헤더 사이즈
	bifResult.biWidth = width221 * 16 / 3;
	bifResult.biHeight = height221 * 14;
	bifResult.biPlanes = 1;						// 그림 개수
	bifResult.biBitCount = 24;					// 24bit color
	bifResult.biCompression = 0;				// 압축 여부
	bifResult.biSizeImage = size221;			// 가변적 (순수한 imageSize)
	bifResult.biXPelsPerMeter = 0;
	bifResult.biYPelsPerMeter = 0;
	bifResult.biClrUsed = 0;
	bifResult.biClrImportant = 0;
	FILE* wfResult = fopen("result.bmp", "wb");
	if (wfResult == NULL)
	{
		printf("Open Error");
		return 0;
	}
	fseek(wfResult, 0, SEEK_SET);
	fwrite(&bfhResult, sizeof(BITMAPFILEHEADER), 1, wfResult);
	fwrite(&bifResult, sizeof(BITMAPINFOHEADER), 1, wfResult);
	fwrite(Image221, 1, size221, wfResult);
	fclose(wfResult);
	delete[] Image221;
	printf("성공");
	fclose(rf);
}

728x90
반응형

+ Recent posts