JAVA android 矩阵 怎么设置坐标
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA android 矩阵 怎么设置坐标相关的知识,希望对你有一定的参考价值。
//矩阵 旋转角度
matrix.setRotate(i);
// 渲染出 图片
canvas.drawBitmap( BIT , matrix , new Paint());
我目的是为了图片一直旋转,但出现2个问题
1: 图片只会随着右上角为中心的锚点旋转,我想以图片中心点为中心旋转。
2:怎么设置图片的位置坐标。
matrix.postTranslate(x,y) ——这个(x,y)为图片左上角的位置
2、设置图片图片中心点为中心旋转
matrix.postRotate(角度, x, y);——这个(x,y)为图片中心点的位置
3、渲染图片
canvas.drawBitmap( BIT , matrix , new Paint()); 参考技术A 先创建新的 bitmap
matrix.setRotate(i, bmp.getWidth/2,bmp.getHeight()/2);
Bitmap BIT = Bitmap.create(bmp, 0,0, bmp.getWidth,bmp.getHeight(),matrix,false);
在 onDraw() 调用canvas 定制 x,y 坐标
canvas.drawBitmap( BIT , x,y , new Paint());
/// 自己在键盘上敲的,如果需要,我可以贴代码..追问
我的是:
Bitmap.createBitmap(bmp, 0,0, bmp.getWidth,bmp.getHeight(),matrix,false);
没有BITmap.create
而且报错了 里面填的是什么参数?
先创建新的 bitmap
bmp= Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(),
bmp.getHeight(), mat, false);
坐标变换矩阵是一个3*3的矩阵如图2.1,用来对图形进行坐标变化,将原来的坐标点转移到新的坐标点,
因为一个图片是有点阵和每一点上的颜色信息组成的,所以对坐标的变换,就是对每一点进行搬移形成新的图片。
具体的说图形的放大缩小,移动,旋转,透视,扭曲这些效果都可以用此矩阵来完成。
这个矩阵的作用是对坐标x,y进行变换计算结果如下:
x'=a*x+b*y+c
y'=d*x+e*y+f
通常情况下g=h=0,这样使1=0*x+0*y+1恒成立。和颜色矩阵一样,坐标变换矩阵真正使用的参数很少也很有规律。
上图就是一个坐标变换矩阵的简单例子,计算后发现x'=x+50,y'=y+50.
可见图片的每一点都在x和y方向上平移到了(50,50)点处,这种效果就是平移效果,将图片转移到了(50,50)处。
计算上面得矩阵x'=2*x,y‘=2*y.经过颜色矩阵和上面转移效果学习,相信读者可以明白这个矩阵的作用了,这个矩阵对图片进行了放大,具体的说是放大了二倍。
下面将介绍几种常用的变换矩阵:
1. 旋转
绕原点逆时针旋转θ度角的变换公式是 x' = xcosθ − ysinθ 与 y。' = xsinθ + ycosθ
2. 缩放
变换后长宽分别放大x'=scale*x;y'=scale*y.
3. 切变
4. 反射
( , )单位向量
5. 正投影
( , )单位向量
上面的各种效果也可以叠加在一起,既矩阵的组合变换,可以用矩阵乘法实现之,如:R=B(A*C)=(B*A)C,注意一点就是B*A和A*B一般是不等的。
下面将编一个小程序,通过控制坐标变换矩阵来达到控制图形的目的,JavaCode如下:
[java] view plaincopy
CooMatrix类:
public class CooMatrix extends Activity
private Button change;
private EditText [] et=new EditText[9];
private float []carray=new float[9];
private MyImage sv;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
change=(Button)findViewById(R.id.set);
sv=(MyImage)findViewById(R.id.MyImage);
for(int i=0;i<9;i++)
et[i]=(EditText)findViewById(R.id.indexa+i);
carray[i]=Float.valueOf(et[i].getText().toString());
change.setOnClickListener(l);
private Button.OnClickListener l=new Button.OnClickListener()
@Override
public void onClick(View arg0)
// TODO Auto-generated method stub
getValues();
sv.setValues(carray);
sv.invalidate();
;
public void getValues()
for(int i=0;i<9;i++)
carray[i]=Float.valueOf(et[i].getText().toString());
MyImage类继承自View类:
public class MyImage extends View
private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Bitmap mBitmap;
private float [] array=new float[9];
public MyImage(Context context,AttributeSet attrs)
super(context,attrs);
mBitmap = BitmapFactory.decodeResource(context.getResources(),
R.drawable.ic_launcher_android);
invalidate();
public void setValues(float [] a)
for(int i=0;i<9;i++)
array[i]=a[i];
@Override protected void onDraw(Canvas canvas)
Paint paint = mPaint;
canvas.drawBitmap(mBitmap, 0, 0, paint);
//new 一个坐标变换矩阵
Matrix cm = new Matrix();
//为坐标变换矩阵设置响应的值
cm.setValues(array);
//按照坐标变换矩阵的描述绘图
canvas.drawBitmap(mBitmap, cm, paint);
Log.i("CMatrix", "--------->onDraw");
上面的代码中类CooMatrix用于接收用户输入的坐标变换矩阵参数,类MyImage接收参数,通过setValues()设置矩阵参数,然后Canvas调用drawBitmap绘图。效果如下:
上面给出了用坐标变换矩阵做出的各种效果,用坐标变换矩阵可以方面的调节图形的各种效果,
但是我们看看Matrix类就可以发现,实际上,matrix类本身已经提供了许多类似的方法,我们只要调用,就可以了。
setScale(float sx, float sy, float px, float py) 放大
setSkew(float kx, float ky, float px, float py) 斜切
setTranslate(float dx, float dy) 平移
setRotate(float degrees, float px, float py) 旋转
上面的函数提供了基本的变换平移,放大,旋转,斜切。为了做出更复杂的变换,同时不必亲手去改动坐标变换矩阵,
Matrix类提供了许多Map方法,将原图形映射到目标点构成新的图形,
下面简述setPolyToPoly(float[] src, int srcIndex, float[] dst, int dstIndex, int pointCount) 的用法,希望起到举一反三的作用。
参数src和dst是分别存储了原图像的点和和指定的目标点的一维数组,数组中存储的坐标格式如下:
[x0, y0, x1, y1, x2,y2,...]
这个个函数将src中的坐标映射到dst中的坐标,实现图像的变换。
具体的例子可以参考APIDemos里的PolyToPoly,我在这里就不再贴代码了,只讲一下函数是怎么变换图片的。下面是效果:
图中写1的是原图,写有2,3,4的是变换后的图形。现在分析2是怎么变换来的,变换的原坐标点和目的坐标点如下:
src=new float[] 32, 32, 64, 32
dst=new float[] 32, 32, 64, 48
从上图标示出的坐标看出原图的(32,32)映射到原图的(32,32),(64,32)映射到原图(64,48)这样的效果是图像放大了而且发生了旋转。这样的过程相当于(32,32)点不动,然后拉住图形(64,32)点并拉到(64,48)点处,这样图形必然会被拉伸放大并且发生旋转。最后用一个平移将图形移动到右边现在的位置。希望能够好好理解这一过程,下面的3,4图是同样的道理。
Android UICanvas 画布 ⑧ ( Canvas 绘图坐标系 2x2 矩阵 | Canvas 绘图坐标系 3x3 操作矩阵 )
文章目录
Canvas 状态保存机制 中 , 存在两个栈结构 , 分别是 状态栈 和 图层栈 ;
其中 图层栈 又称为 Layer 栈 ;
Canvas 画布中 , 有 2 2 2 套坐标系 , 分别是 :
- Canvas 自身坐标系
- Canvas 绘图坐标系
一、Canvas 绘图坐标系 2x2 矩阵
在 Canvas 绘制矩形的过程中 , 最终调用的是 BaseCanvas#nDrawRect 方法 ,
private static native void nDrawRect(long nativeCanvas, float left, float top, float right,
float bottom, long nativePaint);
最终的 左上右下 Canvas 绘图坐标系 中的坐标数据 , 也就是上述 BaseCanvas#nDrawRect 方法的 float left, float top, float right, float bottom
参数 , 会被转为一个
2
×
2
2\\times2
2×2 的 Matrix 矩阵 ;
该 2 × 2 2\\times2 2×2 的 Matrix 矩阵 用于存储 Canvas 绘图坐标系 ;
Canvas 绘图坐标系 可以通过调用 Canvas#translate 平移 , Canvas#rotate 旋转 , Canvas#scale 缩放 , Canvas#skew 扭曲斜拉 等方法 进行改变 ;
二、Canvas 绘图坐标系 3x3 操作矩阵
Canvas#translate 平移 , Canvas#rotate 旋转 , Canvas#scale 缩放 , Canvas#skew 扭曲斜拉 等操作数据 , 会被封装到一个 3 × 3 3 \\times 3 3×3 的 Matrix 矩阵 中 , 该矩阵中有 9 9 9 个参数 , 用于记录上述 4 4 4 种操作数值 :
- cosX -sinX translateX
- sinX cosX translateY
- 0 0 scale
其中 sinX 和 cosX 表示 Canvas#rotate 旋转角度的 正弦和余弦值 , 顺时针旋转为正 ;
translateX 和 translateY 分别表示 X 轴 和 Y 轴平移的值 ;
scale 表示 Canvas 画布缩放值 ;
调用 Canvas#getMatrix 方法 , 可获取上述 3 × 3 3 \\times 3 3×3 的 Matrix 矩阵 , 该方法原型如下 :
/**
* 返回一个新矩阵和画布当前变换矩阵的副本。
*
* @deprecated @link #isHardwareAccelerated() 硬件加速的
* 画布在传递到视图或可绘制时可能有任何矩阵,
* 因为它是在层次结构中创建此类画布的位置由实现定义的。
* 在这种情况下,建议绘制内容而不考虑当前矩阵,或跟踪画布之外的相关变换状态。
*/
@Deprecated
public final @NonNull Matrix getMatrix()
Matrix m = new Matrix();
//noinspection deprecation
getMatrix(m);
return m;
上述 Canvas#translate 平移 , Canvas#rotate 旋转 , Canvas#scale 缩放 , Canvas#skew 扭曲斜拉 等操作的 3 × 3 3 \\times 3 3×3 的 Matrix 矩阵
会与
代表 Canvas 绘图坐标系的 2 × 2 2 \\times 2 2×2 的 Matrix 矩阵
进行运算 , 最终得到一个 新的 Canvas 绘图坐标系 ;
以上是关于JAVA android 矩阵 怎么设置坐标的主要内容,如果未能解决你的问题,请参考以下文章