上一篇博客里写到了24位真彩图转八位灰度图的方法,这一篇博客是在上个代码的基础上,添加了分解灰度图8个位平面的功能。#include <iostream> #include <stdio h=""> #include <stdlib h=""> #include <windows h=""> #include <string> using namespace std; /* typedef struct tagBITMAPFILEHEADER { WORD bfType; // 位图文件的类型,必须为BM(1-2字节) DWORD bfSize; // 位图文件的大小,以字节为单位(3-6字节) WORD bfReserved1; // 位图文件保留字,必须为0(7-8字节) WORD bfReserved2; // 位图文件保留字,必须为0(9-10字节) DWORD bfOffBits; // 位图数据的起始位置,以相对于位图(11-14字节) // 文件头的偏移量表示,以字节为单位 } BITMAPFILEHEADER; typedef struct tagBITMAPINFOHEADER{ DWORD biSize; // 本结构所占用字节数(15-18字节) LONG biWidth; // 位图的宽度,以像素为单位(19-22字节) LONG biHeight; // 位图的高度,以像素为单位(23-26字节) WORD biPlanes; // 目标设备的级别,必须为1(27-28字节) WORD biBitCount;// 每个像素所需的位数,必须是1(双色),(29-30字节) // 4(16色),8(256色)16(高彩色)或24(真彩色)之一 DWORD biCompression; // 位图压缩类型,必须是 0(不压缩),(31-34字节) // 1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一 DWORD biSizeImage; // 位图的大小(其中包含了为了补齐行数是4的倍数而添加的空字节),以字节为单位(35-38字节) LONG biXPelsPerMeter; // 位图水平分辨率,每米像素数(39-42字节) LONG biYPelsPerMeter; // 位图垂直分辨率,每米像素数(43-46字节) DWORD biClrUsed;// 位图实际使用的颜色表中的颜色数(47-50字节) DWORD biClrImportant;// 位图显示过程中重要的颜色数(51-54字节) } BITMAPINFOHEADER; typedef struct tagRGBQUAD { BYTE rgbBlue;// 蓝色的亮度(值范围为0-255) BYTE rgbGreen; // 绿色的亮度(值范围为0-255) BYTE rgbRed; // 红色的亮度(值范围为0-255) BYTE rgbReserved;// 保留,必须为0 } RGBQUAD; */ int Convert8bitGray( ) { BITMAPFILEHEADER fileHeader; BITMAPINFOHEADER infoHeader; RGBQUAD *pColorTable; BYTE *img; BYTE *newimg; FILE* pfin =fopen("original.bmp","r+b"); //Read the Bitmap file header; fread(&fileHeader,sizeof(BITMAPFILEHEADER),1,pfin); //Read the Bitmap info header; fread(&infoHeader,sizeof(BITMAPINFOHEADER),1,pfin); //为简化代码,只处理24位彩色 if( infoHeader.biBitCount == 24 ) { int i=0,j=0; if(infoHeader.biWidth%4!=0) infoHeader.biWidth=(infoHeader.biWidth+3)/4*4; if(infoHeader.biHeight%4!=0) infoHeader.biHeight=(infoHeader.biHeight +3)/4*4; infoHeader.biSizeImage=infoHeader.biWidth*infoHeader.biHeight*3; img =new BYTE[infoHeader.biSizeImage]; memset(img,0,infoHeader.biSizeImage); fread(img,sizeof(BYTE),infoHeader.biSizeImage,pfin); fclose(pfin); FILE* pfout = fopen( "GrayPic.bmp" , "w+b"); fileHeader.bfOffBits+=(sizeof(RGBQUAD)*256); infoHeader.biBitCount=8; int lineBytes=((infoHeader.biWidth*8+31)/32*4); int oldSize=infoHeader.biSizeImage; infoHeader.biSizeImage=lineBytes*infoHeader.biHeight; pColorTable=new RGBQUAD[256]; newimg=new BYTE[infoHeader.biSizeImage]; memset(newimg,0,infoHeader.biSizeImage); for(i=0;i<256;i++) { pColorTable[i].rgbBlue=i; pColorTable[i].rgbGreen=i; pColorTable[i].rgbRed=i; pColorTable[i].rgbReserved=0; } BYTE red,green,blue; BYTE gray; for(i=0;i<oldsize i="" 3="" red="img[i];" green="img[i+1];" blue="img[i+2];" gray="(77*red+151*green+28*blue)">>8; newimg[j++]=gray; } //将修改后的图片保存到文件 fwrite( &fileHeader , sizeof(fileHeader) , 1 , pfout ); fwrite( &infoHeader , sizeof(infoHeader) , 1 , pfout ); fwrite(pColorTable,sizeof(RGBQUAD),256,pfout); fwrite( newimg ,sizeof(BYTE) , infoHeader.biSizeImage , pfout ); fclose(pfout); delete []pColorTable; delete []img; delete []newimg; } return 0; } //分解灰度图位平面 int deGray() { BITMAPFILEHEADER fileHeader; BITMAPINFOHEADER infoHeader; RGBQUAD *pColorTable; RGBQUAD *pCT; RGBQUAD *temp; BYTE *img; FILE* pfin =fopen("GrayPic.bmp","r+b"); pColorTable=new RGBQUAD[256]; pCT=new RGBQUAD[256]; temp=new RGBQUAD[256]; //Read the Bitmap file header; fread(&fileHeader,sizeof(BITMAPFILEHEADER),1,pfin); //Read the Bitmap info header; fread(&infoHeader,sizeof(BITMAPINFOHEADER),1,pfin); //Read the Bitmap RGBQUAD fread(pColorTable,sizeof(RGBQUAD),256,pfin); //对齐,宽和高是4的倍数 if(infoHeader.biWidth%4!=0) infoHeader.biWidth=(infoHeader.biWidth+3)/4*4; if(infoHeader.biHeight%4!=0) infoHeader.biHeight=(infoHeader.biHeight +3)/4*4; infoHeader.biSizeImage=infoHeader.biWidth*infoHeader.biHeight*3; img =new BYTE[infoHeader.biSizeImage]; memset(img,0,infoHeader.biSizeImage); fread(img,sizeof(BYTE),infoHeader.biSizeImage,pfin); fclose(pfin); char filename[20]; int i=0,j=0; for(i=0;i<8;i++) { sprintf(filename,"bitPlane%d",i+1); FILE* pfout = fopen(strcat(filename,".bmp"), "w+b"); for(j=0;j<256;j++) { temp[j].rgbBlue=pColorTable[j].rgbBlue; temp[j].rgbGreen=pColorTable[j].rgbGreen; temp[j].rgbRed=pColorTable[j].rgbRed; temp[j].rgbReserved=pColorTable[j].rgbReserved; temp[j].rgbBlue=temp[j].rgbBlue&(1<<i); temp[j].rgbGreen=temp[j].rgbGreen&(1<<i); temp[j].rgbRed=temp[j].rgbRed&(1<<i); temp[j].rgbReserved=temp[j].rgbReserved&(1<<i); } fwrite( &fileHeader , sizeof(fileHeader) , 1 , pfout ); fwrite( &infoHeader , sizeof(infoHeader) , 1 , pfout ); fwrite(temp,sizeof(RGBQUAD),256,pfout); fwrite(img,sizeof(BYTE) , infoHeader.biSizeImage , pfout ); fclose(pfout); } delete[] temp; return 0; } int main() { Convert8bitGray(); deGray(); return 0; } </oldsize></string></windows></stdlib></stdio></iostream> 运行结果如下: