請問一下一個BMP格式的二值影像的像素是用一個位元組表示的還是用一個位表示的呀?如果用一個位表示一個像素,那怎么訪問像素呢?
uj5u.com熱心網友回復:
參考/*引數說明:
*strSrc——源檔案(8位bmp灰度圖)
*strDst——目標檔案(1位bmp二值圖) // 一位元組 8個 點
*threshold——閾值
*/
BOOL GraytoBinary(const char *strSrc, const char *strDst, const int threshold)
{
BITMAPFILEHEADER fileheader; //檔案頭
BITMAPINFOHEADER bmpinfo; //資訊頭
FILE *fSrc; //源檔案(灰度圖)
fSrc=https://bbs.csdn.net/topics/fopen(strSrc,"rb");
if( !fSrc )
{
return false;
}
fread(&fileheader, sizeof(BITMAPFILEHEADER), 1, fSrc); //讀取源檔案的檔案頭
fread(&bmpinfo, sizeof(BITMAPINFOHEADER), 1, fSrc); //讀取源檔案的資訊頭
// const int SecBPP = 8 / bmpinfo.biBitCount; //源檔案每位元組的像素數
const int SrcBitCount = bmpinfo.biBitCount; //源檔案的位深
const int SrcRowLen = (((bmpinfo.biWidth * bmpinfo.biBitCount + 31)/8)/4)*4; // 520 源檔案每行位元組數
const int SrcClrNum = bmpinfo.biClrUsed ? bmpinfo.biClrUsed : 256 ; //原影像顏色表個數(8位256色)
// read src colors !
// RGBQUAD SrcClr[256];
// fread(SrcClr,sizeof(RGBQUAD),SrcClrNum,fSrc);
// or seek to data
fseek(fSrc,sizeof(RGBQUAD)*SrcClrNum,SEEK_CUR);
//修改檔案資訊為:目標檔案資訊
bmpinfo.biBitCount = 1; //二值圖的位深
bmpinfo.biClrImportant = 0; //所有顏色都很重要
bmpinfo.biClrUsed = 2; //有2個顏色表
bmpinfo.biCompression = 0; //不壓縮
const int DstBPP = 8; //二值圖每位元組的像素數
const int DstRowLen = (((bmpinfo.biWidth * bmpinfo.biBitCount + 31)/8)/4)*4;// 68 二值圖每行位元組數
fileheader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) +
2*sizeof(RGBQUAD) + bmpinfo.biHeight*DstRowLen; //二值圖的檔案大小
fileheader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) +
2*sizeof(RGBQUAD); //二值圖的位圖資料偏移量
bmpinfo.biSizeImage = bmpinfo.biHeight * DstRowLen; //二值圖的影像資料大小
//創建目標檔案
FILE *fDst;
fDst=fopen(strDst,"wb");
if( !fDst )
{
return false;
}
fwrite(&fileheader, sizeof(BITMAPFILEHEADER), 1, fDst); // 寫入二值圖檔案頭
fwrite(&bmpinfo, sizeof(BITMAPINFOHEADER), 1, fDst); // 寫入二值圖資訊頭
RGBQUAD clrDst[2]; //臨時變數:原影像(8位)顏色表 與 目標影像(1位)顏色表
//clrDst[2]陣列存盤具體的顏色資訊,二值圖資料部分存盤的是陣列下標
clrDst[0].rgbBlue = 0;
clrDst[0].rgbGreen = 0;
clrDst[0].rgbRed = 0;
clrDst[0].rgbReserved = 0; // 0 表示 黑色
clrDst[1].rgbBlue = 255;
clrDst[1].rgbGreen = 255;
clrDst[1].rgbRed = 255;
clrDst[1].rgbReserved = 0; // 1 表示 白色
for(int ii = 0; ii < 2; ii++)
{
fwrite(&clrDst[ii],sizeof(RGBQUAD),1,fDst); //將顏色表寫入目標檔案
}
BYTE *bufSrc = new BYTE[SrcRowLen]; //源檔案(灰度圖)存放一行像素的緩沖區
BYTE *bufDst = new BYTE[DstRowLen]; //目標檔案(二值圖)存放一行像素的緩沖區
for(int i = 0; i < bmpinfo.biHeight; i++)
{
fread(bufSrc,SrcRowLen,1,fSrc); //讀取源檔案(8位位圖)第i行資料
memset(bufDst,0,DstRowLen); //將目標檔案(二值圖)第i行資料清零
for(int j = 0; j < bmpinfo.biWidth; j++)
{
int index = j / DstBPP; //從源檔案每讀8位元組,目標檔案增加一位元組
int nShift = 8 - (j % DstBPP + 1 ) * bmpinfo.biBitCount; //moved bit
// nShift = 7 6 5 4 3 2 1
if(bufSrc[j] < threshold)
bufDst[index] &= ~(1 << nShift);// =0
else
bufDst[index] |= (1 << nShift);// =1
}
fwrite(bufDst, DstRowLen, 1, fDst); // write this row
}
//
fclose(fSrc);
fclose(fDst);
//
delete []bufSrc;
delete []bufDst;
return true;
}
// GraytoBinary("Girl8.bmp", "Girl2.bmp",28);//
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/55917.html
標籤:圖形處理/算法
上一篇:Run-Time Check Failure #2 - Stack around the variable 'InitCtrls' was corrupted.
下一篇:opencv讀取tif影像
