扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
在本页阅读全文(共3页)
  1、算法思想 
  为实现整个图像的旋转,我们首先获取源图像每个点的像素值。然后根据旋转点和角度的大小计算出新图像的大小。再逐点计算源图像中每个点经旋转后在新图像中对应点的坐标,并把相应的像素值赋给它。 
  在图三中,阴影部分为源图像,O为旋转点,P、Q分别为旋转前后图像左上角的点,cx,cy为O相对于源图像左上角P点的坐标值。 
  这里我们以O为圆心,以O距图像4个顶点的距离的最大值作为半径dr画圆,这样图像无论以任何角度旋转都不会超出这个圆的范围。于是,我们就以该圆为画布绘制旋转所得新图像。由于实际中图像是用矩形表示的,于是我们生成和圆的外切正方形(图中虚线部分)等大小的新图像。 
  对源图像中任一点(i,j),根据上面的公式,不难计算出旋转θ度在新图像中的位置,即相对于Q点的位置(destX , destY): 
  destX = dr + (i - cx) *cos(radian) - (j - cy)*sin(radian); 
  destY = dr + (j - cy) *cos(radian) + (i - cx)*sin(radian); 
  计算出这个位置后,把该点的像素值赋值到这个位置,如此对每个点进行这种变换,即可实现整个图像的旋转。 
  旋转后的图像较大,在实际绘制时需要做位置调整,不难看出,Q点相对于P点的偏移量为(cx-dr , cy-dr)。即假设源图像的屏幕位置为(a , b),则旋转后的图像位置应该为( (a + cx ? dr) , (b + cy ? dr) )。 
   


  图四 算法流程图 在MIDP2.0中,Image类提供了两个方法:getRGB()和createRGBImage(),分别完成获取图像象素信息和通过像素数组创建图像的功能。借助于这两个方法,结合上面的流程图,我们得到实现图像旋转算法的代码,如下面所示。 
  /** 
  *@param imgSource 源图像 
  *@param cx 旋转点相对于源图像坐上角横坐标 
  *@param cy 旋转点相对于源图像坐上角纵坐标 
  *@param theta 图像逆时针旋转的角度 
  *@param dd 含2个元素的整形数组,存放新图像相对源图像沿x轴和y轴的位置偏移量 
  *@return 旋转后的图像 
  **/ 
  public Image rotate(Image imgSource, int cx, int cy, double theta, int[] dd) { 
   if (Math.abs(theta % 360) < 0.1) return imgSource; //角度很小时直接返回 
    int w1 = imgSource.getWidth(); //原始图像的高度和宽度 
    int h1 = imgSource.getHeight(); 
    int[] srcMap = new int[w1 * h1]; 
    imgSource.getRGB(srcMap, 0, w1, 0, 0, w1, h1); //获取原始图像的像素信息 
    int dx = cx > w1 / 2 ? cx : w1 - cx; //计算旋转半径 
    int dy = cy > h1 / 2 ? cy : h1 - cy; 
    double dr = Math.sqrt(dx * dx + dy * dy); 
    int wh2 = (int) (2 * dr + 1); //旋转后新图像为正方形,其边长+1是为了防止数组越界 
    int[] destMap = new int[wh2 * wh2]; //存放新图像象素的数组 
    double destX, destY; 
    double radian = theta * Math.PI / 180; //计算角度计算对应的弧度值 
    for (int i = 0; i < w1; i++) { 
     for (int j = 0; j < h1; j++) { 
      if (srcMap[j * w1 + i] >> 24 != 0) { //对非透明点才进行处理 
       // 得到当前点经旋转后相对于新图像左上角的坐标 
       destX = dr + (i - cx) * Math.cos(radian) + (j - cy)* Math.sin(radian); 
       destY = dr + (j - cy) * Math.cos(radian) - (i - cx)* Math.sin(radian); 
       //从源图像中往新图像中填充像素 
       destMap[(int) destY * wh2 + (int) destX] = srcMap[j * w1 + i]; 
      } 
     } 
    } 
    dd[0] = cx-dr; //返回位置偏移分量 
    dd[1] = cy-dr; 
    return Image.createRGBImage(destMap, wh2, wh2, true); //返回旋转后的图像 
  } 
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。