bmp数据提取
- bmp格式文件的解析


关于bitmap文件格式
https://blog.csdn.net/huanggengxing/article/details/82529221 https://blog.csdn.net/gx19862005/article/details/22513249 https://blog.51cto.com/redwolf/22909
bmp图片每一行数据都要是4的整数倍,不是则后面补0以满足

- bmp格式文件第一个数据是图片的左下角
- 每一行数据的宽度都向4取整
缩放
- 图片缩放涉及一定的算法
- 近值取样插值算法

/* 首先定义图像数据结构 */typedef unsigned char TUInt8; // [0..255]struct TARGB32 //32 bit color{TUInt8 B,G,R,A; // A is alpha};struct TPicRegion //一块颜色数据区的描述,便于参数传递{TARGB32* pdata; //颜色数据首地址long byte_width; //一行数据的物理宽度(字节宽度);//abs(byte_width)有可能大于等于width*sizeof(TARGB32), bmp文件一行数据宽度要4字节对齐;long width; //像素宽度long height; //像素高度};//那么访问一个点的函数可以写为:inline TARGB32& Pixels(const TPicRegion& pic,const long x,const long y){return ( (TARGB32*)((TUInt8*)pic.pdata+pic.byte_width*y) )[x];}//---------------------------------------------------------------------/* 插值算法3 ZOOM* Dst : 目的区域* Src : 源区域*/void PicZoom3(const TPicRegion& Dst,const TPicRegion& Src){if ( (0==Dst.width)||(0==Dst.height)||(0==Src.width)||(0==Src.height)) return;unsigned long xrIntFloat_16=(Src.width<<16)/Dst.width+1;unsigned long yrIntFloat_16=(Src.height<<16)/Dst.height+1;unsigned long dst_width=Dst.width;TARGB32* pDstLine=Dst.pdata;unsigned long srcy_16=0;for (unsigned long y=0;y<Dst.height;++y){TARGB32* pSrcLine=((TARGB32*)((TUInt8*)Src.pdata+Src.byte_width*(srcy_16>>16)));unsigned long srcx_16=0;for (unsigned long x=0;x<dst_width;++x){pDstLine[x]=pSrcLine[srcx_16>>16];srcx_16+=xrIntFloat_16;}srcy_16+=yrIntFloat_16;((TUInt8*&)pDstLine)+=Dst.byte_width;}}
/* 定点数的方法来优化除法运算 */void PicZoom2( const TPicRegion& Dst, const TPicRegion& Src){if ( (0==Dst.width)||(0==Dst.height)||(0==Src.width)||(0==Src.height)) return;//函数能够处理的最大图片尺寸65536*65536unsigned long xrIntFloat_16=(Src.width<<16)/Dst.width+1; //16.16格式定点数unsigned long yrIntFloat_16=(Src.height<<16)/Dst.height+1; //16.16格式定点数//可证明: (Dst.width-1)*xrIntFloat_16<Src.width成立for (unsigned long y=0;y<Dst.height;++y){for (unsigned long x=0;x<Dst.width;++x){unsigned long srcx=(x*xrIntFloat_16)>>16;unsigned long srcy=(y*yrIntFloat_16)>>16;Pixels(Dst,x,y)=Pixels(Src,srcx,srcy);}}}
/* 交换x,y循环的顺序, 以按照颜色数据在内存中的排列顺序读写 */void PicZoom1(const TPicRegion& Dst,const TPicRegion& Src){if ( (0==Dst.width)||(0==Dst.height)||(0==Src.width)||(0==Src.height)) return;for (long y=0;y<Dst.height;++y){for (long x=0;x<Dst.width;++x){long srcx=(x*Src.width/Dst.width);long srcy=(y*Src.height/Dst.height);Pixels(Dst,x,y)=Pixels(Src,srcx,srcy);}}}
//Src.PColorData指向源数据区,Dst.PColorData指向目的数据区//函数将大小为Src.Width*Src.Height的图片缩放到Dst.Width*Dst.Height的区域中void PicZoom0(const TPicRegion& Dst,const TPicRegion& Src){if ( (0==Dst.width)||(0==Dst.height)||(0==Src.width)||(0==Src.height)) return;for (long x=0;x<Dst.width;++x){for (long y=0;y<Dst.height;++y){/* 计算目标区域中的每一点对应的源区域位置 */long srcx=(x*Src.width/Dst.width);long srcy=(y*Src.height/Dst.height);/* 将源区域位置像素赋值给目标区域对应位置 */Pixels(Dst,x,y)=Pixels(Src,srcx,srcy);}}}

