VC中保存BMP位图文件的方法及BMP文件格式带源码实现

#include "stdio.h"
#include "Windows.h"
//几个全局变量,存放读入图像的位图数据、宽、高、颜色表及每像素所占位数(比特) //此处定义全局变量主要为了后面的图像数据访问及图像存储作准备
unsigned char *pBmpBuf;//读入图像数据的指针
int bmpWidth;//图像的宽
int bmpHeight;//图像的高
RGBQUAD *pColorT able;//颜色表指针
int biBitCount;//图像类型
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;
//灰度图像有颜色表,且颜色表表项为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);
//关闭文件
fclose(fp);
return 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;
//以二进制写的方式打开文件
FILE *fp=fopen(bmpName,"wb");
if(fp==0) return 0;
//申请位图文件头结构变量,填写文件头信息
BITMAPFILEHEADER fileHead;
fileHead.bfType = 0x4D42;//bmp类型
//bfSize是图像文件4个组成部分之和
fileHead.bfSize= sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + colorT ablesize + lineByte*height;
fileHead.bfReserved1 = 0;
fileHead.bfReserved2 = 0;
//bfOffBits是图像文件前三个部分所需空间之和
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[]="tarret.BMP";
readBmp(readPath);
//输出图像的信息
printf("width=%d,height=%d,biBitCount=%d\n",bmpWidth,bmpHeight,biBit Count);
//改变灰度图像的颜色表蓝色分量的值,察看前后变化
if(biBitCount==8){
for(int i=0; i<256;i++){
pColorTable[i].rgbBlue = 255-pColorTable[i].rgbBlue;
}
}
//将图像数据存盘
char writePath[]="tarret1.BMP";
saveBmp(writePath, pBmpBuf, bmpWidth, bmpHeight, biBitCount, pColorT able);
//清除缓冲区,pBmpBuf和pColorT able是全局变量,在文件读入时申请的空间
delete []pBmpBuf;
if(biBitCount==8)
delete []pColorTable;
}。

合集下载

C语言读取BMP图像数据的源码

C语言读取BMP图像数据的源码

C语⾔读取BMP图像数据的源码BMP是英⽂Bitmap(位图)的简写,它是Windows操作系统中的标准图像⽂件格式,能够被多种Windows应⽤程序所⽀持。

随着Windows操作系统的流⾏与丰富的Windows应⽤程序的开发,BMP位图格式理所当然地被⼴泛应⽤。

这种格式的特点是包含的图像信息较丰富,⼏乎不进⾏压缩,但由此导致了它与⽣俱⽣来的缺点--占⽤磁盘空间过⼤。

所以,⽬前BMP在单机上⽐较流⾏。

BMP⽂件格式分析简介BMP(Bitmap-File)图形⽂件是Windows采⽤的图形⽂件格式,在Windows环境下运⾏的所有图象处理软件都⽀持BMP图象⽂件格式。

Windows系统内部各图像绘制操作都是以BMP为基础的。

Windows 3.0以前的BMP图⽂件格式与显⽰设备有关,因此把这种BMP图象⽂件格式称为设备相关位图DDB(device-dependent bitmap)⽂件格式。

Windows 3.0以后的BMP图象⽂件与显⽰设备⽆关,因此把这种BMP图象⽂件格式称为设备⽆关位图DIB(device-independent bitmap)格式(注:Windows 3.0以后,在系统中仍然存在DDB位图,象BitBlt()这种函数就是基于DDB位图的,只不过如果你想将图像以BMP格式保存到磁盘⽂件中时,微软极⼒推荐你以DIB格式保存),⽬的是为了让Windows能够在任何类型的显⽰设备上显⽰所存储的图象。

BMP 位图⽂件默认的⽂件扩展名是BMP或者bmp(有时它也会以.DIB或.RLE作扩展名)。

位图⽂件结构表位图⽂件位图⽂件头 14 字节位图信息头 40 字节彩⾊表(调⾊板) 4N 字节位图数据 x 字节构件详解:位图⽂件头位图⽂件头包含⽂件类型、⽂件⼤⼩、存放位置等信息。

结构定义如下:typedef struct tagBITMAPFILEHEADER{UNIT bfType;DWORD bfSize;UINT bfReserved1;UINT bfReserved2;DWORD bfOffBits;}BITMAPFILEHEADER;其中:bfType 说明⽂件类型,在windows系统中为BM。

实验一、VC6.0下bmp位图的读取与显示

实验一、VC6.0下bmp位图的读取与显示

实验一、VC6.0下bmp位图的读取与显示一、实验目的:1、掌握windows BMP格式位图文件的基本格式。

2、会使用VC++读取图像数据并显示。

二、实验内容:1、在VC6.0环境下,生成MFC应用程序框架。

