#include"stdio.h"
#include"iostream.h"
#include"string.h"
#include <conio.h>
#include"stdlib.h"
#include"windows.h"
unsigned char *pBmpBuf;//讀入映像資料的指標
int bmpWidth;//映像的寬
int bmpHeight;//映像的高
RGBQUAD *pColorTable;//顏色表指標
int biBitCount;//映像類型,每一像素位元數
/*****************************************************/
/*函數名稱readBmp()*/
bool readBmp(char *bmpName)
{
//二進位讀方式開啟指定的影像檔
FILE *fp=fopen(bmpName,"rb");
if(fp==0) return 0;
//跳過位元影像檔案頭結構BITMAPFILEHEADER
fseek(fp,sizeof(BITMAPFILEHEADER),0);
//定義位元影像資訊頭結構變數,讀取位元影像資訊頭進記憶體,存放在變數head中
BITMAPINFOHEADER head;
fread(&head, sizeof(BITMAPINFOHEADER), 1,fp);
//擷取映像寬、高、每像素所佔位元等資訊
bmpWidth=head.biWidth;
bmpHeight=head.biHeight;
biBitCount=head.biBitCount;
//定義變數,計算映像每行像素所佔的位元組數(必須是4的倍數)
//int lineByte=(bmpWidth * biBitCount/8+3)/4*4;
int lineByte=(bmpWidth*biBitCount+31)/32*4;
//灰階映像有顏色表,且顏色表表項為256
if(biBitCount==8)
{
//申請顏色表所需要的空間,讀顏色表進記憶體
pColorTable=new RGBQUAD[256];
fread(pColorTable,sizeof(RGBQUAD),256,fp);
}
//申請位元影像資料所需要的空間,讀位元影像資料進記憶體
pBmpBuf=new unsigned char[lineByte * bmpHeight];
fread(pBmpBuf,1,lineByte * bmpHeight,fp);
int BytesPerLine;
BYTE data[999999];
BYTE Color[1300][3];
BytesPerLine=(bmpWidth*biBitCount+31)/32*4;
fseek(fp,54,0);
for(int i=bmpHeight-1;i>=0;i--)
{
fread(data,1,BytesPerLine,fp);
for(int k=0;k <bmpWidth*3;k++)
{
if(k%3==2)
{
Color[k/3][2]=data[k-2];//b
Color[k/3][1]=data[k-1];//g
Color[k/3][0]=data[k-0];//r
}
}
int m=1,n;
cout<<"第"<<i<<"行的顏色red分量矩陣為:"<<endl;
for(k=0;k<bmpWidth;k++)
{
n=int(Color[k][0]);
if(n/100==0&&n/10==0)
cout<<" "<<n<<" ";
else if(n/100==0)
cout<<" "<<n<<" ";
else
cout<<n<<" ";
if(k==10*m-1)
{
cout<<endl;
m++;
}
}
cout<<endl<<endl<<endl;
m=1;
cout<<"第"<<i<<"行的顏色green分量矩陣為:"<<endl;
for(k=0;k<bmpWidth;k++)
{
n=int(Color[k][1]);
if(n/100==0&&n/10==0)
cout<<" "<<n<<" ";
else if(n/100==0)
cout<<" "<<n<<" ";
else
cout<<n<<" ";
if(k==10*m-1)
{
cout<<endl;
m++;
}
}
cout<<endl<<endl<<endl;
m=1;
cout<<"第"<<i<<"行的顏色blue分量矩陣為:"<<endl;
for(k=0;k<bmpWidth;k++)
{
n=int(Color[k][2]);
if(n/100==0&&n/10==0)
cout<<" "<<n<<" ";
else if(n/100==0)
cout<<" "<<n<<" ";
else
cout<<n<<" ";
if(k==10*m-1)
{
cout<<endl;
m++;
}
}
cout<<endl<<endl<<endl;
}
//關閉檔案
fclose(fp);
return 1;
}
/*函數名稱:saveBmp()函數參數:char *bmpName檔案名稱字及路徑;
unsigned char *imgBuf待存檔的位元影像資料;
int width以像素為單位待存檔位元影像的寬;
int height以像素為單位待存檔位元影像高;
int biBitCount每像素所佔位元;
RGBQUAD *pColorTable顏色表指標
傳回值:0為失敗,1為成功.
說明:給定一個映像位元影像資料、寬、高、顏色表指標及每像素所佔的位元等資訊,
將其寫到指定檔案中*/
bool saveBmp(char *bmpName,unsigned char *imgBuf,int width,int height,
int biBitCount, RGBQUAD *pColorTable)
{
//如果位元影像資料指標為0,則沒有資料傳入,函數返回
if(!imgBuf) return 0;
//顏色表大小,以位元組為單位,灰階映像顏色表為1024位元組,彩色映像顏色表大小為0
int colorTablesize=0;
if(biBitCount==8)
colorTablesize=1024;
//待儲存映像資料每行位元組數為4的倍數
//int lineByte=(width * biBitCount/8+3)/4*4;
int lineByte=(bmpWidth*biBitCount+31)/32*4;
//以二進位寫的方式開啟檔案
FILE *fp=fopen(bmpName,"wb");
if(fp==0) return 0;
//申請位元影像檔案頭結構變數,填寫檔案頭資訊
BITMAPFILEHEADER fileHead;
fileHead.bfType = 0x4D42;
//bmp類型
//bfSize是影像檔4個組成部分之和
fileHead.bfSize=sizeof(BITMAPFILEHEADER)+
sizeof(BITMAPINFOHEADER)+colorTablesize+
lineByte*height;
fileHead.bfReserved1=0;
fileHead.bfReserved2=0;
//bfOffBits是影像檔前3個部分所需空間之和
fileHead.bfOffBits=54+colorTablesize;
//寫檔案頭進檔案
fwrite(&fileHead,sizeof(BITMAPFILEHEADER),1,fp);
//申請位元影像資訊頭結構變數,填寫資訊頭資訊
BITMAPINFOHEADER head;
head.biBitCount=biBitCount;
head.biClrImportant=0;
head.biClrUsed=0;head.biCompression=0;
head.biHeight=height;
head.biPlanes=1;
head.biSize=40;
head.biSizeImage=lineByte*height;
head.biWidth=width;
head.biXPelsPerMeter=0;
head.biYPelsPerMeter=0;
//寫位元影像資訊頭進記憶體
fwrite(&head,sizeof(BITMAPINFOHEADER),1,fp);
//如果灰階映像,有顏色表,寫入檔案
if(biBitCount==8)
fwrite(pColorTable,sizeof(RGBQUAD),256,fp);
//寫位元影像資料進檔案
fwrite(imgBuf,height*lineByte,1,fp);
//關閉檔案fclose(fp);
return 1;
}
void main()
{
//讀入指定BMP檔案進記憶體
char readPath[]="D:\\4.bmp";
readBmp(readPath);
//輸出映像的資訊
printf("width=%d,height=%d,biBitCount=%d\n",bmpWidth,bmpHeight,biBitCount);
cout<<endl<<endl<<endl;
//將映像資料存檔
char writePath[]="D:\\2.bmp";
saveBmp(writePath,pBmpBuf,bmpWidth,bmpHeight,biBitCount,pColorTable);
//清除緩衝區,pBmpBuf和pColorTable是全域變數,在檔案讀入時申請的空間
delete []pBmpBuf;
if(biBitCount==8)
delete []pColorTable;
}