如何旋转位图(HBITMAP),高分请教

wh_peng 2008-10-24 07:59:43
加精
如题,
不知道有没有什么现成的函数?
有什么好的资料吗?
先谢谢了
...全文
1637 33 打赏 收藏 转发到动态 举报
写回复
用AI写文章
33 条回复
切换为时间正序
请发表友善的回复…
发表回复
wxbplc 2011-11-27
  • 打赏
  • 举报
回复
师傅们,我是菜鸟,多多指导。谢谢!
ruf 2011-11-24
  • 打赏
  • 举报
回复
从3D光栅扫描角度来说,一张图片对应两个三角形拼接,每个顶点对应纹理坐标,做sin,cos的运算值需要对顶点的变换就OK,剩下就是对三角形进行光栅扫描过程,插值出纹理坐标,然后根据uv值到图片中取rgb值,这里可以优化的是插值过程将浮点运算专程整形运算~<<16位[Quote=引用 31 楼 kfheimao 的回复:]

引用 30 楼 lovewhatilove 的回复:
厉害个飞机,1秒钟旋转一个这么小得图片,我的一秒旋转800*480都能打到13+帧,而且是667arm cup~

引用 16 楼 seven_zhangxw 的回复:

引用 15 楼 wh_peng 的回复:
经过优化,速度大大提高了,
500*400的图片1秒了,2592*3800的也才3秒左右

再次感谢nbcool……
[/Quote]
ruf 2011-11-23
  • 打赏
  • 举报
回复
厉害个飞机,1秒钟旋转一个这么小得图片,我的一秒旋转800*480都能打到13+帧,而且是667arm cup~[Quote=引用 16 楼 seven_zhangxw 的回复:]

引用 15 楼 wh_peng 的回复:
经过优化,速度大大提高了,
500*400的图片1秒了,2592*3800的也才3秒左右

再次感谢nbcool BEYONDMA


这两个人很厉害,很佩服。。。学习了。
[/Quote]
kfheimao 2011-11-23
  • 打赏
  • 举报
回复
[Quote=引用 30 楼 lovewhatilove 的回复:]
厉害个飞机,1秒钟旋转一个这么小得图片,我的一秒旋转800*480都能打到13+帧,而且是667arm cup~

引用 16 楼 seven_zhangxw 的回复:

引用 15 楼 wh_peng 的回复:
经过优化,速度大大提高了,
500*400的图片1秒了,2592*3800的也才3秒左右

再次感谢nbcool BEYONDMA


这两个人很厉害,很佩服。。。……
[/Quote]

晕,那你倒是发出来看看啊
orochi717 2011-11-22
  • 打赏
  • 举报
回复
1. float 转换为 fixed (定点浮点型), fixed运算相当于整数运算,整数运算比浮点运算快很多
2. newImage[newWidth*(i)+j] 这个地方,每次多了一个乘法运算和加法, newWidth*(i) 优化。
比如: (没有测试,只是提供思路)
     // 优化乘法 1
int xTmp = newWidth;
for(int i = 0; i < newHeight; i++)
{
for(int j = 0; j < newWidth; j++)
{
// 省略100字。。。
newImage[xTmp +j]=255;
}
xTmp += newWidth;
}

// 优化乘法 和 加法(大叔你知不知道i++比++i慢一倍)
int xTmp = newWidth;
for(int i = 0; i < newHeight; ++i)
{
uchar* pTmp = newImage + xTmp;
for(int j = 0; j < newWidth; ++j)
{
// 省略100字。。。
*pTmp =255;
++pTmp;
}
xTmp += newWidth;
}

3. 旋转的图可以保留下来,下次发现有度数接近就用保存下来的。
4. 如果不做3, 可以做内存池,没必要每次旋转图片new。
还有现在图形旋转都是 从目标图找原图的像素然后做 两次线性(当然线性算法可以)。
看你用的是基本最近距离的算法,结果是旋转出来的图很不好看,如果你用两次线性会更慢
dzq138 2011-11-19
  • 打赏
  • 举报
回复
就是浮点换整数,内存换速度的优化技术,网上到处都是-_-0

1.对于0,90,180,270,360之类的角度,何必再去调用sin cos等函数计算位置?直接用整数值代替就行了,你不觉得调用数字计算比调用函数会快一点吗,何况要调用500x400x3次?

2.类似取sin(1)~sin(360)之类的公式,完全可以用一个360个元素的整数数组替代。浮点可采用近似整数值替代或者用更好的转整数算法。

3.内存操作优化。

4.流水线优化。

5.函数级优化

等等还有很多地方可以优化,没事多看书吧,写软件没看过内存及代码优化技术的书是不行的。
Qqwwee_Com 2011-11-19
  • 打赏
  • 举报
回复
5楼的方法不错,


。。。。。。。。。。。。。

个性签名:我的梦想因安卓而开始,因csdn而丰富而充实
ruf 2011-11-17
  • 打赏
  • 举报
回复
800*480图片测试为13.xxxx帧,arm cpu(三星6410,降频667来用的,而且后台有程序在运行状态下)~

精简的3D流程,支持各种旋转,放缩,移动等操作~

你的问题在你的扫描算法上面~
dreamice01 2008-11-04
  • 打赏
  • 举报
回复
牛B
dandelionl 2008-11-04
  • 打赏
  • 举报
回复
mark
nhscorpio 2008-11-04
  • 打赏
  • 举报
回复
学习一下
ljooo 2008-11-03
  • 打赏
  • 举报
回复
刚才在另一个函数修改的,可能有些错误。
image是原图的数据,newImage是旋转后的图,调用前未分配空间,在Rotate里分配。fRotateAngle是旋转的弧度。

