Android对图像进行各种对称显示(以矩形为例)
2011-09-01 20:44
399 查看
先说说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实现了,具体代码如下:
在用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();
}
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实现了,具体代码如下:
在用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();
}
相关文章推荐
- android 使用NDK进行图像处理(openCV)时的图像转换问题(灰度图显示)
- 要绘图,首先得调整画笔,待画笔调整好之后,再将图像绘制到画布上,这样才可以显示在手机屏幕上。Android 中的画笔是 Paint类,Paint 中包含了很多方法对其属性进行设置,主要方法(没有全部列
- Android利用canvas画各种图形(点、直线、弧、圆、椭圆、文字、矩形、多边形、曲线、圆角矩形) --图像图形
- Raphaël 是一个小型的 JavaScript 库,用来简化在页面上显示向量图的工作。你可以用它在页面上绘制各种图表、并进行图片的剪切、旋转等操作。
- [Android] 使用Matrix矩阵类对图像进行缩放、旋转、对比度、亮度处理
- JQuery中对各种域进行隐藏和显示操作
- Android 针对多种屏幕进行设计 (二)支持各种屏幕密度
- Android利用canvas画各种图形(点、直线、弧、圆、椭圆、文字、矩形、多边形、曲线、圆角矩形)
- android 对图像进行矩阵变换(Martix)的使用笔记
- Android利用canvas画各种图形(点、直线、弧、圆、椭圆、文字、矩形、多边形、曲线、圆角矩形)
- Android中ListView的各种显示效果
- 圆弧矩形进度条,可用于在layout或者imageview外层实现进度的显示(改良android-square-progressbar)
- Android CustomShapeImageView对图片进行各种样式裁剪:圆形、星形、心形、花瓣形等
- Android利用canvas画各种图形(点、直线、弧、圆、椭圆、文字、矩形、多边形、曲线、圆角矩形)
- Android中进行图片缩放显示
- android开发学习---layout布局、显示单位和如何进行单元测试
- 可循环显示图像的Android Gallery组件
- Android中进行图像压缩和缩放
- Android 中使用OpenGL ES进行2D开发(绘制矩形)
- Android利用canvas画各种图形(点、直线、弧、圆、椭圆、文字、矩形、多边形、曲线、圆角矩形)