一、概述

 1. 在Android中,如果你用Matrix进行过图像处理,那么一定知道Matrix这个类。Android中的Matrix是一个3 x 3的矩阵,其内容如下

  

2.Matrix的对图像的处理可分为四类基本变换:

  Translate           平移变换

  Rotate                旋转变换

  Scale                  缩放变换

  Skew                  错切变换

针对每种变换,Android提供了pre、set和post三种操作方式。其中
set用于设置Matrix中的值。
pre是先乘,因为矩阵的乘法不满足交换律,因此先乘、后乘必须要严格区分。先乘相当于矩阵运算中的右乘。
post是后乘,因为矩阵的乘法不满足交换律,因此先乘、后乘必须要严格区分。后乘相当于矩阵运算中的左乘。

除平移变换(Translate)外,旋转变换(Rotate)、缩放变换(Scale)和错切变换(Skew)都可以围绕一个中心点来进行,如果不指定,在默认情况下是围绕(0, 0)来进行相应的变换的。

  

二、常用操作

1.平移  

matrix.postTranslate(view.getImageBitmap().getWidth(), view.getImageBitmap().getHeight());

2.缩放

matrix.setScale(2f, 2f);

3.旋转

//第一种方式
//旋转 围绕图片中心
matrix.setRotate(45f,view.getImageBitmap().getWidth()/2f,view.getImageBitmap().getHeight()/2f);
//平移
matrix.postTranslate(view.getImageBitmap().getWidth()*1.5f,0f); //第二种方式
//旋转 中心点(0,0)
matrix.setRotate(45f); //先将图片中心移到(0,0),旋转后再移到原位置
matrix.preTranslate(-view.getImageBitmap().getWidth()/2f,-view.getImageBitmap().getHeight()/2f);
matrix.postTranslate(view.getImageBitmap().getWidth()*2f,view.getImageBitmap().getHeight()/2f);

4.错切

     matrix.setSkew(0.5f,0f);//水平
matrix.setSkew(0f,0.5f);//竖直
matrix.setSkew(0.5f,0.5f);//水平和数值

5.对称

 1)x轴对称

float matrix_values[] = {1f, 0f, 0f, 0f, -1f, 0f, 0f, 0f, 1f};
matrix.setValues(matrix_values);

 2)Y轴对称

float matrix_values[] = {-1f, 0f, 0f, 0f, 1f, 0f, 0f, 0f, 1f};
matrix.setValues(matrix_values);

 3)y=x对称

float matrix_values[] = {0f, -1f, 0f, -1f, 0f, 0f, 0f, 0f, 1f};
matrix.setValues(matrix_values);

三、代码

1.xml文件

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/rl"
>
<com.example.dhj.bitmapdemo.TransformMatrixView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/view"
/>
</RelativeLayout> <RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="visible" > <Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginBottom="135dp"
android:onClick="click"
android:text="平移" /> <Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/button"
android:layout_alignBottom="@+id/button"
android:layout_marginLeft="17dp"
android:layout_marginStart="17dp"
android:layout_toEndOf="@+id/button"
android:layout_toRightOf="@+id/button"
android:onClick="click"
android:text="旋转" /> <Button
android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/button2"
android:layout_marginLeft="35dp"
android:layout_marginStart="35dp"
android:layout_toEndOf="@+id/button2"
android:layout_toRightOf="@+id/button2"
android:onClick="click"
android:text="水平倾斜" /> <Button
android:id="@+id/button4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/button5"
android:layout_alignBottom="@+id/button5"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:onClick="click"
android:text="竖直倾斜" /> <Button
android:id="@+id/button5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/button2"
android:layout_alignStart="@+id/button2"
android:layout_below="@+id/button2"
android:onClick="click"
android:text="水平竖直倾斜" /> <Button
android:id="@+id/button6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/button3"
android:layout_alignStart="@+id/button3"
android:layout_below="@+id/button3"
android:onClick="click"
android:text="x轴对称" /> <Button
android:id="@+id/button7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="@+id/button4"
android:layout_marginTop="15dp"
android:onClick="click"
android:text="y轴对称" /> <Button
android:id="@+id/button8"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/button7"
android:layout_alignLeft="@+id/button5"
android:layout_alignStart="@+id/button5"
android:onClick="click"
android:text="y=x对称" /> <Button
android:id="@+id/button11"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/button6"
android:layout_alignStart="@+id/button6"
android:layout_alignTop="@+id/button8"
android:onClick="click"
android:text="缩放" /> </RelativeLayout> </FrameLayout>

  

