`
zhouxiaoli521
  • 浏览: 552980 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Android Matrix类实现J2ME的drawRegion的镜像方法【新一则】

阅读更多

先说说drawRegion方法:

public void drawRegion(Image src,//图像文件
                       int x_src,//图像的起始点X坐标
                       int y_src,//图像的起始点Y坐标
                       int width,//要画图像的宽度
                       int height,//要画图像的高度
                       int transform,//旋转参数
                       int x_dest,//目标X坐标(也就是你要把图像画到那个Canvas上的哪个位置)
                       int y_dest,//目标Y坐标
                       int anchor)//锚点

 简单的说就是从原图截取一块内容并且可以旋转画在指定的位置。

从网上找了一个方法用matrix实现了,具体代码如下:

http://novembre.iteye.com/blog/636175 写道
     在用Android实现J2ME的drawRegion方法时,发现网上介绍的镜像翻转都是用像素数组行变列实现的,其实这还是j2me式的实现方法,Android中有Matrix类,如果学过计算机图形学,只要按其原理,进行矩阵变换即可。

 

 一、对称变换

 

   

 

1. 对称于Y轴

    其变换矩阵:

        

   

    其变换为:

    

 

2. 对称于X轴:

      

 

3. 对称于原点O:

   

 

4. 对称于直线y=x: 

   

 

5. 对称于直线y=-x:

    

 

二、drawRegion方法的实现

 

public void drawRegion(Image image_src, 
            			   int x_src, int y_src,
            			   int width, int height, 
            			   int transform,
            			   int x_dest, int y_dest,
            			   int anchor){
		
		if((anchor&VCENTER) != 0){
			y_dest -= height/2;
		}else if((anchor&BOTTOM) != 0){
			y_dest -= height;
		}
		if((anchor&RIGHT) != 0){
			x_dest -= width;
		}else if((anchor&HCENTER) != 0){
			x_dest -= width/2;
		}
		
		Bitmap newMap = Bitmap.createBitmap(image_src.getBitmap(), x_src, y_src, width, height);
				
		Matrix mMatrix = new Matrix();
		Matrix temp = new Matrix();
		Matrix temp2 = new Matrix();
		
		float[] mirrorY = {
				-1, 0, 0,
				0, 1, 0,
				0, 0, 1
		};
		temp.setValues(mirrorY);
		
		switch(transform){
		case Sprite.TRANS_NONE:
			
			break;

		case Sprite.TRANS_ROT90:
			mMatrix.setRotate(90,width/2, height/2);
			break;

		case Sprite.TRANS_ROT180:
			mMatrix.setRotate(180,width/2, height/2);
			break;

		case Sprite.TRANS_ROT270:
			mMatrix.setRotate(270,width/2, height/2);
			break;

		case Sprite.TRANS_MIRROR:
			mMatrix.postConcat(temp);
			break;

		case Sprite.TRANS_MIRROR_ROT90:
			mMatrix.postConcat(temp);
			mMatrix.setRotate(90,width/2, height/2);
			break;

		case Sprite.TRANS_MIRROR_ROT180:
			mMatrix.postConcat(temp);
			mMatrix.setRotate(180,width/2, height/2);
			break;

		case Sprite.TRANS_MIRROR_ROT270:
			mMatrix.postConcat(temp);
			mMatrix.setRotate(270,width/2, height/2);
			break;

		}
					
		mMatrix.setTranslate(x_dest, y_dest);
		
		canvas.drawBitmap(newMap, mMatrix, mPaint);
		
		
	}

    

   

    利用Matrix类,不止可实现对称变换,还可以实现其它的几何变换,包括组合变换。附件中是从网上找到的关于图形变换原理的ppt,希望对大家有帮助。

 

 然而事情到这里并没有结束,我发现对于我来说这个实现方法有一个问题。在往下说之前我先说一下我为什么要在android上实现drawRegion方法,我在做一个动画使用到了动画编辑器spritex,所以必须使用这个编辑器提供的类SpriteX.java,这个类只使用了j2me中的canvas里的基本绘图函数(当然也包括了drawRegion),所以只要你实现了j2me的canvas方法就可以用SpriteX.java,SpriteX.java的paint方法中使用了drawRegion所以我们也必须要实现它。

 

现在在说说我发现的问题那就是我上面找到的实现方法是使用“Bitmap newMap = Bitmap.createBitmap(image_src.getBitmap(), x_src, y_src, width, height);”来截取一块图像。它create了一个张图片。在android中每次创建图片系统都会GC一次!

 

现在问题出来了 我的程序移植在刷新--》SpriteX.java的paint方法每次都调用drawRegion--》drawRegion方法每次都createBitmap--》系统每次都GC

 

这样下去程序肯定会完蛋的,所以我修改了这个类,使用另一种方式来实现了它,没有create。

 说明写在程序中了

 

	public void drawRegion(Image image_src, 
			   int x_src, int y_src,
			   int width, int height, 
			   int transform,
			   int x_dest, int y_dest,
			   int anchor) {

		if ((anchor & VCENTER) != 0) {
			y_dest -= height / 2;
		} else if ((anchor & BOTTOM) != 0) {
			y_dest -= height;
		}
		if ((anchor & RIGHT) != 0) {
			x_dest -= width;
		} else if ((anchor & HCENTER) != 0) {
			x_dest -= width / 2;
		}

		//Bitmap newMap = Bitmap.createBitmap(image_src.getImage(), x_src, y_src,width, height);
		/*
		 * 这里没有使用create 而是用canvas的clipRect方法来实现扣图的效果
		 * 使用了save为后面恢复剪裁区用
		 */
		g.save();
		g.clipRect(x_dest, y_dest, x_dest+width, y_dest+height);
		Matrix mMatrix = new Matrix();
		Matrix temp = new Matrix();

		float[] mirrorY = { -1, 0, 0, 0, 1, 0, 0, 0, 1 };
		temp.setValues(mirrorY);

		switch (transform) {
		case SpriteX.TRANS_NONE:

			break;

		case SpriteX.TRANS_ROT90:
			mMatrix.setRotate(90, width / 2, height / 2);
			break;

		case SpriteX.TRANS_ROT180:
			mMatrix.setRotate(180, width / 2, height / 2);
			break;

		case SpriteX.TRANS_ROT270:
			mMatrix.setRotate(270, width / 2, height / 2);
			break;

		case SpriteX.TRANS_MIRROR:
			mMatrix.postConcat(temp);
			break;

		case SpriteX.TRANS_MIRROR_ROT90:
			mMatrix.postConcat(temp);
			mMatrix.setRotate(90, width / 2, height / 2);
			break;

		case SpriteX.TRANS_MIRROR_ROT180:
			mMatrix.postConcat(temp);
			mMatrix.setRotate(180, width / 2, height / 2);
			break;

		case SpriteX.TRANS_MIRROR_ROT270:
			mMatrix.postConcat(temp);
			mMatrix.setRotate(270, width / 2, height / 2);
			break;
		}
		
		/*
		 * 这里的偏移要注意减去x_src和y_src
		 * 并且调用restore()恢复剪裁区
		 */
		mMatrix.setTranslate(x_dest-x_src, y_dest-y_src);
		g.drawBitmap(image_src.getImage(), mMatrix, p);
		g.restore();
	}

 

分享到:
评论
3 楼 NBUsher 2012-11-12  
好贴,让我们找到J2ME和android的契合点,谢谢
2 楼 zhouxiaoli521 2012-02-22  
yuanzhifei89 写道
SpriteX.java这个文件能发我一个么?邮箱:563451339@qq.com

那个很久没用找不到了
SpriteX.java,这个类只使用了j2me中的canvas里的基本绘图函数,所以只要你实现了j2me的canvas方法就可以用SpriteX.java”
1 楼 yuanzhifei89 2012-02-22  
SpriteX.java这个文件能发我一个么?邮箱:563451339@qq.com

相关推荐

Global site tag (gtag.js) - Google Analytics