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
반응형
'Education > Edu | .net' 카테고리의 다른 글
# 5.4) [Win32API] modal 및 modeless 개념 (0) | 2021.01.11 |
---|---|
# 5.2) [Win32API] Win32API 기본 설명 (0) | 2021.01.11 |
# 4) [C/C++] 문제풀이_1 (0) | 2021.01.08 |
# 3.2) [C/C++] JSF 확장자 파일 입출력 (bmp 이미지 출력) (0) | 2021.01.07 |
# 3.1) [C/C++] JSF파일에서 바이너리로 이미지 파일 입출력 (0) | 2021.01.06 |