2.自定义view

class TransformMatrixView extends ImageView
{
private Bitmap bitmap;
private Matrix matrix;
public TransformMatrixView(Context context)
{
super(context);
Bitmap b = BitmapFactory.decodeResource(getResources(), R.drawable.p1);
bitmap=resizeBitmap(b,162,251);
matrix = new Matrix();
setBackgroundColor(Color.parseColor("#3f51b5"));
} public TransformMatrixView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
Bitmap b = BitmapFactory.decodeResource(getResources(), R.drawable.p1);
bitmap=resizeBitmap(b,162,251);
matrix = new Matrix();
// setBackgroundColor(Color.parseColor("#3f51b5"));
} @Override
protected void onDraw(Canvas canvas)
{
// 画出原图像
canvas.drawBitmap(bitmap, 0, 0, null);
// 画出变换后的图像
canvas.drawBitmap(bitmap, matrix, null);
super.onDraw(canvas);
} @Override
public void setImageMatrix(Matrix matrix)
{
this.matrix.set(matrix);
super.setImageMatrix(matrix);
} public Bitmap getImageBitmap()
{
return bitmap;
} /**
* 使用Matrix将Bitmap压缩到指定大小
* @param bitmap
* @param w
* @param h
* @return
*/
public static Bitmap resizeBitmap(Bitmap bitmap, int w, int h)
{
int width = bitmap.getWidth();
int height = bitmap.getHeight(); float scaleWidth = ((float) w) / width;
float scaleHeight = ((float) h) / height; Matrix matrix = new Matrix();
matrix.postScale(scaleWidth, scaleHeight); Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0, width,
height, matrix, true);
return resizedBitmap;
}
}

3.activity

