비트 맵 BitMap 그림 읽 기 및 저장

6232 단어 영상 처리
그림 을 처리 할 때 원본 파일 은 일반적으로 손상 되 지 않 은 그림 파일 형식 을 사용 해 야 하 며, 비트 맵 (BitMap) 은 windows 시스템 에서 압축 되 지 않 은 그림 을 저장 할 수 있 는 파일 형식 입 니 다.비트 맵 파일 의 읽 기와 저장 을 실현 하려 면 먼저 비트 맵 파일 의 저장 데이터 구 조 를 알 아야 한다.비트 맵 파일 은 네 부분 으로 순서대로 구성 되 어 있 습 니 다. BITMAFILEHEADER, BITMAPINFOHEADER, 팔레트, Image Data.
1) BITMAFILEHEADER 구조의 길 이 는 고정된 14 개의 바이트 로 파일 에 대한 정 보 를 설명 한다.그 데이터 구 조 는:
typedef struct tagBITMAPFILEHEADER {
        WORD    bfType;//must be 0x4D42.
        DWORD   bfSize;//the size of the whole bitmap file.
        WORD    bfReserved1;
        WORD    bfReserved2;
        DWORD   bfOffBits;//the sum bits of BITMAPFILEHEADER,BITMAPINFOHEADER and RGBQUAD;the index byte of the image data.
} BITMAPFILEHEADER, FAR *LPBITMAPFILEHEADER, *PBITMAPFILEHEADER;

2) BITMAPINFOHEADER 구조의 길 이 는 고정된 40 개의 바이트 로 이미지 에 대한 정 보 를 설명 한다.그 데이터 구 조 는:
typedef struct tagBITMAPINFOHEADER{
        DWORD      biSize;//the size of this struct.it is 40 bytes.
        LONG       biWidth;//the width of image data. the unit is pixel.
        LONG       biHeight;//the height of image data. the unit is pixel.
        WORD       biPlanes;//must be 1.
        WORD       biBitCount;//the bit count of each pixel.usually be 1,4,8,or 24.
        DWORD      biCompression;//is this image compressed.0 indicates no compression.
        DWORD      biSizeImage;//the size of image data.
        LONG       biXPelsPerMeter;
        LONG       biYPelsPerMeter;
        DWORD      biClrUsed;
        DWORD      biClrImportant;
} BITMAPINFOHEADER, FAR *LPBITMAPINFOHEADER, *PBITMAPINFOHEADER;

    주의해 야 할 것 은 그 중에서 biSizeImage 는 실제 이미지 데이터 의 크기 를 가리 키 며 바이트 단위 이다.그 계산 공식 은 너비 * 높이 이다.그 중 너 비 는 반드시 4 의 정수 배 여야 한다.정수 배가 아니라면 너비 보다 큰 4 의 정수 배 가장 가 까 운 수 치 를 취한 다.이 요 구 는 현재 컴퓨터 가 대부분 32 비트 4 바이트 이 고 컴퓨터 가 4 바이트 씩 읽 기 때문에 줄 마다 픽 셀 을 여러 번 읽 을 수 있 기 때 문 일 수 있 습 니 다.
3) 팔레트: 현재 컴퓨터 는 대부분 32 비트 또는 더 높 기 때문에 이미지 데 이 터 는 진짜 컬러 24 비트 로 표현 할 수 있 습 니 다. 즉, 모든 픽 셀 은 24bit 로 표시 되 고 8bit 마다 RGB 3 색 중의 1 색 을 표시 합 니 다.그러나 예전 의 컴퓨터 처리 능력 이 비교적 떨 어 졌 다. 이미지 용 1 비트, 4 비트 또는 8 비트, 즉 BITMAPInfoheader 의 biBitCount 는 24 가 아니 었 다. 이때 RGB 색 채 를 표현 하려 면 팔레트 가 필요 하 다. 팔레트 는 이미지 데이터 에서 사용 하 는 한 가지 색 을 RGB 색 에 대응 하 더 라 도 이미지 데이터 의 픽 셀 값 은 색인 값 이다.진정한 픽 셀 값 은 이 색인 값 에 대응 하 는 팔레트 의 값 입 니 다.팔레트 는 하나의 배열 입 니 다. 배열 의 모든 요 소 는 rgb 색상 입 니 다. 8 비트 이미지 에 대해 최대 256 가지 색상 을 표현 할 수 있 고 팔레트 의 크기 는 256 입 니 다.팔레트 배열 의 모든 요소 의 데이터 구조:
typedef struct tagRGBQUAD {
        BYTE    rgbBlue;
        BYTE    rgbGreen;
        BYTE    rgbRed;
        BYTE    rgbReserved;
} RGBQUAD;
typedef RGBQUAD FAR* LPRGBQUAD;

