19

我正在寻找一种将图像旋转一定程度(输入)的算法。

public Image rotateImage(Image image, int degrees)

(图像实例可以用包含每个像素 RGB 值的 int[] 替换,我的问题是我需要为 JavaME MIDP 2.0 项目实现它,所以我必须使用 1.5 版之前可在 JVM 上运行的代码 谁能帮我解决这个问题?

编辑:我忘了提到我没有可用的 SVG API,我需要一种方法来旋转 90-180-270 以外的任意角度

此外,MIDP 2.0 上没有可用的 java.awt.* 包

4

4 回答 4

25

我在互联网上找到的描述图像旋转算法的最佳页面之一与 Dan Bloomberg出色的leptonica 库有关。虽然 leptonica 库本身是用 C 语言编写的,对您没有帮助,但他关于图像旋转算法的页面:

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

绝对值得一读。您很可能希望实现类似于他在页面第二部分中描述的按区域映射算法的旋转。

于 2009-01-27T18:33:16.707 回答
7

一般解决方案:对于目标图像中的每个像素点,取源图像中的像素点与目标像素点坐标,反方向旋转。

解决方案的增强:旋转通常不会给出精确的像素坐标。根据与它们重叠的百分比,对源像素与其相邻像素进行加权平均。

二值图像的更快解决方案:将图像转换为连续前景像素的“运行”。然后旋转这些线的端点并将它们绘制到目的地。

通常,由于整数舍入,这会产生微小的间隙,因此当一个或两个端点与整数的距离超过 10% 时,通过使用向上和向下舍入的整数坐标为单个源线绘制两条线来修补。

如果一个端点在 10% 以内而另一个不在,则两条线将形成“V”形。如果两者的偏差超过 10%,则两条线将形成“X”形。

这可以相对于 X 轴或 Y 轴来完成。使用轴和旋转角度之间夹角最小的那个。(即如果旋转角度在 45 到 -45 之间,则使用 X 轴。)

二值图像的更快解决方案:如果背景像素比前景像素少,则用前景填充目标,并按照上述算法使用背景像素。

于 2009-02-24T22:00:19.367 回答
-3

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

于 2009-01-27T18:26:14.177 回答
-3
  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);
  }
于 2010-05-15T14:47:18.483 回答