图像旋转算法

20

我正在寻找一种算法,可以将图像按照给定角度(输入)进行旋转。

public Image rotateImage(Image image, int degrees)

(可以用包含每个像素RGB值的int[]替换Image实例, 我的问题是我需要在JavaME MIDP 2.0项目中实现它,因此我必须使用可在1.5版本之前的JVM上运行的代码。 有人能帮我解决这个问题吗?)

编辑:我忘记提到我没有可用的SVG API,并且我需要一种旋转任意度数而不仅仅是90-180-270度的方法。

另外,在MIDP 2.0上不可用java.awt.*包。


Sprite类提供了一些基本的图像旋转和镜像功能。然而,对于较小的角度,我们可能需要使用一些算法。 - Prabhu R
4个回答

25

我在互联网上找到的描述图像旋转算法最好的页面之一,与丹·布隆伯格(Dan Bloomberg)的极佳leptonica库密切相关。尽管 leptonica 库本身是用 C 写的,无法帮助您,但他在图像旋转算法方面的页面:

http://www.leptonica.org/rotation.html

绝对值得一读。您最有可能想要实现像他在页面的第二部分中所描述的区域映射旋转算法。


值得注意的是,如果您已经有一个简单的旋转算法(例如在此答案中给出的采样旋转算法),以及一个良好的调整大小算法,那么您可以(我发现)将图像放大两倍或四倍,进行简单的旋转,然后使用良好的调整大小算法将图像减半或缩小四分之一。这就是我在 Jimp 中所做的,以获得旋转后更好的图像质量。 - Clonkex

7
通用解决方案: 对于目标图像中的每个像素,取源图像中与目标像素坐标相反方向旋转的像素。 解决方案的改进: 旋转通常不会给出确切的像素坐标。根据它与邻居重叠的百分比进行加权平均,以得到源像素。 二值图像的更快解决方案: 将图像转换为连续前景像素的"运行"。然后旋转这些线的端点并将其绘制到目标中。
通常由于整数舍入而产生轻微的间隙,因此当一个或两个端点距离某个整数超过10%时,通过绘制两条线来补丁单个源线,使用上下取整的整数坐标。
如果一个端点在10%内而另一个端点不在,则这两条线将形成'V'形。如果两个端点都偏离超过10%,则这两条线将形成'X'形。
可以相对于X轴或Y轴进行操作。使用与轴和旋转角度之间的最小角度相对应的那个轴。 (即,如果旋转角度在45到-45之间,请使用X轴。) 二值图像的更快速解决方案: 如果背景像素少于前景像素,则用前景填充目标,并使用背景像素遵循上述算法。

-2

Graphics2D和AffineTransform将帮助您实现所需的功能。具体来说,Graphics2D.drawImage(Image,AffineTransform)和AffineTransform.getRotateInstance。您还可以使用它进行缩放、平移和剪切。这两个类至少从1.4版本开始就一直存在于运行时中,可能更早。


1
很遗憾,Graphics2D不是MIDP 2.0规范的一部分。感谢您的理解。 - Stefano Driussi

-2
  public Image rotateImage(Image img, float degrees){
   BufferedImage sourceBI = new BufferedImage(img.getWidth(null),img.getHeight(null),BufferedImage.TYPE_INT_ARGB);
   sourceBI.getGraphics().drawImage(img,0,0,null);
   AffineTransform at = new AffineTransform();
   at.rotate(degrees*Math.PI/180, sourceBI.getWidth()/2, sourceBI.getHeight()/2);
   BufferedImageOp bio = new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR);
   return bio.filter(sourceBI, null);
  }

1
Java ME(MIDP API)中没有BufferedImageAffineTransformMIDP API - gnat

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接