2、在已生成的应用程序中,加BMP位图读取与显示的代码,从已有文件中读取bmp格式文件并在视图中显示。

三、实验原理及步骤:基本知识:BMP位图文件格式BMP位图文件中主要由4部分内容组成:1、文件头BITMAPFILEHEADER为一STRUCTURE:typedef struct tagBITMAPFILEHEADER {WORD bfType;//文件类型,必须为“BM”或0x424dDWORD bfSize;//文件大小WORD bfReserved1;//保留WORD bfReserved2;//保留DWORD bfOffBits;//从文件头到实际位图数据的偏移字节数} BITMAPFILEHEADER, FAR *LPBITMAPFILEHEADER, *PBITMAPFILEHEADER;2、位图信息头BITMAPINFOHEADER,定义如下:typedef struct tagBITMAPINFOHEADER{DWORD biSize;//structure sizeLONG biWidth;//image widthLONG biHeight;//image heightWORD biPlanes;//value is 1WORD biBitCount;//color bitsDWORD biCompression;//compression or notDWORD biSizeImage;//Imagesize=width*height( 其中width必须为4的倍数。

LONG biXPelsPerMeter;//LONG biYPelsPerMeter;DWORD biClrUsed;//DWORD biClrImportant;} BITMAPINFOHEADER, FAR *LPBITMAPINFOHEADER, *PBITMAPINFOHEADER;3、调色板typedef struct tagRGBQUAD {BYTE rgbBlue;BYTE rgbGreen;BYTE rgbRed;BYTE rgbReserved;} RGBQUAD;用于存放图像的颜色。

在vc中自建操作bmp位图文件的类(Classes that build BMP bitmap files in VC)

在vc中自建操作bmp位图文件的类(Classes that build BMP bitmap files in VC)

在vc中自建操作bmp位图文件的类(Classes that build BMP bitmapfiles in VC)Classes that build BMP bitmap files in VCXi'an Wanshan Software Co. Ltd.JiatunProgrammers who have programming experience know that to make the application's interface beautiful and inevitableUsing lots of bitmaps. The popular visual programming tools now provide good use of bitmapsThe support, known as the three visual development tools of VB, VC, and Delphi, encapsulates bitmaps by encapsulating themObjects provide good support for bitmap usage: VB provides two powerful objects:PictureBox and Image make it very easy to load and display bitmaps by using them.Delphi also provides a bitmap object: TImage, its function and usage, and VBImage is similar. In VC, you use the device dependent class CDC and the GDI object class CBitmap to completeBitmap operation. However, in VC, using the CBitmap class mustload the BMP bitmap into the resource,Then, using the member functions of class CBitmap, use it to operate through member functions of the CDC classIt. There are two drawbacks to doing this: loading a bitmap into a resource causes an executable file to increase and is detrimentalIn software release; can only use limited bitmap in the resource, unable to select other bitmap. AndThe BMP bitmap file is saved in DIB (device independent bitmap), and the BMP bitmap is loaded into the resourceIs converted to DDB (device related bitmaps), and class CBitmap is a series of DDB operationsThe API function is encapsulated and used with some limitations, so that DIB can be independentPlatform characteristics. To make up for two deficiencies in using a resource bitmap, you must use the BMP bitmap directlyDocument. The example of VC provides a way to read and display BMP bitmap files, but use themQuite troublesome. First, use the API function GlobalAlloc to allocate memory and create the HDIB bitmapHandle, all operations can only read and write memory directly,and then through StrechDIBits andThe SetDIBsToDevice function appears on the screen, and it takes time and effort to operate.Therefore, the author studies the encapsulation and DIB structure of class CBitmap and uses the new functions provided in Win32Number, set up a class dedicated to operating BMP files, and completely follow the implementation of class CBitmap:Derived from class CGdiObject, all interfaces of the new class are exactly the same as part of the class CBitmap interface.Thus, the interface between the two is used for programmers who are accustomed to using the CBitmap class interfaceThere is no difference.Let's start with a brief introduction to the structure of DIB. DIB bitmaps can exist either in memory or in memorySave in file form on disk (BMP file). All DIB contains two parts of information: bitmapsInformation (BITMAPINFO), including bitmaps, headers, and color tables; bitmap data. For memoryAs long as the above two parts of DIB, and for the DIB file, you also have to add bitmap file header. TwoThe structure is shown here:DIBDIB fileSecond, Win32 provides a new function, CreateDIBSection, which creates a new oneMemory locations that store DIB bits can either execute the corresponding GDI operations or point directly through themThe pointer, azimuth, DIB bit region of the DIB bit region. This is a very useful function, through which weYou can use DIB instead of DDB.After knowing the relevant knowledge, we can derive an operation BMP by ourselves from class CGdiObjectClass: CBitmapFile.There are two points worth noting when writing your own class:1. to define class CBitmapFile in the BitmapFile.h file, you must first declare the class CBitmapFileIs derived from class CGdiObject. Then use macros first in the classDECLARE_DYNAMIC (CBitmapFile) indicates that the highest parent class of the new class is class CObject, which is consistentClass library specification for MFC. Next to macro DECLARE_DYNAMIC is the declaration of the static function FromHandle,These two declarations must be placed at the forefront of the class definition.2. add the function of the class member in the BitmapFile.cpp file before you implement itIMPLEMENT_DYNAMIC (CBitmapFile, CGdiObject); indicates that class CBitmapFile is derived directlyClass CGdiObject.In a class CBitmapFile declaration, three functions are slightly different from the definitions in class Cbitmap:1. in class CbitmapFile, the argument of the LoadBitmap function is LPCTSTR, and the BMP text is savedFilename of the file.2. in class CbitmapFile, the parameter in the CreateBitmap function is less parameter nPlanes, in functionThe internal default is 1.3. in class CbitmapFile, there is more parameter lpBits in the arguments of the CreateBitmapIndirect function,It points to the memory area of the specified bitmap DIB bits.The most important thing in the member function is the function CreateBitmapIndirect and the function LoadBitmap:1. creates a function with function CreateBitmapIndirect in the function CreateDIBSectionCompatible with the DC based HBITMAP handle and Attach it with the function CGdiObject that inherits from class A.The handle CGdiObject of class m_hObject is associated. The DIB bitmap data of the specified bitmap is then copiedThe memory area of the DIB bit created by the function CreateDIBSection.2. in function LoadBitmap, the structure is first read from the file of the specified file nameBITMAPFILEHEADER is the size of the data block, and then the file header mark to determine whether the file is BMP bitsThe file size of the chart file, then saved by BITMAPFILEHEADER in bfSize, is really large with the fileSmall comparison file for damage, and then by BITMAPFILEHEADER,bfOffBits andBITMAPFILEHEADER structure size subtraction, calculate the location, information head and color table of the total size, moveApply a space to save bitmaps, information headers, and color table information, and then from BITMAPFILEHEADERBfSize and bfOffBits subtract, calculate the size of DIB bitmap data, dynamically apply for a space to saveDIB bitmap data, and finally call the member function CreateBitmapIndirect to create the DIB bitmap.In the OnPaint () event of the application, the method of drawing the DIB bitmap is drawn when using class CBitmapBitmap methods are exactly the same, but one thing to note is that the CDC class does not provide the return of the new classThe CBitmapFile pointer type selects the DIB bitmap into the memory's SelectObject function, so in makingWhen SelectObject is used, the return type is coerced to CbitmapFile * type.So far, some of the main points in the preparation of the new class CBitmapFile and some of the issues you should pay attention to when using itIntroducing so much.Attached file/ /File Description: / / class CBitmapFile, the class is used to read the BMP file, to read,/ / establishment and a series of common operation./ / file name: BitmapFile.h/ / time: 1999-2-11/ / Author: Jia Tun/ /#ifndef _CBITMAPFILE_H_#define _CBITMAPFILE_H_Class CBitmapFile: public CGdiObject{DECLARE_DYNAMIC (CBitmapFile)Public:Static, CBitmapFile*, PASCAL, FromHandle (HBITMAP, hBitmap);/ / ConstructorsCBitmapFile ();BOOL LoadBitmap (LPCTSTR lpszFileName);BOOL, CreateBitmap (int, nWidth, int, nHeight, UINT, nBitCount, const, void*, lpBits);BOOL CreateBitmapIndirect (LPBITMAPINFO, lpBitmapInfo, const, void*, lpBits);/ / AttributesOperator HBITMAP () const;Int GetBitmap (BITMAP* pBitMap);Protected:/ / AttributesInt GetColorNumber (WORD wBitCount);Public:/ / OperationsDWORD SetBitmapBits (DWORD, dwCount, const, void*, lpBits);DWORD GetBitmapBits (DWORD, dwCount, LPVOID, lpBits);/ / ImplementationPublic:Virtual, ~CBitmapFile ();};#endif/ /File Description: / / implementation class member function in CBitmapFile/ / file name: BitmapFile.cpp/ / time: 1999-2-11/ / Author: Jia Tun/ /#include "BitmapFile.h""#include <memory.h>IMPLEMENT_DYNAMIC (CBitmapFile, CGdiObject);CBitmapFile* PASCAL CBitmapFile:: FromHandle (HBITMAP hBitmap){Return (CBitmapFile*) CGdiObject:: FromHandle (hBitmap);}CBitmapFile:: CBitmapFile (){}BOOL CBitmapFile:: LoadBitmap (LPCTSTR, lpszFileName){CFile file;If (... File.Open (lpszFileName, CFile:: modeRead|CFile:: shareDenyWrite)){MessageBox (NULL, BMP, file, open, error), warning, MB_OK);Return FALSE;BITMAPFILEHEADER bfhHeader;File.Read (&bfhHeader, sizeof (BITMAPFILEHEADER));If (bfhHeader.bfType = = ((WORD) ('M'<<8) |'B')){MessageBox(null,“该文件不是一个BMP文件!”,“警告”,mb_ok);返回false;}如果(bfhheader.bfsize!=文件getlength())。

Bmp图像存储格式

Bmp图像存储格式

摘要:本文简单介绍了位图文件的两种存储格式,并且在VC++6.0下实现了读取位图文件中的数据,用SetPixel()函数在窗口中重现图像,最后在程序中实现了一种存储格式到另一种存储格式的转换。

关键字:BMP、灰度位图、24位真彩色位图、存储格式一、前言BMP(Bitmap的缩写)图像是指文件名后缀为BMP的位图图像。

位图图像在计算机中使用很广泛,例如在windows中,记事本、写字板中的文字就是用位图图像表示出来的。

许多以其它格式存储的图像,就是在位图图像的基础上,进行优化处理后得到的,例如JPEG图像等。

在数字图像处理中,许多算法就是针对24位真彩色位图或灰度位图设计的。

因此,很有必要介绍一下位图文件的这两种存储格式。

二、24位真彩色图像存储格式把下图的24位真彩色图像格式在16位编辑器(例如VC编辑器)中打开,可以看到图像的二进制数据。

24位真彩色的二进制数据为:这是24位真彩色位图文件数据一部分。

这一部分数据包括位图文件头、位图信息头和位图阵列三部分。

(一)位图文件头位图文件头用来记录标志文件大小的一些信息,在文件中占14个字节,存储的内容如下:字节 1 2 3 4 5 6 7 8 9 10 11 12 13 14 000000 42 4D CC B4 02 00 00 00 00 00 36 00 00 00 其中:42 4D 为位图的标志,即ASCII码为BMCC B4 02 表示位图文件的总字节数,换算成十进制为(02B4CC)H=(177356)10,即这副图像的大小为177356字节。

00 00 00 00 00 为保留字节,用来存储文件大小的数据。

36 00 00 00 00 表示位图阵列的起始位置,(36)H=(54)10即54字节开始为位图阵列。

(二) 位图信息头位图信息头记录和位图相关的一些信息,在文件中占40个字节,存储的内容如下:字节 1 2 3 4 5 6 7 8 9 10 11121314151600000 0 2800001 6 02C1C511800003 2 012B12B00004 8 0其中:28 00 00 00 表示信息头的长度,(28)H=(40)10,即位图信息头占40个字节。

C语言读取bmp位图文件(含bmp格式定义)

C语言读取bmp位图文件(含bmp格式定义)
rgb_to_yuv(in_ptr[0], in_ptr[1], in_ptr[2], &Y, &U, &V);
in_ptr += pbmp->info.BiBitCount / 8;
*out_ptr_y++ = Y;
if (x % 2 == 0 && y % 2 == 0) {
pbmp->info.BiWidth = *(DWORD*)(&headbuffer[0]);
pbmp->info.BiHeight = *(DWORD*)(&headbuffer[4]);
pbmp->info.BiBitCount = *(DWORD*)(&headbuffer[10]);
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include "loadbmp.h"
void rgb_to_yuv(unsigned int r, unsigned int g, unsigned int b,
unsigned int *y, unsigned int *u, unsigned int *v)
#define FILEHEADSIZE 14
/* windows style*/
typedef struct {
/* BITMAPINFOHEADER*/
DWORD BiSize;
DWORD BiWidth;
DWORD BiHeight;
// free(pbmp->yuy2);

在VC中自建操作BMP位图文件的类

在VC中自建操作BMP位图文件的类

在VC中自建操作BMP位图文件的类有编程经验的程序员都知道:要使应用程序的界面美观不可避免的要使用大量位图。

现在流行的可视化编程工具对位图的使用提供了很好的支持,被称为三大可视化开发工具的VB、VC、Delphi通过封装位图对象对位图使用提供了很好的支持:VB提供了两个功能很强的对象:PictureBox及Image,通过使用它们,装载、显示位图变得非常容易。

Delphi中也提供了一个位图对象:TImage,它的功能与用法与VB中的Image类似。

在VC中通过使用设备相关类CDC与GDI对象类CBitmap来完成位图的操作。

然而在VC中使用CBitmap类必须将BMP位图装入资源中,然后通过类 CBitmap 的成员函数使用它,在通过CDC类的成员函数操作它。

这样做有两点缺陷:将位图装入资源导致可执行文件增大,不利于软件发行;只能使用资源中有限的位图,无法选取其它位图。

而且BMP位图文件是以DIB(设备无关位图)方式保存,BMP位图装入资源后被转换为DDB(设备相关位图),类CBitmap就是对一系列DDB操作的API函数进行了封装,使用起来有一定的局限性,不如DIB可以独立于平台特性。

要弥补使用资源位图的两点不足,就必须直接使用BMP位图文件。

VC的示例中提供了一种方法读取并显示BMP位图文件,但使用起来相当的麻烦。

首先使用API 函数GlobalAlloc分配内存并创建HDIB位图句柄,所有操作只能直接读写内存,然后通过StrechDIBits及SetDIBsToDevice函数来显示于屏幕上,操作起来费时费力。

因此笔者通过研究类CBitmap的封装与DIB结构,使用Win32中提供的新函数,建立了一个专用于操作BMP文件的类,而且完全仿照类CBitmap的实现:从类CGdiObject派生,新类的所有接口与类CBitmap 的部分接口完全相同。

这样对于习惯使用CBitmap类接口用法的程序员来说两者的接口在使用上没有什么分别。

位图文件(BMP)格式分析以及程序实现

inf.read((char*)&header, sizeof(header));if(header.bfType != 0x4D42)return false;这个很简单,没有什么好说的。

2、加载位图信息头//Load the image information headerBITMAPINFOHEADER infoheader;memset(&infoheader, 0, sizeof(infoheader));inf.read((char*)&infoheader, sizeof(infoheader));m_iImageWidth = infoheader.biWidth;m_iImageHeight = infoheader.biHeight;m_iBitsPerPixel = infoheader.biBitCount;这里我们得到了3各重要的图形属性:宽,高,以及每个像素颜色所占用的位数。

3、行对齐由于Windows在进行行扫描的时候最小的单位为4个字节,所以当图片宽X 每个像素的字节数!= 4的整数倍时要在每行的后面补上缺少的字节,以0填充(一般来说当图像宽度为2的幂时不需要对齐)。

位图文件里的数据在写入的时候已经进行了行对齐,也就是说加载的时候不需要再做行对齐。

但是这样一来图片数据的长度就不是:宽X 高X 每个像素的字节数了,我们需要通过下面的方法计算正确的数据长度://Calculate the image data sizeint iLineByteCnt = (((m_iImageWidth*m_iBitsPerPixel) + 31) >> 5) << 2;m_iImageDataSize = iLineByteCnt * m_iImageHeight;4、加载图片数据对于24位和32位的位图文件,位图数据的偏移量为sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER),也就是说现在我们可以直接读取图像数据了。

VC中保存BMP位图文件的方法及BMP文件格式带源码实现

#include "stdio.h"#include "Windows.h"//几个全局变量,存放读入图像的位图数据、宽、高、颜色表及每像素所占位数(比特) //此处定义全局变量主要为了后面的图像数据访问及图像存储作准备unsigned char *pBmpBuf;//读入图像数据的指针int bmpWidth;//图像的宽int bmpHeight;//图像的高RGBQUAD *pColorT able;//颜色表指针int biBitCount;//图像类型bool readBmp(char *bmpName){//二进制读方式打开指定的图像文件FILE *fp=fopen(bmpName,"rb");if(fp==0) return 0;//跳过位图文件头结构BITMAPFILEHEADERfseek(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;//灰度图像有颜色表,且颜色表表项为256if(biBitCount==8){//申请颜色表所需要的空间,读颜色表进内存pColorTable=new RGBQUAD[256];fread(pColorTable,sizeof(RGBQUAD),256,fp);}//申请位图数据所需要的空间,读位图数据进内存pBmpBuf=new unsigned char[lineByte * bmpHeight];fread(pBmpBuf,1,lineByte * bmpHeight,fp);//关闭文件fclose(fp);return 1;}bool saveBmp(char *bmpName, unsigned char *imgBuf, int width, int height, int biBitCount, RGBQUAD *pColorTable){//如果位图数据指针为0,则没有数据传入,函数返回if(!imgBuf)return 0;//颜色表大小,以字节为单位,灰度图像颜色表为1024字节,彩色图像颜色表大小为0int colorTablesize=0;if(biBitCount==8)colorTablesize=1024;//待存储图像数据每行字节数为4的倍数int lineByte=(width * biBitCount/8+3)/4*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) + colorT ablesize + lineByte*height;fileHead.bfReserved1 = 0;fileHead.bfReserved2 = 0;//bfOffBits是图像文件前三个部分所需空间之和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[]="tarret.BMP";readBmp(readPath);//输出图像的信息printf("width=%d,height=%d,biBitCount=%d\n",bmpWidth,bmpHeight,biBit Count);//改变灰度图像的颜色表蓝色分量的值,察看前后变化if(biBitCount==8){for(int i=0; i<256;i++){pColorTable[i].rgbBlue = 255-pColorTable[i].rgbBlue;}}//将图像数据存盘char writePath[]="tarret1.BMP";saveBmp(writePath, pBmpBuf, bmpWidth, bmpHeight, biBitCount, pColorT able);//清除缓冲区,pBmpBuf和pColorT able是全局变量,在文件读入时申请的空间delete []pBmpBuf;if(biBitCount==8)delete []pColorTable;}。

【数字图像处理】C++读取、旋转和保存bmp图像文件编程实现(彩色图)

【数字图像处理】C++读取、旋转和保存bmp图像⽂件编程实现(彩⾊图)彩⾊图:彩⾊图的处理和灰度图略有不⼀样。

主要是像素数据不同。

由于每⾏数据的字节数必须是4的整数倍,这个地⽅处理起来要⽐灰度图⿇烦很多,多以暂时还没做好。

本程序的局限性就是只能处理尺⼨是4的整数倍的图⽚,可以旋转任意⾓度(逆时针)。

参考代码:分两个⽂件:BmpRot.h和BmpRot.cppBmpRot.h:BmpRot.cpp:23. cout<<"实际位图数据的偏移字节数:"<<pBmpHead.bfOffBits<<endl<<endl;24. }25.26. void showBmpInforHead(tagBITMAPINFOHEADER pBmpInforHead){27. cout<<"位图信息头:"<<endl;28. cout<<"结构体的长度:"<<pBmpInforHead.biSize<<endl;29. cout<<"位图宽:"<<pBmpInforHead.biWidth<<endl;30. cout<<"位图⾼:"<<pBmpInforHead.biHeight<<endl;31. cout<<"biPlanes平⾯数:"<<pBmpInforHead.biPlanes<<endl;32. cout<<"biBitCount采⽤颜⾊位数:"<<pBmpInforHead.biBitCount<<endl;33. cout<<"压缩⽅式:"<<pBmpInforHead.biCompression<<endl;34. cout<<"biSizeImage实际位图数据占⽤的字节数:"<<pBmpInforHead.biSizeImage<<endl;35. cout<<"X⽅向分辨率:"<<pBmpInforHead.biXPelsPerMeter<<endl;36. cout<<"Y⽅向分辨率:"<<pBmpInforHead.biYPelsPerMeter<<endl;37. cout<<"使⽤的颜⾊数:"<<pBmpInforHead.biClrUsed<<endl;38. cout<<"重要颜⾊数:"<<pBmpInforHead.biClrImportant<<endl;39. }40.41.42. int main(){43. char strFile[LENGTH_NAME_BMP];//bmp⽂件名44. IMAGEDATA *imagedata = NULL;//动态分配存储原图⽚的像素信息的⼆维数组45. IMAGEDATA *imagedataRot = NULL;//动态分配存储旋转后的图⽚的像素信息的⼆维数组46. int width,height;//图⽚的宽度和⾼度47. cout<<"请输⼊所要读取的⽂件名:"<<endl;48. cin>>strFile;49. FILE *fpi,*fpw;50. fpi=fopen(strFile,"rb");51. if(fpi != NULL){52. //先读取⽂件类型53. WORD bfType;54. fread(&bfType,1,sizeof(WORD),fpi);55. if(0x4d42!=bfType)56. {57. cout<<"the file is not a bmp file!"<<endl;58. return NULL;59. }60. //读取bmp⽂件的⽂件头和信息头61. fread(&strHead,1,sizeof(tagBITMAPFILEHEADER),fpi);62. //showBmpHead(strHead);//显⽰⽂件头63. fread(&strInfo,1,sizeof(tagBITMAPINFOHEADER),fpi);64. //showBmpInforHead(strInfo);//显⽰⽂件信息头65.66. //读取调⾊板67. for(unsigned int nCounti=0;nCounti68. {69. //存储的时候,⼀般去掉保留字rgbReserved70. fread((char *)&strPla[nCounti].rgbBlue,1,sizeof(BYTE),fpi);71. fread((char *)&strPla[nCounti].rgbGreen,1,sizeof(BYTE),fpi);72. fread((char *)&strPla[nCounti].rgbRed,1,sizeof(BYTE),fpi);73. cout<<"strPla[nCounti].rgbBlue"<<strPla[nCounti].rgbBlue<<endl;74. cout<<"strPla[nCounti].rgbGreen"<<strPla[nCounti].rgbGreen<<endl;75. cout<<"strPla[nCounti].rgbRed"<<strPla[nCounti].rgbRed<<endl;76. }77.78. width = strInfo.biWidth;79. height = strInfo.biHeight;80. imagedata = (IMAGEDATA*)malloc(width * height * sizeof(IMAGEDATA));81. imagedataRot = (IMAGEDATA*)malloc(2 * width * 2 * height * sizeof(IMAGEDATA));82. //初始化原始图⽚的像素数组83. for(int i = 0;i < height;++i)84. {85. for(int j = 0;j < width;++j)86. {87. (*(imagedata + i * width + j)).blue = 0;88. (*(imagedata + i * width + j)).green = 0;89. (*(imagedata + i * width + j)).red = 0;90. }91. }92. //初始化旋转后图⽚的像素数组93. for(int i = 0;i < 2 * height;++i)94. {95. for(int j = 0;j < 2 * width;++j)96. {97. (*(imagedataRot + i * 2 * width + j)).blue = 0;98. (*(imagedataRot + i * 2 * width + j)).green = 0;99. (*(imagedataRot + i * 2 * width + j)).red = 0;100. }101. }102. //fseek(fpi,54,SEEK_SET);103. //读出图⽚的像素数据104. fread(imagedata,sizeof(struct tagIMAGEDATA) * width,height,fpi);105.106. fclose(fpi);107. }108. else109. {110. cout<<"file open error!"<<endl;111. return NULL;112. }113.114. //图⽚旋转处理114. //图⽚旋转处理115. int RotateAngle;//要旋转的⾓度数116. double angle;//要旋转的弧度数117. int midX_pre,midY_pre,midX_aft,midY_aft;//旋转所围绕的中⼼点的坐标118. midX_pre = width / 2;119. midY_pre = height / 2;120. midX_aft = width;121. midY_aft = height;122. int pre_i,pre_j,after_i,after_j;//旋转前后对应的像素点坐标123. cout<<"输⼊要旋转的⾓度(0度到360度,逆时针旋转):"<<endl;124. cin>>RotateAngle;125. angle = 1.0 * RotateAngle * PI / 180;126. for(int i = 0;i < 2 * height;++i)127. {128. for(int j = 0;j < 2 * width;++j)129. {130. after_i = i - midY_aft;//坐标变换131. after_j = j - midX_aft;132. pre_i = (int)(cos((double)angle) * after_i - sin((double)angle) * after_j) + midY_pre;133. pre_j = (int)(sin((double)angle) * after_i + cos((double)angle) * after_j) + midX_pre;134. if(pre_i >= 0 && pre_i < height && pre_j >= 0 && pre_j < width)//在原图范围内135. *(imagedataRot + i * 2 * width + j) = *(imagedata + pre_i * width + pre_j);136. }137. }138.139. //保存bmp图⽚140. if((fpw=fopen("b.bmp","wb"))==NULL)141. {142. cout<<"create the bmp file error!"<<endl;143. return NULL;144. }145. WORD bfType_w=0x4d42;146. fwrite(&bfType_w,1,sizeof(WORD),fpw);147. //fpw +=2;148. fwrite(&strHead,1,sizeof(tagBITMAPFILEHEADER),fpw);149. strInfo.biWidth = 2 * width;150. strInfo.biHeight = 2 * height;151. fwrite(&strInfo,1,sizeof(tagBITMAPINFOHEADER),fpw);152. //保存调⾊板数据153. for(unsigned int nCounti=0;nCounti154. {155. fwrite(&strPla[nCounti].rgbBlue,1,sizeof(BYTE),fpw);156. fwrite(&strPla[nCounti].rgbGreen,1,sizeof(BYTE),fpw);157. fwrite(&strPla[nCounti].rgbRed,1,sizeof(BYTE),fpw);158. }159. //保存像素数据160. for(int i =0;i < 2 * height;++i)161. {162. for(int j = 0;j < 2 * width;++j)163. {164. fwrite( &(*(imagedataRot + i * 2 * width + j)).red,1,sizeof(BYTE),fpw);//注意三条语句的顺序:否则颜⾊会发⽣变化165. fwrite( &(*(imagedataRot + i * 2 * width + j)).green,1,sizeof(BYTE),fpw);166. fwrite( &(*(imagedataRot + i * 2 * width + j)).blue,1,sizeof(BYTE),fpw);167. }168. }169. fclose(fpw);170.171. //释放内存172. delete[] imagedata;173. delete[] imagedataRot;174. }转⾃CSDN 江南烟⾬博客在此表⽰感谢。

bmp图像读取源代码

BOOL CBmp::loadBitmapFile(CStringpath,CBitmap&bitmap){CFile file;if( !file.Open(path, CFile::modeRead) )return FALSE;BITMAPFILEHEADER bmfHeader;long fileLen = file.GetLength();if(file.Read(&bmfHeader,sizeof(bmfHeader)) !=sizeof(bmfHeader))return FALSE;if(bmfHeader.bfType != 0x4d42)return FALSE;HGLOBAL hDIB = ::GlobalAlloc(GMEM_FIXED,fileLen);if(hDIB == 0)return FALSE;if(file.Read(hDIB,fileLen -sizeof(BITMAPFILEHEADER)) !=fileLen - sizeof(BITMAPFILEHEADER) ){::GlobalFree(hDIB);return FALSE;}BITMAPINFO &bmInfo =*(LPBITMAPINFO)::GlobalLock(hDIB);BITMAPINFOHEADER *pInfoHead = (BITMAPINFOHEADER *)hDIB;int headerSize = sizeof(BITMAPINFOHEADER);BYTE *pBmpPixelBuffer=(BYTE*)&bmInfo+bmfHeader.bfOffBits –sizeof(BITMAPFILEHEADER);CDC dc;dc.CreateDC("DISPLAY",NULL,NULL,NULL);HBITMAP hBitmap;hBitmap =CreateDIBitmap(dc.m_hDC,(BITMAPINFOHEADER*)&bmInfo,CBM_INIT,(VOID*)pBmpPixelBuffer,&bmInfo,DI B_RGB_COLORS);bitmap.Attach(hBitmap);::GlobalUnlock (hDIB);::GlobalFree(hDIB);return TRUE;throw(gcnew System::NotImplementedException);}BOOL CBmp::bmpSave(CBitmap& m_bitmap, CString filename){BITMAP bm;m_bitmap.GetBitmap(&bm);int nWidth = bm.bmWidth;//每行的像素数int nHeight = bm.bmHeight;//列的像素数int nLineBits = bm.bmWidthBytes;//每行的像素数if ((nLineBits % 4) != 0)nLineBits += 4 - nLineBits%4;int nBitCounts = nLineBits * bm.bmHeight;int nBits = bm.bmBitsPixel;//每个像素的位数int nBitmapinfoSize = 0;if(nBits <= 8){int nColor = 1 << nBits;int nPalUnitSize = sizeof(RGBQUAD);nBitmapinfoSize = sizeof(BITMAPINFOHEADER) + nPalUnitSize * nColor;}elsenBitmapinfoSize = sizeof(BITMAPINFOHEADER);BITMAPINFO *pbmpinfo = NULL;pbmpinfo = (BITMAPINFO*)(newBYTE[nBitmapinfoSize]);ZeroMemory((void *)pbmpinfo,nBitmapinfoSize);//将该段内存中的值初始化为BITMAPINFOHEADER *pInfoHeader = (BITMAPINFOHEADER*)pbmpinfo;//BITMAPINFOHEADER的首地址与BITMAPINFO相同ZeroMemory((void*)pInfoHeader,sizeof(BITMAPINFOHEADE R));pInfoHeader->biSize = sizeof(BITMAPINFOHEADER); pInfoHeader->biWidth = nWidth;pInfoHeader->biBitCount = nBits;pInfoHeader->biPlanes = 1;pInfoHeader->biSizeImage = nBitCounts;pInfoHeader->biCompression = BI_RGB;pInfoHeader->biHeight = nHeight;CDC dc;dc.CreateDC("DISPLAY",NULL,NULL,NULL);int nLx = dc.GetDeviceCaps (LOGPIXELSX);int nLy = dc.GetDeviceCaps (LOGPIXELSY);double dbInchPerMeter = 39.375;int nPMx = (int)((double)nLx * dbInchPerMeter);int nPMy = (int)((double)nLy * dbInchPerMeter);pInfoHeader->biXPelsPerMeter = nPMx;pInfoHeader->biYPelsPerMeter = nPMy;if(nBits <= 8){int nColors = 1 << nBits;GetDIBColorTable(dc.m_hDC,0,nColors,pbmpinfo->bmiCol ors);}BYTE* pBits = NULL;HGLOBAL hGlobal= ::GlobalAlloc(GMEM_FIXED,nBitCounts);//存储BITMAPINFO结构体pBits = (BYTE*)::GlobalLock(hGlobal);ZeroMemory((void*)pBits,nBitCounts);GetDIBits(dc.m_hDC,(HBITMAP)m_bitmap,0,nHeight,pBits ,pbmpinfo,DIB_RGB_COLORS);BITMAPFILEHEADER bmfHeader;int nFileHeadSize = sizeof(BITMAPFILEHEADER);ZeroMemory((void*)&bmfHeader,sizeof(BITMAPFILEHEADER ));bmfHeader.bfType = 0x4d42;bmfHeader.bfSize = nFileHeadSize + nBitmapinfoSize + nBitCounts;bmfHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + nBitmapinfoSize;CFile savetoFile;if(!savetoFile.Open(filename,CFile::modeCreate| CFile::modeWrite))return FALSE;savetoFile.Write(&bmfHeader,sizeof(BITMAPFILEHEADER) );savetoFile.Write(pbmpinfo,nBitmapinfoSize);savetoFile.Write(pBits,nBitCounts);savetoFile.Close();::GlobalUnlock(hGlobal);::GlobalFree(hGlobal);delete[]pbmpinfo;return TRUE;}。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
相关文档
最新文档