void Rotate(uchar *image,int width,int height,uchar *&newImage, int &newWidth,int &newHeight, float fRotateAngle)
{

// 旋转角度的正弦和余弦
float fSina, fCosa;
// 两个中间常量
float f1,f2;
// 象素在源DIB中的坐标
int i0;
int j0;

// 源图四个角的坐标(以图像中心为坐标系原点)
float fSrcX1,fSrcY1,fSrcX2,fSrcY2,fSrcX3,fSrcY3,fSrcX4,fSrcY4;

// 旋转后四个角的坐标(以图像中心为坐标系原点)
float fDstX1,fDstY1,fDstX2,fDstY2,fDstX3,fDstY3,fDstX4,fDstY4;


// 计算旋转角度的正弦
fSina = (float) sin((double)fRotateAngle);

// 计算旋转角度的余弦
fCosa= (float) cos((double)fRotateAngle);

// 计算原图的四个角的坐标(以图像中心为坐标系原点)
fSrcX1 = (float) (- (width - 1) / 2);
fSrcY1 = (float) ( (height - 1) / 2);
fSrcX2 = (float) ( (width - 1) / 2);
fSrcY2 = (float) ( (height - 1) / 2);
fSrcX3 = (float) (- (width - 1) / 2);
fSrcY3 = (float) (- (height - 1) / 2);
fSrcX4 = (float) ( (width - 1) / 2);
fSrcY4 = (float) (- (height - 1) / 2);

// 计算新图四个角的坐标(以图像中心为坐标系原点)
fDstX1 = fCosa * fSrcX1 + fSina * fSrcY1;
fDstY1 = -fSina * fSrcX1 + fCosa * fSrcY1;
fDstX2 = fCosa * fSrcX2 + fSina * fSrcY2;
fDstY2 = -fSina * fSrcX2 + fCosa * fSrcY2;
fDstX3 = fCosa * fSrcX3 + fSina * fSrcY3;
fDstY3 = -fSina * fSrcX3 + fCosa * fSrcY3;
fDstX4 = fCosa * fSrcX4 + fSina * fSrcY4;
fDstY4 = -fSina * fSrcX4 + fCosa * fSrcY4;

// 计算旋转后的图像实际宽度
newWidth = (int) ( max( fabs(fDstX4 - fDstX1), fabs(fDstX3 - fDstX2) ) + 0.5);
// 计算旋转后的图像高度
newHeight = (int) ( max( fabs(fDstY4 - fDstY1), fabs(fDstY3 - fDstY2) ) + 0.5);

//int length= newWidth* newHeight;
newImage=new uchar[ newWidth* newHeight];

// 两个常数,这样不用以后每次都计算了
f1 = (float) (-0.5 * (newWidth - 1) * fCosa - 0.5 * (newHeight - 1) * fSina
+ 0.5 * (width - 1));
f2 = (float) ( 0.5 * (newWidth - 1) * fSina - 0.5 * (newHeight - 1) * fCosa
+ 0.5 * (height - 1));

// 针对图像每行进行操作
for(int i = 0; i < newHeight; i++)
{
// 针对图像每列进行操作
for(int j = 0; j < newWidth; j++)
{


// 计算该象素在源DIB中的坐标
i0 = int(-((float) j) * fSina + ((float) i) * fCosa + f2+0.5);
j0 = int(((float) j) * fCosa + ((float) i) * fSina + f1+0.5);

if( (i0 < 0) || (j0 > width - 1) || (j0 < 0) || (i0 > height - 1))
{
// 要计算的点不在源图范围内,直接返回255。
newImage[newWidth*(i)+j]=255;
}
else
newImage[newWidth* (i) +j]=image[width*(i0)+j0];
}
}



}
ljooo 2008-11-03
  • 打赏
  • 举报
回复
你发错版了。
正确是 “图形图像/机器视觉删除”或 “VC/MFC删除/图形处理/算法添加”。
图像旋转是很基本的操作,像500*400这种小图像应该在1-3ms之间。
dongyi940333 2008-11-03
  • 打赏
  • 举报
回复
学习了^_^
cmouse 2008-11-03
  • 打赏
  • 举报
回复
学习。。。
overbill 2008-11-03
  • 打赏
  • 举报
回复
我做过图片旋转,用指针很快的
wh_peng 2008-10-30
  • 打赏
  • 举报
回复
经过优化,速度大大提高了,
500*400的图片1秒了,2592*3800的也才3秒左右

再次感谢nbcool BEYONDMA

wh_peng 2008-10-30
  • 打赏
  • 举报
回复
谢谢 nbcool BEYONDMA
我优化优化看先
beyondma 2008-10-30
  • 打赏
  • 举报
回复
我把NBCOOL老大的话补充说明一下:)你就是用一张有360个元素的表代替SIN COS的运算,比如你求SIN(1)的话就直接查表了,而不是用math.h当中的SIN去算:)然后看下有关的资料是不是并根据相应的情况,看看到底是内存重要还是效率重要。做下优化。
另外提醒一下,尽量不要过于频繁的NEW DELETE,那样内存碎片太多,反而不好。
Seven_zhangxw 2008-10-30
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 wh_peng 的回复:]
经过优化,速度大大提高了,
500*400的图片1秒了,2592*3800的也才3秒左右

再次感谢nbcool BEYONDMA
[/Quote]

这两个人很厉害,很佩服。。。学习了。
加载更多回复(12)

19,502

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 嵌入开发(WinCE)
社区管理员
  • 嵌入开发(WinCE)社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