先说说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实现了,具体代码如下:
?
?一、对称变换
?
???
?
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(); }
?
那个很久没用找不到了
SpriteX.java,这个类只使用了j2me中的canvas里的基本绘图函数,所以只要你实现了j2me的canvas方法就可以用SpriteX.java”