白黒BMPファイルの読み書きとデータ白黒画像表示
11788 ワード
画像処理にとって、bmp画像から含まれる情報をどのように読み取るかは、非常に重要である.matlabの場合、文は1文で十分です.
c++がファイルをメモリに読み込む方法、またはデータをbmp白黒画像に保存する方法については、画像がどのように格納されているかを検討する必要があります.一般に,白黒画像はファイルヘッダ,情報ヘッダ,パレット,最後にビットマップマトリクス情報からなる.ファイルヘッダは、画像の識別子、サイズ、オフセット量などからなり、以下のように定義されます.
ヘッダーは、ファイルの縦横などの情報で構成され、次のように定義されます.
その後はパレット、白黒画像パレットは次のようになります.
最後に,情報のビット数は一般的に8 bit,最大値は255である2次元画像情報に注目する.
BMPの白黒画像を読み取るには、プログラムは次のように書くことができます.
BMPの白黒ファイルにデータを書き込む場合、プログラムは次のように書くことができます.
マトリクス情報を白黒で画面に表示します.プログラムは次のとおりです.
im=imread('a.bmp');
c++がファイルをメモリに読み込む方法、またはデータをbmp白黒画像に保存する方法については、画像がどのように格納されているかを検討する必要があります.一般に,白黒画像はファイルヘッダ,情報ヘッダ,パレット,最後にビットマップマトリクス情報からなる.ファイルヘッダは、画像の識別子、サイズ、オフセット量などからなり、以下のように定義されます.
typedef struct tagBITMAPFILEHEADER {
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
} BITMAPFILEHEADER, FAR *LPBITMAPFILEHEADER, *PBITMAPFILEHEADER;
ヘッダーは、ファイルの縦横などの情報で構成され、次のように定義されます.
typedef struct tagBITMAPINFOHEADER{
DWORD biSize;
LONG biWidth;
LONG biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
LONG biXPelsPerMeter;
LONG biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
} BITMAPINFOHEADER, FAR *LPBITMAPINFOHEADER, *PBITMAPINFOHEADER;
その後はパレット、白黒画像パレットは次のようになります.
typedef struct tagRGBQUAD {
BYTE rgbBlue;
BYTE rgbGreen;
BYTE rgbRed;
BYTE rgbReserved;
} RGBQUAD;
最後に,情報のビット数は一般的に8 bit,最大値は255である2次元画像情報に注目する.
BMPの白黒画像を読み取るには、プログラムは次のように書くことができます.
bool LoadFromFile(const char* str, unsigned char* & data, int & width, int & height)
{
//
ifstream fin(str,ios::in|ios::_Nocreate|ios::binary);
if(!fin)
return false;
fin.seekg(0, ios::end);
DWORD size = fin.tellg();
// 1024+1024+40
if(size < 14+1024+40)
{
return false;
}
pAllData = new BYTE[size];
memset(pAllData, 0, size);
fin.seekg(0, ios::beg);
fin.read((char*)pAllData, size);
// 0x4d42,
LPBITMAPFILEHEADER pBitMapFileHeader = (LPBITMAPFILEHEADER)pAllData;
if(pBitMapFileHeader->bfType != 0x4d42)
{
pBitMapFileHeader = NULL;
delete [] pAllData;
return false;
}
//
LPBITMAPINFO pBitMapInfo = (LPBITMAPINFO) (pAllData + 14);
width = pBitMapInfo->bmiHeader.biWidth;
height = pBitMapInfo->bmiHeader.biHeight;
//
data = new unsigned char[width*height];
memcpy(data, pAllData + 14 + 40 + 1024, width*height);
// ,
delete [] pAllData;
return true;
}
BMPの白黒ファイルにデータを書き込む場合、プログラムは次のように書くことができます.
bool FiberWriteBitmap(UINT8* pImage, int biHeight , int biWidth, CString csPath)
{
BITMAPFILEHEADER BitmapFileHead;
BITMAPINFOHEADER BitmapInfoHead;
BitmapInfoHead.biSize = 40;
BitmapInfoHead.biBitCount = 8;
BitmapInfoHead.biClrUsed = 256;
BitmapInfoHead.biCompression = 0;
BitmapInfoHead.biHeight = biHeight ;
BitmapInfoHead.biPlanes = 1;
BitmapInfoHead.biClrImportant = 0;
BitmapInfoHead.biWidth = biWidth;
BitmapInfoHead.biXPelsPerMeter = 2835;// 72 dpi
BitmapInfoHead.biYPelsPerMeter = 2835;
BitmapInfoHead.biSizeImage = (DWORD)biHeight*biWidth;
static RGBQUAD palette[256];
for ( unsigned int i = 0; i< 256; i++ )
{
palette[i].rgbBlue = i;
palette[i].rgbGreen = i;
palette[i].rgbRed = i;
}
// Build fileheader and write
BitmapFileHead.bfType=('M' << 8) + 'B';
BitmapFileHead.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+
256*sizeof(RGBQUAD);
BitmapFileHead.bfSize = BitmapFileHead.bfOffBits + BitmapInfoHead.biSizeImage;
BitmapInfoHead.biClrUsed=256;
BitmapInfoHead.biClrImportant=0;
BitmapFileHead.bfReserved1=0;
BitmapFileHead.bfReserved2=0;
CFile file;
if(!file.Open(csPath, CFile::modeCreate|CFile::modeWrite))
return false;
file.Write(&BitmapFileHead,sizeof(BITMAPFILEHEADER));
file.Write(&BitmapInfoHead,sizeof(BITMAPINFOHEADER));
file.Write(palette,sizeof(RGBQUAD)*256);
file.Write(pImage,biHeight*biWidth);
file.Close();
return TRUE;
}
マトリクス情報を白黒で画面に表示します.プログラムは次のとおりです.
bool ShowDataToWindow(CDC *pDC,DWORD width, DWORD height, LPBYTE lpData, int xDest, int yDest, int DestWidth, int DestHeight, int xSrc, int ySrc, int SrcWidth, int SrcHeight)
{
if(lpData == NULL)
return false;
LPBITMAPINFO lpBitMapInfo = (LPBITMAPINFO)new BYTE[40+1024];
lpBitMapInfo->bmiHeader.biSize = 40;
lpBitMapInfo->bmiHeader.biBitCount = 8;
lpBitMapInfo->bmiHeader.biClrUsed = 256;
lpBitMapInfo->bmiHeader.biCompression = 0;
lpBitMapInfo->bmiHeader.biHeight = height;
lpBitMapInfo->bmiHeader.biPlanes = 1;
lpBitMapInfo->bmiHeader.biClrImportant = 0;
lpBitMapInfo->bmiHeader.biWidth = width;
lpBitMapInfo->bmiHeader.biXPelsPerMeter = 2835;
lpBitMapInfo->bmiHeader.biYPelsPerMeter = 2835;
lpBitMapInfo->bmiHeader.biSizeImage = (DWORD)height*width;
LPBYTE lpQuad = (LPBYTE)lpBitMapInfo;
for(int i = 0;i<256;++i)
{
*(lpQuad+40+i*4+0) = (BYTE)i;
*(lpQuad+40+i*4+1) = (BYTE)i;
*(lpQuad+40+i*4+2) = (BYTE)i;
*(lpQuad+40+i*4+3) = 0xcc;
}
pDC->SetStretchBltMode(COLORONCOLOR);
StretchDIBits(pDC->GetSafeHdc(), xDest, yDest, DestWidth, DestHeight,
xSrc, ySrc, SrcWidth, SrcHeight, lpData, lpBitMapInfo, DIB_RGB_COLORS, SRCCOPY);
delete[] lpBitMapInfo;
return true;
}