共计 5879 个字符,预计需要花费 15 分钟才能阅读完成。
首先 简单解释一下bmp文件格式
bmp 格式文件 分为四个部分
header 文件格式,大小
infoheader 图像的高,宽,位数
optional palette 可选调色板:使用索引来表示图像是的 索引与颜色的映射 并非一定包含
image data 图像像素信息的数据
其中24位bmp文件不使用索引 所以不需要optional palette 部分
所以在读取调色板是进行文件格式的判断,如24位,则不需要读取调色板,直接读取像素信息
FILE *fp=NULL; int ret = fopen_s(&fp,"D:\\11.bmp","rb"); if(fp==0) { return ; } BITMAPFILEHEADER fileheader={0}; fread(&fileheader,sizeof(fileheader),1,fp); if(fileheader.bfType!=0x4D42) { fclose(fp); return ; } BITMAPINFOHEADER head; fread(&head,sizeof(BITMAPINFOHEADER),1,fp); long bmpWidth = head.biWidth; long bmpHeight = head.biHeight; WORD biBitCount = head.biBitCount; if(biBitCount != 24) { ::AfxMessageBox(_T("请选择24位位图!")); fclose(fp); return ; } int totalSize = (bmpWidth *biBitCount/8+3)/4*4*bmpHeight; BYTE *pBmpBuf = new BYTE[totalSize]; size_t size = 0; while(true) { int iret = fread(&pBmpBuf[size],1,1,fp); if(iret == 0) break; size = size + iret; } fclose(fp); int i,j; CClientDC dc(this); int pitch=bmpWidth%4; for(i=0;i<bmpHeight;i++) { int realPitch=i*pitch; for(j=0;j<bmpWidth;j++) { dc.SetPixel(j,i,RGB( pBmpBuf[(i*bmpWidth+j)*3+2+realPitch], pBmpBuf[(i*bmpWidth+j)*3+1+realPitch], pBmpBuf[(i*bmpWidth+j)*3+realPitch])); } } delete [] pBmpBuf; pBmpBuf = NULL; return ;
完整读取代码,为了兼容Linux 和windows平台用fopen、fread、fseek、fclose替换掉了open、read、lseek、close系列函数。
#include <unistd.h> #include <fcntl.h> #include <sys/stat.h> #include <sys/types.h> #include <stdlib.h> #include <stdio.h> //#include "window.h" /*bmp file header*/ typedef struct FileHeader { unsigned short bfType; unsigned int bfSize; unsigned short bfReserved1; unsigned short bfReserved2; unsigned int bfOffBits; }__attribute__((packed))FileHeader; /*bmp info header*/ typedef struct InfoHeader { unsigned int biSize; int biWidth; int biHeight; unsigned short biPlanes; unsigned short biBitCount; unsigned int biCompression; unsigned int biSizeImage; int biXPelsPerMeter; int biYPelsPerMeter; unsigned int biClrUsed; unsigned int biClrImportant; }__attribute__((packed))InfoHeader; //we won't use it while BitCount=24 typedef struct tagRGBQUAD { unsigned char rgbBlue; unsigned char rgbGreen; unsigned char rgbRed; unsigned char rgbReserved; }RGBQUAD; typedef struct { unsigned char b; unsigned char g; unsigned char r; }RGB_data; /*for test global variable*/ /*maybe can not use this in the project*/ unsigned char *pBmpBuf,*pBmpBufOne,*pBmpBufTwo,*pBmpBufThree; RGBQUAD *pColorTable; int bmpWidth,bmpWidthback,bmpWidthsky; int bmpHeight,bmpHeightback,bmpHeightsky; int biBitCount,biBitCountback,biBitCountsky; char * readBmp(char *bmpName) { FILE *fp = fopen(bmpName, "rb"); //int fp; /*maybe fd should be more comfortably*/ //fp = open(bmpName, O_RDONLY); if (NULL == fp) { printf("There is no fp!!!\n"); return 0; } fseek(fp, sizeof(FileHeader), SEEK_SET); //lseek(fp, sizeof(FileHeader), SEEK_SET); InfoHeader head; fread(&head, sizeof(InfoHeader), 1, fp); //read(fp, &head, sizeof(InfoHeader)); bmpWidth = head.biWidth; bmpHeight = head.biHeight; biBitCount = head.biBitCount; int lineByte = (bmpWidth * biBitCount / 8 + 3) / 4 * 4; if (biBitCount == 8) { //pColorTable=new RGBQUAD[256]; pColorTable = (RGBQUAD *)malloc(sizeof(RGBQUAD) * 1024); fread(pColorTable, sizeof(RGBQUAD), 256, fp); } pBmpBuf = (unsigned char *)malloc(sizeof(unsigned char) * lineByte * bmpHeight); fread(pBmpBuf, 1, lineByte * bmpHeight, fp); fclose(fp); return pBmpBuf; } int saveBmp(char *bmpName, unsigned char *imgBuf, int width, int height, int biBitCount, RGBQUAD *pColorTable) { if(imgBuf == NULL) { printf("imgBuf is NULL!!\n"); return -1; } int colorTablesize = 0; if (biBitCount == 8) { colorTablesize=1024; } int lineByte = (width * biBitCount / 8 + 3) / 4 * 4; FILE *fp = fopen(bmpName, "wb"); if (fp == NULL) { printf("fopen error...\n"); return -1; } FileHeader fileHead; fileHead.bfType=0x4D42; fileHead.bfSize = sizeof(FileHeader) + sizeof(InfoHeader) + colorTablesize + lineByte * height; fileHead.bfReserved1 = 0; fileHead.bfReserved2 = 0; fileHead.bfOffBits = 54 + colorTablesize; fwrite(&fileHead, sizeof(FileHeader), 1, fp); InfoHeader infoHead; infoHead.biBitCount = biBitCount; infoHead.biClrImportant = 0; infoHead.biClrUsed = 0; infoHead.biCompression = 0; infoHead.biHeight = height; infoHead.biPlanes = 1; infoHead.biSize = 40; infoHead.biSizeImage = lineByte * height; infoHead.biWidth = width; infoHead.biXPelsPerMeter = 0; infoHead.biYPelsPerMeter = 0; fwrite(&infoHead, sizeof(InfoHeader), 1, fp); if (biBitCount == 8) { fwrite(pColorTable,sizeof(RGBQUAD),256,fp); } fwrite(imgBuf, height * lineByte, 1, fp); fclose(fp); return 0; } /* main function test program*/ #if 1 int main(int argc, char *argv[]) { char readPath[] = "logo256.bmp"; readBmp(readPath); printf("width = %d, height = %d, biBitCount = %d \n", bmpWidth, bmpHeight, biBitCount); char writePath[] = "logo256copy.bmp"; saveBmp(writePath, pBmpBuf, bmpWidth, bmpHeight, biBitCount, pColorTable); free(pBmpBuf); if (biBitCount == 8) { free(pColorTable); } return 0; } #endif #if 0 extern int a1,b1,n; extern int a[50],b[50]; //int reviseBitMap(void) int main(int argc,char *argv[]) { int i,j; int x,y; int k; char readPathOne[] = "back.bmp"; pBmpBufOne = readBmp(readPathOne); printf("width = %d, height = %d, biBitCount = %d \n", bmpWidth, bmpHeight, biBitCount); bmpWidthback = bmpWidth; bmpHeightback = bmpHeight; biBitCountback = biBitCount; int lineByteback = (bmpWidthback * biBitCountback / 8 + 3) / 4 * 4; char readPathThree[] = "sky.bmp"; pBmpBufThree = readBmp(readPathThree); printf("width = %d, height = %d, biBitCount = %d \n", bmpWidth, bmpHeight, biBitCount); bmpWidthsky = bmpWidth; bmpHeightsky = bmpHeight; biBitCountsky = biBitCount; int lineBytesky = (bmpWidthsky * biBitCountsky / 8 + 3) / 4 * 4; char readPathTwo[] = "plane.bmp"; pBmpBufTwo = readBmp(readPathTwo); printf("wdith = %d, height = %d, biBitCount = %d \n", bmpWidth, bmpHeight, biBitCount); int lineByteplane = (bmpWidth * biBitCount / 8 + 3) / 4 * 4; if (biBitCount == 8) { for (i = 0; i < bmpHeight / 2; i++) { for (j = 0; j < bmpWidth / 2; j++) { *(pBmpBuf + i * lineByteplane + j) = 0; } } } else if (biBitCount == 24) { x = a[a1]; y = b[b1]; for (i = 0; i < bmpHeight; i++) { for(j=0;j<bmpWidth;j++) { for(k=0;k<3;k++) { *(pBmpBufOne+(x+i)*lineByteback+(y+j)*3+k) &= (*(pBmpBufThree+i*lineBytesky+j*3+k)); *(pBmpBufOne+(x+i)*lineByteback+(y+j)*3+k) |= (*(pBmpBufTwo+i*lineByteplane+j*3+k)); if (lineBytesky != lineByteplane) { printf("............................\n"); } } } } char writePath[]="hncuduplicate.bmp"; saveBmp(writePath,pBmpBufOne,bmpWidthback,bmpHeightback,biBitCountback,pColorTable); } free(pBmpBufOne); free(pBmpBufTwo); free(pBmpBufThree); if (biBitCount == 8) { free(pColorTable); } return 0; } #endif
正文完