程序移植与 http://blog.csdn.net/housisong/archive/2006/12/21/1452249.aspx /* * Color32.h * * Created on: 2009-4-29 * Author: flashtao */ #ifndef COLOR32_H_ #define COLOR32_H_ //base type typedef char Int8; typedef unsigned char UInt8; typedef short Int16; typedef unsigned short UInt16; typedef long Int32; typedef unsigned long UInt32; //32bitARGB颜色类型 //16bit 应该是 565型的! struct Color32 { union { UInt16 rgb; struct { UInt16 b:5; UInt16 g:6; UInt16 r:5; }; }; inline Color32(){} inline Color32(const Color32& color32):rgb(color32.rgb){} inline explicit Color32(const UInt32 color32):rgb(color32){} inline bool operator ==(const Color32& color32) const { return rgb==color32.rgb; } inline bool operator !=(const Color32& color32) const{ return !((*this)==color32); } }; //图像数据区的描述信息 struct TPixels32Ref { public: Color32* pdata; //图像数据区首地址 即 y==0行的颜色首地址 long byte_width; //一行图像数据的字节宽度 正负值都有可能 long width; //图像宽度 long height; //图像高度 inline TPixels32Ref() :pdata(0),byte_width(0),width(0),height(0){} inline TPixels32Ref(const TPixels32Ref& ref) :pdata(ref.pdata),byte_width(ref.byte_width),width(ref.width),height(ref.height){} //访问(x,y)坐标处的颜色 inline Color32& pixels(const long x,const long y) const { return getLinePixels(y)[x]; } //得到y行的颜色首地址 inline Color32* getLinePixels(const long y) const { return (Color32*) ( ((UInt8*)pdata) + byte_width*y ); } //是否是空图像区 inline bool getIsEmpty()const { return ((width<=0)||(height<=0)); } //将pline指向下一行颜色 inline void nextLine(Color32*& pline)const { ((UInt8*&)pline)+=byte_width; } //坐标边界饱和 如果(x,y)坐标在图片数据区外,(x,y)值会被设置到图片最近的边界内,并返回false(否则什么也不做,返回true) //警告! 图片区域不能为空 inline bool clipToBorder(long& x, long& y)const { bool isIn = true; if (x < 0) { isIn = false; x = 0; } else if (x >= width) { isIn = false; x = width - 1; } if (y < 0) { isIn = false; y = 0; } else if (y >= height) { isIn = false; y = height - 1; } return isIn; } //获取一个点的颜色,默认执行边界饱和测试 当坐标超出区域的时候返回的颜色为最近的边界上的颜色值并且其alpha通道置零 //警告! 图片区域不能为空 速度很慢 inline Color32 getPixelsBorder(long x, long y) const { bool isInPic = clipToBorder(x,y); Color32 result = pixels(x,y); return result; } }; #endif /* COLOR32_H_ */ void CZoom16AppView::Zoom(CFbsBitmap* Dst, CFbsBitmap* src) { TPixels32Ref srcPic; TPixels32Ref dstPic; src->LockHeap(); srcPic.pdata=(Color32*)(src->DataAddress()); srcPic.width=src->SizeInPixels().iWidth; srcPic.height=src->SizeInPixels().iHeight; srcPic.byte_width=srcPic.width*sizeof(Color32); src->UnlockHeap(); Dst->LockHeap(); dstPic.pdata=(Color32*)(Dst->DataAddress()); dstPic.width=Dst->SizeInPixels().iWidth; dstPic.height=Dst->SizeInPixels().iHeight; dstPic.byte_width=dstPic.width*sizeof(Color32); Dst->UnlockHeap(); Dst->LockHeap(); src->LockHeap(); PicZoom_Bilinear0(dstPic,srcPic); // PicZoom_Bilinear1(dstPic,srcPic); // PicZoom_Bilinear2(dstPic,srcPic); src->UnlockHeap(); Dst->UnlockHeap(); } void CZoom16AppView::Bilinear1(const TPixels32Ref& pic,const long x_16,const long y_16,Color32* result) { long x=x_16>>16; long y=y_16>>16; Color32 Color0=pic.getPixelsBorder(x,y); Color32 Color2=pic.getPixelsBorder(x+1,y); Color32 Color1=pic.getPixelsBorder(x,y+1); Color32 Color3=pic.getPixelsBorder(x+1,y+1); unsigned long u_8=(x_16 & 0xFFFF)>>8; unsigned long v_8=(y_16 & 0xFFFF)>>8; unsigned long pm3_16=(u_8*v_8); unsigned long pm2_16=(u_8*(unsigned long)(255-v_8)); unsigned long pm1_16=(v_8*(unsigned long)(255-u_8)); unsigned long pm0_16=((255-u_8)*(255-v_8)); result->r=(UInt8)((pm0_16*Color0.r+pm1_16*Color1.r+pm2_16*Color2.r+pm3_16*Color3.r)>>16); result->g=(UInt8)((pm0_16*Color0.g+pm1_16*Color1.g+pm2_16*Color2.g+pm3_16*Color3.g)>>16); result->b=(UInt8)((pm0_16*Color0.b+pm1_16*Color1.b+pm2_16*Color2.b+pm3_16*Color3.b)>>16); } void CZoom16AppView::PicZoom_Bilinear1(const TPixels32Ref& Dst,const TPixels32Ref& Src) { if ( (0==Dst.width)||(0==Dst.height) ||(0==Src.width)||(0==Src.height)) return; long xrIntdouble_16=((Src.width)<<16)/Dst.width+1; long yrIntdouble_16=((Src.height)<<16)/Dst.height+1; const long csDErrorX=-(1<<15)+(xrIntdouble_16>>1); const long csDErrorY=-(1<<15)+(yrIntdouble_16>>1); long dst_width=Dst.width; Color32* pDstLine=Dst.pdata; long srcy_16=csDErrorY; long y; for (y=0;y<Dst.height;++y) { long srcx_16=csDErrorX; for (long x=0;x<dst_width;++x) { Bilinear1(Src,srcx_16,srcy_16,&pDstLine[x]); //border srcx_16+=xrIntdouble_16; } srcy_16+=yrIntdouble_16; ((UInt8*&)pDstLine)+=Dst.byte_width; } }