现在的位置: 首页 > 综合 > 正文

ARM 图片任意角度旋转效果——liuwei 同志写的系统,很强大

2012年02月13日 ⁄ 综合 ⁄ 共 3422字 ⁄ 字号 评论关闭

硬件平台: S3C2440 + 4.3寸TFT(480x272) 

旋转算法: 

void RotateImage(HDC hdc,int x,int y,HIMG hImg,int angle)  
{ 
S32 radians;  
S32 cos_a,sin_a,cos_ay,sin_ay;  
S32 point1x,point1y,point2x,point2y,point3x,point3y; 
S32 minx,miny,maxx,maxy; 
S32 xx,yy,xx0,yy0,xx1,yy1,cx,cy,src_dx,src_dy,dst_dx,dst_dy;  
GUI_COLOR color; 
IMAGE *img; 
DC *pdc; 
/////////// 
//算法优化思路:小数除法->整数除法->乘法->加法 

if(hdc==0) return; 
pdc =HDC2DC(hdc); 

if(hImg==0) return; 
img=(void*)hImg; 

src_dx =img->Width; 
src_dy =img->Height; 
angle %=360; 

//计算外接矩形坐标 
radians =(2*PI*angle)/360.0; 
cos_a =COS(radians)*65536.0; 
sin_a =SIN(radians)*65536.0; 
point1x =(-src_dy*sin_a)>>16; 
point1y =(src_dy*cos_a)>>16; 
point2x =(src_dx*cos_a-src_dy*sin_a)>>16; 
point2y =(src_dy*cos_a+src_dx*sin_a)>>16; 
point3x =(src_dx*cos_a)>>16; 
point3y =(src_dx*sin_a)>>16; 


minx =MIN(0,MIN(point1x,MIN(point2x,point3x))); 
miny =MIN(0,MIN(point1y,MIN(point2y,point3y))); 

maxx =MAX(point1x,MAX(point2x,point3x));  
maxy =MAX(point1y,MAX(point2y,point3y)); 

if(angle>90&&angle<180)  
{ 
dst_dx=(int)CEIL(-minx);  
} 
else  
{ 
dst_dx=(int)CEIL(maxx-minx);  
} 

if(angle>180&&angle<270)  
{ 
dst_dy=(int)CEIL(-miny);  
} 
else  
{ 
dst_dy=(int)CEIL(maxy-miny); 
}  

cx =(dst_dx>>1); //目标位置中心点的x偏移 
cy =(dst_dy>>1); //目标位置中心点的y偏移 


cos_ay =(miny*cos_a)>>16; 
sin_ay =(miny*sin_a)>>16; 
//////////// 

if(((IMAGE*)hImg)->Bpp==32) 
{ 

//ARGB 8888格式(带Alpha通道) 
for(yy=0;yy<dst_dy;yy++) 
{  
cos_ay =((yy+miny)*cos_a)>>16; 
sin_ay =((yy+miny)*sin_a)>>16; 
//// 
yy0 =y+yy-cy; 

if(yy0<0) continue; 
if(yy0>pdc->ymax) return; 

for(xx=0;xx<dst_dx;xx++)  
{  

//// 
xx1 =((((xx+minx)*cos_a)>>16)+sin_ay); //计算坐标  
yy1 =(cos_ay-(((xx+minx)*sin_a)>>16));  
//// 

xx0 =x+xx-cx; 

if(xx1>=0&&xx1<src_dx&&yy1>=0&&yy1<src_dy&&xx0>0&&xx0<pdc->xmax)   
{  

color =img->Data[yy1*img->Width+xx1]; 

pdc->PutPixel(pdc,xx0,yy0,AlphaBlendColor(color,GetPixel(hdc,xx0,yy0),img->AlphaData[yy1*img->Width+xx1])); 
}  
}  
}  
} 
else 
{ 
//其它格式(不带Alpha通道) 
for(yy=0;yy<dst_dy;yy++) 
{  
cos_ay =((yy+miny)*cos_a)>>16; 
sin_ay =((yy+miny)*sin_a)>>16; 
//// 
yy0 =y+yy-cy; 
if(yy0<0) continue; 
if(yy0>pdc->ymax) return; 

for(xx=0;xx<dst_dx;xx++)  
{  

//// 
xx1 =((((xx+minx)*cos_a)>>16)+sin_ay); //计算坐标  
yy1 =(cos_ay-(((xx+minx)*sin_a)>>16));  
//// 

xx0 =x+xx-cx; 

if(xx1>=0&&xx1<src_dx&&yy1>=0&&yy1<src_dy&&xx0>0&&xx0<pdc->xmax) 
{  

pdc->PutPixel(pdc,xx0,yy0,img->Data[yy1*img->Width+xx1]); 
}  
}  
}  
} 

//// 



}

测试程序: 

void TestRotateImage(void) 
{ 
U32 hfile,himg,angle,frame,width,height; 
char key,str_buf[64]; 
U8 *buf; 
HDC hdc; 
COORD x,y; 
//// 

hdc=CreateDC(0,0,ScrWidth(),ScrHeight()-40); //创建设备上下文 
angle=0; 
while(1) 
{ 
hfile=FILE_INVALID; 
while(hfile==FILE_INVALID) 
{ 
DbgUart_Printf("Enter Bmp File Name:\n"); 
if(DbgUart_Gets(str_buf,64)) //输入目标文件名 
{ 
hfile=FileOpen(str_buf,"rw"); 
} 
else 
{ 
ReleaseDC(hdc); 
return; 
} 

} 
//// 
DbgUart_Printf("File Size =%d Byte\n",GetFileSize(hfile)); 

buf=MemAlloc(GetFileSize(hfile)); 
FileRead(buf,GetFileSize(hfile),hfile); 
FileClose(hfile); 
//// 
himg=BmpToImage(buf); //Bmp解码 

MemFree(buf); 

width =((IMAGE*)himg)->Width; 
height =((IMAGE*)himg)->Height; 
DbgUart_Printf("Image Width=%d,Height=%d\n",width,height); 

ThreadLock(); //关线程调度(不关中断) 

x=ScrWidth()>>1; 
y=ScrHeight()>>1; 
while(1) 
{ 
int i; 
char str_buf[32]; 
//// 
i =0; 
angle =0; 
frame =0; 
SetSysTime(0); //设置系统时间 

while(i<10) 
{ 

  RotateImage(hdc,x,y,himg,angle); 

  angle+=5; //角度每次增加5度 
  frame++; //帧计数 
  if(angle>=360) 
  { 
  angle=0; 
  i++; 
  } 
  
  //// 
  key=0; 
  if(DbgUart_Getch(&key)) 
  { 
  if(key==0x1b) goto ret; 
  } 

  
  } 
  //// 
  
  i=GetSysTime(); 
  StrPrintf(str_buf,"RotateImage 测试(%d*%d):Tick数=%d,时间=%d秒,帧数=%d,平均:%d帧/秒",width,height,i,i/TicksPerSec(),frame,(frame*TicksPerSec())/i); 
  Label(HDC_SCREEN,0,ScrHeight()-40,ScrWidth(),40,RGB(200,0,0),RGB(200,200,200),RGB(0,0,0),LEFT,str_buf); 

  } 
  

} 

ret: 
ThreadUnlock(); //恢复线程调度 
  ReleaseImage(himg); //释放资源 
  ReleaseDC(hdc); 

}

抱歉!评论已关闭.