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

wonitaluck   2008-10-24 19:59 楼主
如题,
不知道有没有什么现成的函数?
有什么好的资料吗?
先谢谢了

回复评论 (25)

IImage
点赞  2008-10-24 22:31
旋转算法到处都是,你直接转DIB就行了。
点赞  2008-10-27 09:33
这么少人
点赞  2008-10-27 09:38
少人是因为你这问题实在没啥意思。

这种问题,在网上搜索一下,有几千个答案。
点赞  2008-10-28 10:43
没有现成的函数,算法和代码到处都有
点赞  2008-10-28 11:35
引用: 引用 5 楼 guetcw 的回复:
没有现成的函数,算法和代码到处都有
记号。
点赞  2008-10-28 11:41
引用: 引用 4 楼 yashi 的回复:
少人是因为你这问题实在没啥意思。

这种问题,在网上搜索一下,有几千个答案。

----------------------------------
但是那些算法效率太低了,我旋转一个500x400的图片要6,7秒啊,
这么慢远远达不到要求
我想问的是有没有高效的算法
点赞  2008-10-28 11:47
你用函数PlgBlt()你自己看看函数传入的3个POINT点参数不同就可以达到旋转的效果的 不过精确度一般
点赞  2008-10-28 13:46
引用: 引用 7 楼 wh_peng 的回复:
引用 4 楼 yashi 的回复:
少人是因为你这问题实在没啥意思。

这种问题,在网上搜索一下,有几千个答案。

----------------------------------
但是那些算法效率太低了,我旋转一个500x400的图片要6,7秒啊,
这么慢远远达不到要求
我想问的是有没有高效的算法


你的意思是这样吗?那是你懒得把问题写清楚,还是你写了,我没看出来?
点赞  2008-10-28 14:21
引用: 引用 7 楼 wh_peng 的回复:
引用 4 楼 yashi 的回复:
少人是因为你这问题实在没啥意思。

这种问题,在网上搜索一下,有几千个答案。

----------------------------------
但是那些算法效率太低了,我旋转一个500x400的图片要6,7秒啊,
这么慢远远达不到要求
我想问的是有没有高效的算法


算法你自己不会改一下啊,那么小的图,根本不用6,7秒。要点就是采用整数运算。
点赞  2008-10-29 14:22
引用: 引用 10 楼 nbcool 的回复:
引用 7 楼 wh_peng 的回复:
引用 4 楼 yashi 的回复:
少人是因为你这问题实在没啥意思。

这种问题,在网上搜索一下,有几千个答案。

----------------------------------
但是那些算法效率太低了,我旋转一个500x400的图片要6,7秒啊,
这么慢远远达不到要求
我想问的是有没有高效的算法


算法你自己不会改一下啊,那么小的图,根本不用6,7秒。要点就是采用整数运算。

------------------------------------------------------------------
怎样采用整数运算?可以详细点说吗?我不太理解,谢谢了
点赞  2008-10-29 18:11
就是浮点换整数,内存换速度的优化技术,网上到处都是-_-0

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

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

3.内存操作优化。

4.流水线优化。

5.函数级优化

等等还有很多地方可以优化,没事多看书吧,写软件没看过内存及代码优化技术的书是不行的。

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

再次感谢nbcool BEYONDMA

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

再次感谢nbcool BEYONDMA


这两个人很厉害,很佩服。。。学习了。
点赞  2008-10-30 19:52
你发错版了。
正确是 “图形图像/机器视觉删除”或 “VC/MFC删除/图形处理/算法添加”。
图像旋转是很基本的操作,像500*400这种小图像应该在1-3ms之间。
点赞  2008-11-3 12:21
刚才在另一个函数修改的,可能有些错误。
image是原图的数据,newImage是旋转后的图,调用前未分配空间,在Rotate里分配。fRotateAngle是旋转的弧度。

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

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

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

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


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

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

  18.                 // 计算原图的四个角的坐标(以图像中心为坐标系原点)
  19.                 fSrcX1 = (float) (- (width  - 1) / 2);
  20.                 fSrcY1 = (float) (  (height - 1) / 2);
  21.                 fSrcX2 = (float) (  (width  - 1) / 2);
  22.                 fSrcY2 = (float) (  (height - 1) / 2);
  23.                 fSrcX3 = (float) (- (width  - 1) / 2);
  24.                 fSrcY3 = (float) (- (height - 1) / 2);
  25.                 fSrcX4 = (float) (  (width  - 1) / 2);
  26.                 fSrcY4 = (float) (- (height - 1) / 2);

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

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

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

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

  47.                 // 针对图像每行进行操作
  48.                 for(int i = 0; i < newHeight; i++)
  49.                 {
  50.                         // 针对图像每列进行操作
  51.                         for(int j = 0; j < newWidth; j++)
  52.                         {


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

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



  65. }
点赞  2008-11-3 12:31
我做过图片旋转,用指针很快的
点赞  2008-11-3 13:31
12下一页
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复