c++实现bmp文件的读写
来源:互联网 发布:淘宝客订单虚假交易 编辑:程序博客网 时间:2024/04/28 19:01
程序分为bmp相关的三个文件以及一个实例文件:
1.bmp格式文件的结构体定义-- bmpstruct.h
2.bmp格式文件的类定义文件-- cBMPimage.h
3.bmp格式文件的类实现文件 - cBMPimage.cpp
4示例文件--main.c
1.bmpstruct.h
#ifndef BMPSTRUCT#define BMPSTRUCT//~~~~~~~~~~~~~~~~~~结构体定义~~~~~~~~~~~~~~~~~~~~~~~~//typedef struct tagBMPHEADER{unsigned short bfType; //文件类型unsigned long bfSize; //bmp文件长度WORD Reserved1;WORD Reserved2;unsigned long bfOffset; //文件描述区长度,16色为118,256色为1078}BMPHEADER;//现在算一下,有3个int,2个long,正好3*2+2*4=14字节//图像信息区typedef struct tagBMPINFOHEADER{DWORD biSize;LONG biWidth;LONG biHeight;WORD biPlanes;WORD biBitCount;DWORD biCompression;DWORD biSizeImage;LONG biXplosPerMeter;LONG biYplosPerMeter;DWORD biClrUsed;DWORD biClrImportant;} BMPINFOHEADER;// 2+2*9*4 =40 字节?有疑问//调色板typedef struct tagBMPRGBQUAD{BYTE rgbBlue;BYTE rgbGreen;BYTE rgbRed;BYTE rgbReserve;} BMPRGBQUAD;//位图数据typedef struct tagIMAGEDATA{BYTE red;BYTE green;BYTE blue;}IMAGEDATA;#endif
2.cBMPimage.h
#pragma once#include <stdio.h>#include <windows.h>#include "bmpstruct.h"class cBMPimage{public:BMPHEADER file;BMPINFOHEADER info;BMPRGBQUAD *palette;IMAGEDATA *imagedata;public:cBMPimage(void);~cBMPimage(void);public:int GetBmpSize(FILE *fp) ;int bmpload(const char* filename);int bmpsave(const char* filename);int bmpcopypara(cBMPimage *bmpimage);};
3.cBMPimage.cpp (实际使用时最好将printf去掉)
#include "cBMPimage.h"cBMPimage::cBMPimage(void){palette = NULL;imagedata = NULL;}cBMPimage::~cBMPimage(void){if (palette!=NULL){free(palette);palette = NULL;}if (imagedata!=NULL){free(imagedata);imagedata= NULL;}}int cBMPimage::GetBmpSize( FILE *fp ){long curpos; // attention! this is a long type. int len; curpos = ftell(fp); fseek(fp, 0, SEEK_END); len = ftell(fp); fseek(fp, curpos, SEEK_SET); return len; }int cBMPimage::bmpload( const char* filename ){FILE *fp;int bTrueClr=1;unsigned char *cp1, *cp2, *sp; int i, j; int Width; unsigned char *paletteIndex; if ((fp = fopen(filename,"rb+")) == NULL) // must be "rb" to indicate the position of the file while the pointer is moving! { printf("Can not open file\n"); system("pause"); exit(0); }fread(&file,sizeof(unsigned short),1,fp);//??????????sp = (unsigned char*)&file;sp = sp+4;fread(sp,sizeof(struct tagBMPHEADER)-4,1,fp);fread(&info,sizeof(struct tagBMPINFOHEADER),1,fp);if (info.biBitCount==1||\info.biBitCount==4||\info.biBitCount==8){palette = (BMPRGBQUAD *)malloc(sizeof(BMPRGBQUAD)*(1<<info.biBitCount));fread(palette,sizeof(BMPRGBQUAD)*(1<<info.biBitCount),1,fp);bTrueClr = 0;}if (file.bfType != 0x4d42) { printf("The type of the image is not supported\n"); } if (info.biCompression != 0) { printf("The compression type are not supported.\n"); } if (file.bfSize != GetBmpSize(fp)) { printf("The size of the file is not matched\n"); } cp1 = (unsigned char *)&(file.bfType); cp2 = cp1 + 1; printf("%c", *cp1); printf("%c\n", *cp2); printf("File size: %lu\n", file.bfSize); printf("Offset from the BOF to the virtual image data: %lu\n", file.bfOffset); // print the info value. printf("The size of the infoheader is: %lu\n", info.biSize); printf("Width: %ld\n", info.biWidth); printf("Height: %ld\n", info.biHeight); printf("Planes: %d\n", info.biPlanes); printf("Bit Depth: %d\n", info.biBitCount); printf("Compression type: %lu\n", info.biCompression); printf("Image data size: %lu\n", info.biSizeImage); printf("XperMeter: %ld\n", info.biXplosPerMeter); printf("YperMeter: %ld\n", info.biYplosPerMeter); printf("Color used: %lu\n", info.biClrUsed); printf("Important color: %lu\n", info.biClrImportant); Width = (info.biWidth*info.biBitCount + 31)/8/4*4;//int pic_width = Width/4;// print the pixel of the imagedata imagedata = (IMAGEDATA *)malloc( sizeof(unsigned char)*Width*info.biHeight);paletteIndex = (unsigned char *)malloc(sizeof(unsigned char)*Width*info.biHeight); if (!bTrueClr) { fread(paletteIndex, sizeof(unsigned char)*Width*info.biHeight, 1, fp); for (i = 0; i < info.biHeight; i++) { for (j = 0; j < Width; j++) { (*(imagedata + i * info.biHeight + j)).blue = palette[(BYTE)(*(paletteIndex + i*info.biHeight + j))].rgbBlue; (*(imagedata + i * info.biHeight + j)).green = palette[(BYTE)(*(paletteIndex + i*info.biHeight + j))].rgbGreen; (*(imagedata + i * info.biHeight + j)).red= palette[(BYTE)(*(paletteIndex + i*info.biHeight + j))].rgbRed; } } } else { fread(imagedata, sizeof(unsigned char)*Width*info.biHeight, 1, fp);} fclose(fp); //system("pause"); free(paletteIndex); return 0; }int cBMPimage::bmpcopypara( cBMPimage *pbmpimage ){file.bfOffset = pbmpimage->file.bfOffset;file.bfSize = pbmpimage->file.bfSize;file.bfType = pbmpimage->file.bfType;info.biBitCount = pbmpimage->info.biBitCount;info.biClrImportant = pbmpimage->info.biClrImportant;info.biClrUsed = pbmpimage->info.biClrUsed;info.biCompression = pbmpimage->info.biCompression;info.biHeight = pbmpimage->info.biHeight;info.biPlanes = pbmpimage->info.biPlanes;info.biSize = pbmpimage->info.biSize;info.biSizeImage = pbmpimage->info.biSizeImage;info.biWidth = pbmpimage->info.biWidth;info.biXplosPerMeter = pbmpimage->info.biXplosPerMeter;info.biYplosPerMeter = pbmpimage->info.biYplosPerMeter;if (pbmpimage->palette ==NULL){ palette = NULL;}else{int sizepale = sizeof(BMPRGBQUAD)*(1<<info.biBitCount);palette = (BMPRGBQUAD *)malloc(sizepale);memcpy(palette,pbmpimage->palette,sizepale);}return 1;}int cBMPimage::bmpsave( const char* filename ){FILE *fp = NULL;if (!(fp=fopen(filename,"wb+"))){printf("无法打开文件%s!\n",filename);return -1;}if(fwrite(&file.bfType,sizeof(WORD),1,fp)!=1){printf("Can not write bfType in the file header.\n");fclose(fp);return -1;}if(fwrite(&file.bfSize,sizeof(DWORD),1,fp)!=1){printf("Can not write bfSize in the file header.\n");fclose(fp);return -1;}if(fwrite(&file.Reserved1,sizeof(WORD),1,fp)!=1){printf("Can not write bfReserved1 in the file header.\n");fclose(fp);return -1;}if(fwrite(&file.Reserved2,sizeof(WORD),1,fp)!=1){printf("Can not write bfReserved2 in the file header.\n");fclose(fp);return -1;}if(fwrite(&file.bfOffset,sizeof(DWORD),1,fp)!=1){printf("Can not write bfOffBits in the file header.\n");fclose(fp);return -1;}if(fwrite(&info.biSize,sizeof(DWORD),1,fp)!=1){printf("Can not write biSize in the info header.\n");fclose(fp);return -1;}if(fwrite(&info.biWidth,sizeof(LONG),1,fp)!=1){printf("Can not write biWidth in the info header.\n");fclose(fp);return -1;}if(fwrite(&info.biHeight,sizeof(LONG),1,fp)!=1){printf("Can not write biHeight in the info header.\n");fclose(fp);return -1;}if(fwrite(&info.biPlanes,sizeof(WORD),1,fp)!=1){printf("Can not write biPlanes in the info header.\n");fclose(fp);return -1;}if(fwrite(&info.biBitCount,sizeof(WORD),1,fp)!=1){printf("Can not write biBitCount in the info header.\n");fclose(fp);return -1;}if(fwrite(&info.biCompression,sizeof(DWORD),1,fp)!=1){printf("Can not write biCompression in the info header.\n");fclose(fp);return -1;}if(fwrite(&info.biSizeImage,sizeof(DWORD),1,fp)!=1){printf("Can not write biSizeImage in the info header.\n");fclose(fp);return -1;}if(fwrite(&info.biXplosPerMeter,sizeof(LONG),1,fp)!=1){printf("Can not write biXPelsPerMeter in the info header.\n");fclose(fp);return -1;}if(fwrite(&info.biYplosPerMeter,sizeof(LONG),1,fp)!=1){printf("Can not write biYPelsPerMeter in the info header.\n");fclose(fp);return -1;}if(fwrite(&info.biClrUsed,sizeof(DWORD),1,fp)!=1){printf("Can not write biClrUsed in the info header.\n");fclose(fp);return -1;}if(fwrite(&info.biClrImportant,sizeof(DWORD),1,fp)!=1){printf("Can not write biClrImportant in the info header.\n");fclose(fp);return -1;}BMPRGBQUAD pal[256];for(int i=0;i<256;i++){pal[i].rgbReserve=0;pal[i].rgbBlue=i;pal[i].rgbGreen=i;pal[i].rgbRed=i;}if(info.biBitCount==8){if(fwrite(pal,sizeof(RGBQUAD),256,fp)!=256){printf("Error: can not write the color palette.\n");fclose(fp);return -1;}}int Width = (info.biWidth*info.biBitCount + 31)/8/4*4;int writenum = fwrite(imagedata,sizeof(unsigned char),info.biHeight*Width,fp);if(writenum!=info.biHeight*Width){printf("Error: can not write the pixel data.\n");fclose(fp);return -1;}fclose(fp);//printf("Save As the image successfully.\n");return 0;}
4.main.c
#include "cBMPimage.h"int main(){char *fp ="E:\\cudatest\\bmpread\\bmpread\\Debug\\a.bmp";cBMPimage image1,image2;image1.bmpload(fp);image2.bmpcopypara(&image1);image1.bmpsave("E:\\cudatest\\bmpread\\bmpread\\b.bmp");return 0;}
注:在简略上述程序,只用于8位灰度图时,发现会出现读写错误。逐语句的去找问题,终于找到了。。。。
在打开bmp文件时,若用fopen函数,mode使用“r+”时,会默认用文本文件方式打开bmp文件,这时,读取颜色表不成功(只读到了0~0x19)。
所以在打开bmp文件时,一定要用“rb+”,即以二进制方式打开bmp文件。
为什么在读到0x19 0x19 0x19 0xff 后会结束呢?
因为0x19后是0x1a,0x1A在ASCII码中代表EOF,在过去,ASCII码EOF曾经在unix/linux中被作为文件结束符使用,微软继承了这个传统,也以EOF作为文件的结束符
如何解决这个问题?其实标准已经给出了其中一种解决方法,由于二进制方式的输入输出是一一对应的,字符不会产生变化,那么用二进制读取就不会产生这个问题,事实也证明是可以的,只是存在一点麻烦,由于windows下会把/n转换为/r/n,二进制读取时必须对此转换进行堙别和还原,这会增加代码的复杂性,这种麻烦很让人讨厌。- c++实现bmp文件的读写
- BMP 文件的读写
- bmp文件的读写
- BMP文件的读写
- C语言读写BMP文件
- C/C++读写BMP文件
- BMP文件学习笔记(一): C/C++语言实现.bmp文件读写
- 纯C下的读写BMP文件代码
- 纯C下的读写BMP文件代码
- 纯C下的读写BMP文件代码收藏
- 用C语言进行BMP文件的读写
- 用C语言进行BMP文件的读写
- 用C语言进行BMP文件的读写
- 纯C下的读写BMP文件代码
- 用C语言进行BMP文件的读写
- 用C语言进行BMP文件的读写
- C语言实现BMP格式图片的读写
- C读写BMP文件代码(转载)
- 瑞星携手华为——打开虚拟化安全市场的新大门
- 在 Unix 环境中正确设置 NLS_LANG (文档 ID 1548858.1)
- linux 设备模型
- IT English Collection(13) of Nib file
- 鲍尔默最后一次员工大会:声泪俱下别微软
- c++实现bmp文件的读写
- input event获取按键键值
- 【Android UI设计与开发】第10期:顶部标题栏(一)ActionBar详细概述和简单示例
- A. Petya and Java
- Android详细的对话框AlertDialog.Builder使用方法
- pv操作及信号量实用实例详解
- 谁是作案人
- 《剑指offer》系列---1
- Webview请求网络