본문 바로가기
카테고리 없음

Visual C++ 영상 처리 프로그래밍 BMP형식 영상파일 입력과 출력 분석

by 머리올리자 2021. 2. 21.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <windows.h>
#define WIDTHBYTES(bits) (((bits) +31)/32*4) // 영상의 가로줄 4바이트 배수
#define BYTE unsigned char

int main(void)

{
	FILE* infile = fopen("imageprocessing/Images/CH03/Coin.bmp", "rb"); // 입력할 파일을 오픈
	if (infile == NULL) { printf("영상 파일이 없습니다"); return 1; }

	// BMP 헤드정보의 입력
	BITMAPFILEHEADER hf; // "파일정보헤드" 변수 선언
	BITMAPINFOHEADER hInfo; // "영상정보헤드" 변수 선언
	fread(&hf, sizeof(BITMAPFILEHEADER), 1, infile); // 파일정보헤드 읽음
	if (hf.bfType != 0x4D42) exit(1); // 파일 타입이 "BM" (0x4D42)인지 검사

	fread(&hInfo, sizeof(BITMAPINFOHEADER), 1, infile); // 영상정보헤드 읽음
	if (hInfo.biBitCount != 8) { printf("Bad File format!!"); return 1; } // 흑백인지 검사

	// 팔레트정보의 입력
	RGBQUAD hRGB[256]; // 팔레트정보를 위한 배열 (흑백파일) -> 256개 이하의 색상을 사용하는 비트맵은 RGBQUAD 구조체의 배열로 구성된 색상 테이블이 존재한다.
	fread(hRGB, sizeof(RGBQUAD), 256, infile); // 팔레트 입력

	// 메모리 할당
	BYTE* lpImg = new BYTE[hInfo.biSizeImage]; // 저장할 영상메모리 할당 (동적할당)
	fread(lpImg, sizeof(char), hInfo.biSizeImage, infile); // 영상데이터 읽음
	//lpImg : 파일에서 읽어온 것을 저장할 block을 가리키는 포인터
	//sizeof(char) : block의 사이즈
	//hInfo.biSizeImage : count 개수

	fclose(infile); // 오픈했던 파일을 닫아줌

	int rwsize = WIDTHBYTES(hInfo.biBitCount * hInfo.biWidth);

	// 역상의 이미지 구하기
	for (int i = 0; i < hInfo.biHeight; i++){
		for (int j = 0; j < hInfo.biWidth; j++)
			lpImg[i * rwsize + j] = 255 - lpImg[i * rwsize + j];
	}

	FILE* outfile = fopen("out.bmp", "wb");
	fwrite(&hf, sizeof(char), sizeof(BITMAPFILEHEADER), outfile); // 파일헤드 출력
	fwrite(&hInfo, sizeof(char), sizeof(BITMAPINFOHEADER), outfile); // 영상헤드 출력

	fwrite(hRGB, sizeof(RGBQUAD), 256, outfile); // 팔레트 출력

	fwrite(lpImg, sizeof(char), hInfo.biSizeImage, outfile); // 영상데이터 출력
	fclose(outfile); // 파일을 닫아줌

	// 메모리 해제
	delete[] lpImg;

	return 0;


}