공부

비트맵 이미지블렌딩 프로그램 만들기 (c++ 연습)

글로벌디노 2020. 7. 18. 17:53

가로 세로 크기가 같은 두 개의 32bit컬러 비트맵파일을 블렌딩해서

새로운 bmp 파일로 저장하는 프로그램 만들기

 

 

img1
img2
blendImg

 

 

c++ 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#include <iostream>
#include <Windows.h>
#include <wingdi.h>
 
void Blending(const char* pfName1, const char* pfName2, const char* pfDestName);
 
int main()
{
    // 이미지 컬러블렌딩
    Blending("img1.bmp""img2.bmp""blendImg.bmp");
 
    return 0;
}
 
void Blending(const char* pfName1, const char* pfName2, const char* pfDestName)
{
    // 파일1 오픈
    FILE *pFile1, *pFile2, *pFile3;
    if (fopen_s(&pFile1, pfName1, "rb"!= 0)
    {
        printf("%s file open fail\n", pfName1);
        return;
    }
 
    // 파일2 오픈
    if (fopen_s(&pFile2, pfName2, "rb"!= 0)
    {
        printf("%s file open fail\n", pfName2);
        return;
    }
 
    // 이미지파일헤더 읽기
    BITMAPFILEHEADER bmpHeader1, bmpHeader2;
    fread_s(&bmpHeader1, sizeof(bmpHeader1), sizeof(bmpHeader1), 1, pFile1);
    fread_s(&bmpHeader2, sizeof(bmpHeader2), sizeof(bmpHeader2), 1, pFile2);
 
    // 이미지정보헤더 읽기
    BITMAPINFOHEADER bmpInfoHeader1, bmpInfoHeader2;
    fread_s(&bmpInfoHeader1, sizeof(bmpInfoHeader1), sizeof(bmpInfoHeader1), 1, pFile1);
    fread_s(&bmpInfoHeader2, sizeof(bmpInfoHeader2), sizeof(bmpInfoHeader2), 1, pFile2);
 
    // gimp 에서 비트맵 저장시 xrgb 32 로 저장했더니 헤더에 16바이트가 추가됨
    typedef struct stEmpty
    {
        int aaa;
        int bbb;
        int ccc;
        int ddd;
    }EMPTYDATA;
    EMPTYDATA emptyData;
    fread_s(&emptyData, sizeof(emptyData), sizeof(emptyData), 1, pFile1);
    fread_s(&emptyData, sizeof(emptyData), sizeof(emptyData), 1, pFile2);
 
    // 이미지 데이터 읽기
    int imgSize = bmpInfoHeader1.biWidth * bmpInfoHeader1.biHeight * 4;
    char *pImgData1 = (char*)malloc(imgSize);
    char* pImgData2 = (char*)malloc(imgSize);
 
    fread_s(pImgData1, imgSize, imgSize, 1, pFile1);
    fread_s(pImgData2, imgSize, imgSize, 1, pFile2);
 
    // 블렌딩된 이미지를 저장할 파일 생성 또는 덮어쓰기
    fopen_s(&pFile3, pfDestName, "wb");
 
    // 헤더정보먼저 파일에 저장
    fwrite(&bmpHeader1, sizeof(bmpHeader1), 1, pFile3);
    fwrite(&bmpInfoHeader1, sizeof(bmpInfoHeader1), 1, pFile3);
    fwrite(&emptyData, sizeof(emptyData), 1, pFile3);
 
    // 이미지 데이터 블렌딩 계산해서 새로 저장시킬 메모리에 복사
    char* pImgData3 = (char*)malloc(imgSize);
    RGBQUAD rgb1, rgb2, rgb3;
    for (int i = 0; i < imgSize; i += sizeof(RGBQUAD))
    {
        memcpy_s(&rgb1, sizeof(RGBQUAD), &pImgData1[i], sizeof(RGBQUAD));
        memcpy_s(&rgb2, sizeof(RGBQUAD), &pImgData2[i], sizeof(RGBQUAD));
 
        rgb3.rgbRed = (rgb1.rgbRed / 2+ (rgb2.rgbRed / 2);
        rgb3.rgbGreen = (rgb1.rgbGreen / 2+ (rgb2.rgbGreen / 2);
        rgb3.rgbBlue = (rgb1.rgbBlue / 2+ (rgb2.rgbBlue / 2);
        rgb3.rgbReserved = 0;
 
        memcpy_s(pImgData3 + i, imgSize - i, &rgb3, sizeof(RGBQUAD));
    }
 
    // 블렌딩 이미지데이터 파일로 저장
    fwrite(pImgData3, imgSize, 1, pFile3);
 
    _fcloseall();
    free(pImgData1);
    free(pImgData2);
    free(pImgData3);
}

 

 

이슈

jpg 파일을 bmp 파일로 변환하기 위해 김프 툴 사용

bmp 파일 내보내기 옵션에서

색상공간 정보를 작성하지 마십시오. 란을 체크하지 않으면 색상테이블(팔레트) 정보까지 저장됨

32비트 ARGB 체크가 비활성되어 있어서 XRGB를 체크해서 저장했더니 이미지정보구조체 뒤에 의문의 16바이트 정보가 저장됨

4바이트씩 끊어서 데이터 확인해봤지만 무슨 의미인지는 모르겠다

 

 

참고 : 비트맵 파일 구조

위키백과

코딩도장