首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 .NET Java 游戏 视频 人才 外包 第二书店 程序员
您的位置:Mobile->J2me中任意角度图片旋转(三)

J2me中任意角度图片旋转(三)2007-09-22 来自:lizhe1985  [收藏到我的网摘]

作者:pandonix

日期:2007年9月20日

版权声明:可以任意转载,转载时请务必以超链接形式标明文章原始出处和作者信息及本声明

原文地址:

http://pandonix.javaeye.com/

  本文主要讨论在J2me中如何实现任意角度的图片旋转。其实,早在几年前,minisoyou的BB就已经给出了实现算法,相信做j2me游戏开发的朋友们也都收藏过该算法。本文从图像旋转的基本理论出发,详细讨论如何使用实现和优化该算法,希望对旋转算法感兴趣的朋友有帮助。

  解决“坏点”

  仔细思考一下,坏点出现的主要原因在于,旋转公式的定义域是整个实数域,而像素点显然是离散点,因此,在进行映射时,会产生一定的误差,所以造成本该被定义的像素点,没有被映射到。其实,在图像处理领域,已经存在很多优化的算法,而且理论都基于数学的。

  回到我们的问题,为了解决坏点,我们可以这样来考虑:改遍历原图像数组为遍历newPixels数组,这样就能保证所有的newPixels可以被覆盖。具体代码如下:

java 代码
public static int[] rotate(int[] _pixels,int _width,int _height,double _angle)
{
int i,j;
double radius = Math.sqrt(_width*_width + _height*_height);
int r = (int)radius;
int[] newPixels = new int[r*r];
for(i = 0; i < newPixels.length; i++)
{
newPixels[i] = (TRANSPARENT)<<24;
}
double x1,y1;
int x2,y2;
double cos = Math.cos(_angle);
double sin = Math.sin(_angle);
for(i = 0; i < r; i++)
{
for(j = 0; j < r; j++)
{
x1 = j + (- r)/2;
y1 = i + (- r)/2;
x2 = (int)(x1*cos + y1*sin);
y2 = (int)(-x1*sin + y1*cos);
if(x2 >= -_width/2&&x2< _width/2&&y2 >= -_height/2&&y2< _height/2)
{
int k = (y2 + _height/2)*_width+x2+_width/2;

newPixels[i*r + j] = _pixels[k];
}
}
}
return newPixels;
}

  效果如图所示,基本上解决图像中的坏点,失真度基本可以接受。如果你觉得不符合要求,没关系,下面会介绍BB的算法。

  速度优化

  上面这种算法的时间复杂程度是O(n^2),那么对该算法是否可以优化呢?参考了《A Fast Algorithm for Rotating Bitmaps》一文,可以对算法作以下优化:

public static int[] rotate3(int[] _pixels,int _width,int _height,double _angle)
{
int i,j;
double radius = Math.sqrt(_width*_width + _height*_height);
int r = (int)radius;
int[] newPixels = new int[r*r];
for(i = 0; i < newPixels.length; i++)
{
newPixels[i] = (TRANSPARENT)<<24;
}
double x2,y2;
int x3,y3;
double cos = Math.cos(_angle);
double sin = Math.sin(_angle);
for(i = 0; i < r; i++)
{
x2 = (-r/2)*cos + (i - r/2)*sin;
y2 = (r/2)*sin + (i - r/2)*cos;
x3 = (int)x2;
y3 = (int)y2;
for(j = 0; j < r; j++)
{
if(x3 >= -_width/2&&x3< _width/2&&y3 >= -_height/2&&y3< _height/2)
{
newPixels[i*r +j] = _pixels[(y3 + _height/2)*_width+x3+_width/2];
}
x2 += cos;
y2 -= sin;
x3 = (int)x2;
y3 = (int)y2;
}
}
return newPixels;
}

  使用定点数实现

  其实,主要就是实现Sin和Cos的求值,基本思路是:将Sin和Cos值放大255倍,进行计算以后,对结果再进行缩小处理,具体请参考代码Rotation2.java

  BB的算法

  应该说,BB给出的算法的失真程度最小,他是对目标像素点进行了一个加权计算,但是,遗憾的是,翻阅了很多资料,我也没有找到该算法的相关理论介绍。若有朋友了解,请正解。具体代码请参考Rotation_4444.java

  总结与思考

  总的说来,旋转后的位图都存在不同情况的失真,所以在实际开发过程中,需要视情况而定。除此之外,不同的终端对于透明的不同,例如,K700在透明方面问题就比较多。

推荐人评论

本文主要讨论在J2me中如何实现任意角度的图片旋转。本文从图像旋转的基本理论出发,详细讨论如何使用实现和优化该算法,希望对旋转算法感兴趣的朋友有帮助。

用户评论

正在载入评论列表...

是谁推荐了此篇文章

专家头像李哲
个人blog发送信息
李哲推荐的其他文章

赞助商精华文章

热点新闻

热点评论

    精彩视频

    精彩专题

    网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|版权声明|问题报告

    北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
    世纪乐知(北京)网络技术有限公司 提供技术支持
    Copyright 2000-2008, CSDN.NET, All Rights Reserved
    GongshangLogo