zoukankan      html  css  js  c++  java
  • C/C++ BMP(24位真彩色)图像处理(2)------图像截取

    对上一篇博客《C/C++ BMP(24位真彩色)图像处理(1)------图像打开与数据区处理》的代码做小部分的修改,就可以进行BMP图像的截取操作,代码如下:

    #include <string.h> 
    #include <math.h>   
    #include <stdio.h>   
    #include <stdlib.h>   
    #include <malloc.h>
    
    #include<time.h>//时间相关头文件,可用其中函数计算图像处理速度
    
    #define   WIDTHBYTES(bits) (((bits)+31)/32*4)//用于使图像宽度所占字节数为4byte的倍数
    
    #define MYCUT_HEIGHT 100	//截取高度
    #define MYCUT_WIDTH 100		//截取宽度
    #define BEGIN_X 0			//截取位图开始位置X坐标
    #define BEGIN_Y 0			//截取位图开始位置Y坐标
    
    typedef unsigned char  BYTE;
    typedef unsigned short WORD;
    typedef unsigned long  DWORD;
    typedef long LONG;
    
    //位图文件头信息结构定义
    //其中不包含文件类型信息(由于结构体的内存结构决定,要是加了的话将不能正确读取文件信息)
    
    typedef struct tagBITMAPFILEHEADER {
    DWORD  bfSize;          //文件大小
    WORD   bfReserved1; 	//保留字,不考虑
    WORD   bfReserved2; 	//保留字,同上
    DWORD  bfOffBits;       //实际位图数据的偏移字节数,即前三个部分长度之和
    } BITMAPFILEHEADER; 
    
    //信息头BITMAPINFOHEADER,也是一个结构,其定义如下:
    
    typedef struct tagBITMAPINFOHEADER{
    //public:
    DWORD   biSize;         	//指定此结构体的长度,为40
    LONG    biWidth;       		//位图宽
    LONG    biHeight;       	//位图高
    WORD    biPlanes;       	//平面数,为1
    WORD    biBitCount;     	//采用颜色位数,可以是1,2,4,8,16,24,新的可以是32
    DWORD   biCompression;  	//压缩方式,可以是0,1,2,其中0表示不压缩
    DWORD   biSizeImage;    	//实际位图数据占用的字节数
    LONG    biXPelsPerMeter;	//X方向分辨率
    LONG    biYPelsPerMeter;	//Y方向分辨率
    DWORD   biClrUsed;      	//使用的颜色数,如果为0,则表示默认值(2^颜色位数)
    DWORD   biClrImportant; 	//重要颜色数,如果为0,则表示所有颜色都是重要的
    } BITMAPINFOHEADER; 
    
    void main()
    {
    	long now=0;
    	now=clock();//存储图像处理开始时间
    
    	BITMAPFILEHEADER bitHead,writebitHead;
    	BITMAPINFOHEADER bitInfoHead,writebitInfoHead; 
    	FILE* pfile;//输入文件
    	FILE* wfile;//输出文件
    
    	char strFile[50]="E:\testpicture\1.bmp";//打开图像路径,BMP图像必须为24位真彩色格式
    	char strFilesave[50]="E:\testpicture\2.bmp";//处理后图像存储路径
    	pfile = fopen(strFile,"rb");//文件打开图像
    	wfile = fopen(strFilesave,"wb");//打开文件为存储修改后图像做准备
    
    	//读取位图文件头信息
    	WORD fileType;
    	fread(&fileType,1,sizeof(WORD),pfile);
    	fwrite(&fileType,1,sizeof(WORD),wfile);
    	if(fileType != 0x4d42)
    	{
    		printf("file is not .bmp file!");
    		return;
    	}
    	//读取位图文件头信息
    	fread(&bitHead,1,sizeof(tagBITMAPFILEHEADER),pfile);
    	writebitHead=bitHead;//由于截取图像头和源文件头相似,所以先将源文件头数据赋予截取文件头
    	//读取位图信息头信息
    	fread(&bitInfoHead,1,sizeof(BITMAPINFOHEADER),pfile);
    	writebitInfoHead=bitInfoHead;//同位图文件头相似
    
    	writebitInfoHead.biHeight=MYCUT_HEIGHT;//为截取文件重写位图高度
    	writebitInfoHead.biWidth=MYCUT_WIDTH;//为截取文件重写位图宽度
    	int mywritewidth=WIDTHBYTES(writebitInfoHead.biWidth*writebitInfoHead.biBitCount);//BMP图像实际位图数据区的宽度为4byte的倍数,在此计算实际数据区宽度
    	writebitInfoHead.biSizeImage=mywritewidth*writebitInfoHead.biHeight;//计算位图实际数据区大小
    
    	writebitHead.bfSize=54+writebitInfoHead.biSizeImage;//位图文件头大小为位图数据区大小加上54byte
    	fwrite(&writebitHead,1,sizeof(tagBITMAPFILEHEADER),wfile);//写回位图文件头信息到输出文件
    	fwrite(&writebitInfoHead,1,sizeof(BITMAPINFOHEADER),wfile);//写回位图信息头信息到输出文件
    
    	int width = bitInfoHead.biWidth;
    	int height = bitInfoHead.biHeight;
    	//分配内存空间把源图存入内存   
    	int l_width = WIDTHBYTES(width*bitInfoHead.biBitCount);//计算位图的实际宽度并确保它为4byte的倍数
    	int write_width = WIDTHBYTES(writebitInfoHead.biWidth*writebitInfoHead.biBitCount);//计算写位图的实际宽度并确保它为4byte的倍数
    
    	BYTE    *pColorData=(BYTE *)malloc(height*l_width);//开辟内存空间存储图像数据
    	memset(pColorData,0,height*l_width);   
    
    	BYTE    *pColorDataMid=(BYTE *)malloc(mywritewidth*MYCUT_HEIGHT);//开辟内存空间存储图像处理之后数据
    	memset(pColorDataMid,0,mywritewidth*MYCUT_HEIGHT); 
    
    	long nData = height*l_width;
    	long write_nData = mywritewidth*MYCUT_HEIGHT;//截取的位图数据区长度定义
    	
    	//把位图数据信息读到数组里   
    	fread(pColorData,1,nData,pfile);//图像处理可通过操作这部分数据加以实现
    
    	//截取图像数据区操作,在操作过程中注意截取图像是否越界,可在此处加入代码进行越界处理
    	for(int hnum=height-BEGIN_Y-MYCUT_HEIGHT;hnum<height-BEGIN_Y;hnum++)//由于BMP图像的数据存储格式起点是图像的左下角,所以需要进行坐标换算操作
    		for(int wnum=BEGIN_X;wnum<BEGIN_X+MYCUT_WIDTH;wnum++)
    		{
    			int pixel_point=hnum*l_width+wnum*3;//数组位置偏移量,对应于图像的各像素点RGB的起点
    			int write_pixel_point=(hnum-height+BEGIN_Y+MYCUT_HEIGHT)*mywritewidth+(wnum-BEGIN_X)*3;
    			pColorDataMid[write_pixel_point]=pColorData[pixel_point];
    			pColorDataMid[write_pixel_point+1]=pColorData[pixel_point+1];
    			pColorDataMid[write_pixel_point+2]=pColorData[pixel_point+2];
    		}
    
    	fwrite(pColorDataMid,1,write_nData,wfile);   //将处理完图像数据区写回文件
    	fclose(pfile);
    	fclose(wfile);
    
    	printf("图像处理完成
    ");
    	printf("运行时间为:%dms
    ",int(((double)(clock()-now))/CLOCKS_PER_SEC*1000));//输出图像处理花费时间信息
    }
    
    





  • 相关阅读:
    我喜欢的女孩有了男友 :(
    两个月后,我又回来了。
    准备辞职,想看看老板知道我要辞职之后的表情。
    已经交了辞职报告,今天下午跟老板谈一谈。
    上班第十天
    一年了,回来看看。
    上班第十一天
    领到了离职通知单
    对上班失去了兴趣
    还没有拿到回家的火车票,惨了啊。
  • 原文地址:https://www.cnblogs.com/weixinhum/p/3916702.html
Copyright © 2011-2022 走看看