public class MainActivity extends Activity {
private TransformMatrixView view;
Matrix matrix= new Matrix();
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
view= (TransformMatrixView) findViewById(R.id.view); } public void click(View v){
switch (v.getId()){
case R.id.button:
tranlate();
break;
case R.id.button2:
rorate();
break;
case R.id.button3:
skewhorizontal();
break;
case R.id.button4:
skewVertical();
break;
case R.id.button5:
skew();
break;
case R.id.button6:
symmetryHorizontal();
break;
case R.id.button7:
symmetryVertical();
break;
case R.id.button8:
symmetry();
break;
case R.id.button11:
scale();
break; }
view.setImageMatrix(matrix);
// view.invalidate();
} //平移
private void tranlate(){
// 输出图像的宽度和高度(162 x 251)
// Log.e("TestTransformMatrixActivity", "image size: width x height = " + view.getImageBitmap().getWidth() + " x " + view.getImageBitmap().getHeight());
// 1. 平移
matrix.postTranslate(view.getImageBitmap().getWidth(), view.getImageBitmap().getHeight());
// 在x方向平移view.getImageBitmap().getWidth(),在y轴方向view.getImageBitmap().getHeight() } //旋转
private void rorate(){
//第一种方式
//旋转 围绕图片中心
matrix.setRotate(45f,view.getImageBitmap().getWidth()/2f,view.getImageBitmap().getHeight()/2f);
//平移
matrix.postTranslate(view.getImageBitmap().getWidth()*1.5f,0f); //第二种方式
//旋转 中心点(0,0)
matrix.setRotate(45f); //先将图片中心移到(0,0),旋转后再移到原位置
matrix.preTranslate(-view.getImageBitmap().getWidth()/2f,-view.getImageBitmap().getHeight()/2f);
matrix.postTranslate(view.getImageBitmap().getWidth()*2f,view.getImageBitmap().getHeight()/2f); } //缩放
private void scale(){
matrix.setScale(2f, 2f);
matrix.postTranslate(view.getImageBitmap().getWidth(),view.getImageBitmap().getHeight()); } //水平 倾斜
private void skewhorizontal(){
// matrix.setSkew(0.5f, 0f);
// matrix.postTranslate(view.getImageBitmap().getWidth(), 0f);
matrix.setSkew(0.5f,0f);
matrix.postTranslate(view.getImageBitmap().getWidth(),0f); } //竖直 倾斜
private void skewVertical(){
matrix.setSkew(0f,0.5f);
matrix.postTranslate(view.getImageBitmap().getWidth(),0f); } //倾斜 水平和竖直
private void skew(){
matrix.setSkew(0.5f,0.5f);
matrix.postTranslate(view.getImageBitmap().getWidth(),0f);
} //x轴对称
private void symmetryHorizontal(){
float matrix_values[] = {1f, 0f, 0f, 0f, -1f, 0f, 0f, 0f, 1f};
matrix.setValues(matrix_values);
matrix.postTranslate(0f,view.getImageBitmap().getHeight()*2);
} //y轴对称
private void symmetryVertical(){
float matrix_values[] = {-1f, 0f, 0f, 0f, 1f, 0f, 0f, 0f, 1f};
matrix.setValues(matrix_values);
matrix.postTranslate(view.getImageBitmap().getWidth()*2,0f);
} //对称 y=x
private void symmetry(){
float matrix_values[] = {0f, -1f, 0f, -1f, 0f, 0f, 0f, 0f, 1f};
matrix.setValues(matrix_values);
matrix.postTranslate(view.getImageBitmap().getWidth()+view.getImageBitmap().getHeight(),
view.getImageBitmap().getHeight()+view.getImageBitmap().getWidth());
} }

四、效果

  

参考:

Android中图像变换Matrix的原理、代码验证和应用

最新文章

  1. SSH实例(5)
  2. Android关机闹钟实现
  3. (转)Ratchet教程:meta与link标签
  4. 查询sql 并且读取
  5. 转: HTML5新特性之Mutation Observer
  6. 04-Foundation-NSSet、NSDictionary、block
  7. 接口的作用(C#)
  8. ansible批量管理
  9. 使用git在github上创建新工程
  10. windows 函数
  11. 委托到Lambda的进化: ()=&gt; {} 这个lambda表达式就是一个无参数的委托及具体方法的组合体。
  12. actor 内最好不要阻塞
  13. (转)Geth控制台使用及Web3.js使用实战
  14. Sample Classification Code of CIFAR-10 in Torch
  15. Win10系列:UWP界面布局基础2
  16. JavaEE-学习目录
  17. SpringBoot 使用 EhCache2.x 缓存(三十一)
  18. .NET Core容器化之多容器应用部署-使用Docker-Compose
  19. Hybrid APP基础篇(四)-&gt;JSBridge的原理
  20. jquery call cross-domain webapi owin self-host

热门文章

  1. 【转】 Pro Android学习笔记(九十):了解Handler(4):Worker线程
  2. PTA 说反话-加强版(20 分)(字符串处理)
  3. mysql 内存体系结构--session
  4. Oracle数据库Where条件执行顺序
  5. kali下安装go环境
  6. java成神之——文件IO
  7. php学习之if
  8. 处理大数据对象clob数据和blob数据
  9. 手机自带输入法emoji表情的输入,提交及显示——前端解决方案
  10. dom方式解析xml文件的步骤