4) 이미지 데 이 터 는 1 개의 이미지 에 대해 1 개의 픽 셀 은 1bit 로 저장 하고 24 개의 이미지 에 대해 1 개의 픽 셀 은 24bit 로 저장 합 니 다.비트 맵 파일 의 데 이 터 는 아래 에서 위로, 왼쪽 에서 오른쪽으로 저 장 됩 니 다.그래서 읽 을 때 가장 먼저 읽 은 것 은 그림 왼쪽 아래 의 픽 셀 이 고 마지막 으로 읽 은 것 은 그림 오른쪽 위의 그림 입 니 다.
c + + 로 작 성 된 비트 맵 파일 의 읽 기와 저장 방법:
클래스 구조 (BitMap. h):
#include 
class BitMap
{
public:
    BitMap();
    ~BitMap();
protected:
    BITMAPFILEHEADER fileHeader;
    BITMAPINFOHEADER infoHeader;
public:
    int width_p,height_p,bitCount;
    unsigned char *dataBuf;
    LPRGBQUAD colorTable;
    bool Read(char *fileName);
    bool Write(char *_fileName);   
};

방법 (BitMap. cpp):
#include "BitMap.h"
#include 
#include 
#include 
using namespace std;
#define NULL 0

BitMap::BitMap(){};
BitMap::~BitMap(){};

//read bitmap info from a file
bool BitMap::Read(char* fileName)
{
    FILE *_f=fopen(fileName,"rb");//open file
    if(_f==NULL) return false;

    fread(&fileHeader,sizeof(BITMAPFILEHEADER),1,_f);//read BITMAPFILEHEADER

    fread(&infoHeader,sizeof(BITMAPINFOHEADER),1,_f);//read BITMAPINFOHEADER
    width_p=infoHeader.biWidth;
    height_p=infoHeader.biHeight;
    bitCount=infoHeader.biBitCount;

    if(bitCount==8)//if colorTable exist,read colorTable
    {
        colorTable=new RGBQUAD[256];
        fread(&colorTable,sizeof(RGBQUAD),256,_f);
    }

    dataBuf=new unsigned char[infoHeader.biSizeImage];//read image data
    fread(dataBuf,1,infoHeader.biSizeImage,_f);

    fclose(_f);//close file
    return true;
}

//write bitmap info to a file
bool BitMap::Write(char * _fileName)
{
    FILE* f=fopen(_fileName,"wb");//create or open file to be written
    if(f==NULL) return false;

    int colorTableSize=0;//if bitcount is 24, there is no color table.
    if(bitCount==8)//if bitcount is 8 ,the size of color table is 256*4,4B is the size of RGBQUAD.
        colorTableSize=sizeof(RGBQUAD)*256;

    int headerSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+ colorTableSize;//the size of the header of bmp file.
    int lineSize=(width_p*bitCount/8+3)/4*4;//the size of each line in bmp file.
    int dataSize=lineSize*height_p;//the size of the image data of bmp file.
   
    fileHeader.bfType=0x4D42;//set the attribute of BITMAPFILEHEADER
    fileHeader.bfSize=headerSize+dataSize;
    fileHeader.bfReserved1=0;
    fileHeader.bfReserved2=0;
    fileHeader.bfOffBits=headerSize;

    infoHeader.biSize=40;//set the attribute of BITMAPINFOHEADER
    infoHeader.biWidth=width_p;
    infoHeader.biHeight=height_p;
    infoHeader.biPlanes=1;
    infoHeader.biBitCount=bitCount;
    infoHeader.biCompression=0;
    infoHeader.biSizeImage=dataSize;
    infoHeader.biClrImportant=0;
    infoHeader.biXPelsPerMeter=0;
    infoHeader.biYPelsPerMeter=0;

    fwrite(&fileHeader,sizeof(BITMAPFILEHEADER),1,f);//write the data of BITFILEHEADER to bmp file
    fwrite(&infoHeader,sizeof(BITMAPINFOHEADER),1,f);//write the data of BITINFOHEADER to bmp file
    if(bitCount==8)//if color table exists,write the data of color table to bmp file
    {
        colorTable=new RGBQUAD[256];
        fwrite(&colorTable,sizeof(RGBQUAD),256,f);
    }
    fwrite(dataBuf,1,dataSize,f);//write the image data to bmp file

    fclose(f);//data writting is finished,close the bmp file.
    return true;
}

프로그램 입구:
void main()
{
    BitMap* bm=new BitMap();
    bm->Read("nv.BMP");
    bm->Write("nvnew.bmp");
    delete bm;
}

좋은 웹페이지 즐겨찾기