Android开发--利用Matrix进行图片操作

今天和大家分享一下Android中Matrix的简单用法,Matrix其实就是一个3*3的矩阵,利用这个矩阵对图像操作。在Android中,为我们提供一些封装好的方法可以进行一些简单的图像操作,总共分为rotate(旋转),scale(缩放),translate(平移)和skew(倾斜)四种,每一种变换都提供了set, post和pre三种操作方式,除了translate,其他三种操作都可以指定中心点。其中post的方式是对原矩阵进行后乘,pre方式是对原矩阵进行前乘,另外,每一次通过set的方式调用就会进行一次reset重置,之前的操作就会被销毁,在组合变化中需要注意。

旋转操作

Matrix中与旋转操作相关的方法一共有6个,

public boolean preRotate (float degrees)
public boolean preRotate (float degrees, float px, float py)
public boolean postRotate (float degrees)
public boolean postRotate (float degrees, float px, float py)
public void setRotate (float degrees)
public void setRotate (float degrees, float px, float py)

其中参数degrees指明了旋转的角度,如果大于零则为顺时针,小于零为逆时针;参数px,py用于指定旋转的中心,默认为(0,0)即左上角。

缩放操作

Matrix中与缩放操作相关的方法一共有6个,

public boolean postScale (float sx, float sy)
public boolean postScale (float sx, float sy, float px, float py)
public boolean preScale (float sx, float sy)
public boolean preScale (float sx, float sy, float px, float py)
public void setScale (float sx, float sy)
public void setScale (float sx, float sy, float px, float py)

其中参数sx,sy分别表示x轴和y轴的拉伸变化,如果大于1,为放大,小于1为缩小,为负值则表示对称的变化(在之后的组合变化中我们会用到它来实现镜子和倒影的效果);参数px,py用于指定缩放的中心(就是当缩放变化后该点的位置坐标不会变),默认为(0,0)即左上角。

平移操作

Matrix中关于平移的方法有3个

public boolean postTranslate (float dx, float dy)
public boolean preTranslate (float dx, float dy)
public void setTranslate (float dx, float dy)

其中参数dx,dy表示平移的距离,dx大于零表示向右,小于零表示向左;dy大于零表示向下,小于零表示向上。

倾斜操作

Matrix中关于倾斜操作的方法有6个

public boolean postSkew (float kx, float ky)
public boolean postSkew (float kx, float ky, float px, float py)
public boolean preSkew (float kx, float ky)
public boolean preSkew (float kx, float ky, float px, float py)
public void setSkew (float kx, float ky)
public void setSkew (float kx, float ky, float px, float py)

点(x,y)经过skew(kx,ky,px,py)变换之后,坐标为(kx*(y-py)+px,ky*(x-px)+py),如果,px和py没有,则默认为都为0。

组合变化

1.镜像变化:对于scale变化,如果以一个负数缩放,那么会将该 图像绘制到坐标系统的负值空间。由于(0,0)点位于左上角,使用x轴上的负数会导致向左绘制图像。因此我们需要使用postTranslate方法,将图像向右移动即可实现镜像变化。

matrix.setScale(-1, 1);
matrix.postTranslate(mBitmap.getWidth(),0);

2.倒影变化:同镜像变化,我们可以在y轴上做相同的事情,就会得到倒影的效果。

matrix.postScale(1, -1);
matrix.postTranslate(0, mBitmap.getHeight());

代码样例

根据以上的Matrix的操作,自己做了一个小的实验,效果如下:

MainActivity类:

package com.example.matrixtest;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MainActivity extends Activity {

    private TestView testView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        testView = (TestView) findViewById(R.id.testview);
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(),
                R.drawable.ttt);
        testView.setmBitmap(bitmap);

        ((Button) findViewById(R.id.button_rotate))
                .setOnClickListener(new OnClickListener() {

                    @Override
                    public void onClick(View v) {
                        // TODO Auto-generated method stub
                        testView.rotate(15);
                    }
                });
        ((Button) findViewById(R.id.button_scale))
                .setOnClickListener(new OnClickListener() {

                    @Override
                    public void onClick(View v) {
                        // TODO Auto-generated method stub
                        testView.scale(0.8f, 0.8f);
                    }
                });
        ((Button) findViewById(R.id.button_translate))
                .setOnClickListener(new OnClickListener() {

                    @Override
                    public void onClick(View v) {
                        // TODO Auto-generated method stub
                        testView.translate(1, 1);
                    }
                });
        ((Button) findViewById(R.id.button_skew))
        .setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                testView.skew(-0.3f, 0.3f);
            }
        });
        ((Button) findViewById(R.id.button_mirror))
                .setOnClickListener(new OnClickListener() {

                    @Override
                    public void onClick(View v) {
                        // TODO Auto-generated method stub
                        testView.mirror();
                    }
                });
        ((Button) findViewById(R.id.button_shadow))
                .setOnClickListener(new OnClickListener() {

                    @Override
                    public void onClick(View v) {
                        // TODO Auto-generated method stub
                        testView.shadow();
                    }
                });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

}

TestView类,我重新写了一个View来绘制图片:

package com.example.matrixtest;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.util.AttributeSet;
import android.view.View;

public class TestView extends View {

    private Bitmap mBitmap;
    private Matrix matrix;

    public TestView(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
        matrix = new Matrix();
    }

    public TestView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        // TODO Auto-generated constructor stub
        matrix = new Matrix();
    }

    public TestView(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
        matrix = new Matrix();
    }

    public Bitmap getmBitmap() {
        return mBitmap;
    }

    public void setmBitmap(Bitmap mBitmap) {
        this.mBitmap = mBitmap;
        invalidate();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        // TODO Auto-generated method stub
        super.onDraw(canvas);
        if (mBitmap != null) {
            canvas.drawBitmap(mBitmap, matrix, null);
        }
    }

    public void rotate(float degree) {
        if (mBitmap != null) {
            matrix.preRotate(degree, mBitmap.getWidth() / 2,
                    mBitmap.getHeight() / 2);
            invalidate();
        }

    }

    public void translate(float dx, float dy) {
        if (mBitmap != null) {
            matrix.postTranslate(dx, dy);
            invalidate();
        }
    }

    public void scale(float sx, float sy) {
        if (mBitmap != null) {
            matrix.postScale(sx, sy);
            invalidate();
        }
    }

    public void mirror() {
        if (mBitmap != null) {
            matrix.postScale(-1, 1);
            matrix.postTranslate(mBitmap.getWidth(), 0);
            invalidate();
        }
    }

    public void shadow() {
        if (mBitmap != null) {
            matrix.postScale(1, -1);
            matrix.postTranslate(0, mBitmap.getHeight());
            invalidate();
        }
    }

    public void skew(float kx, float ky){
        if (mBitmap != null) {
            matrix.postSkew(kx, ky);
            invalidate();
        }
    }
}

点击下载源码

时间: 2024-10-02 18:32:12

Android开发--利用Matrix进行图片操作的相关文章

Android开发之使用sqlite3工具操作数据库的两种方式

使用 sqlite3 工具操作数据库的两种方式 请尊重他人的劳动成果,转载请注明出处:Android开发之使用sqlite3工具操作数据库的两种方式 http://blog.csdn.net/fengyuzhengfan/article/details/40193123 在Android SDK的tools目录下提供了一"sqlite3.exe工具,它是一个简单的SQLite数据库管理工具,类似于MySQL提供的命令行窗口在有些时候,开发者利用该工具来査询. 管理数据库. 下面介绍两种方式: 第

利用Matrix实现图片倒影效果

利用matrix可以实现各种图片的特效,今天就用marix加上渐变色实现图片倒影的效果,步骤如下: 1. 获取需要倒影效果的图片,这里取原图片的一半 2. 添加颜色渐变到倒影图片上 具体的实现如下面代码所述,我们以一种自定义view的形式给出效果图,代码如下: package com.flection.view; import com.flection.main.R; import android.annotation.SuppressLint; import android.content.C

Android 开发中下载的图片 图库中看不到

Android 开发中下载的图片,但是代开图库的时候,不能马上看到图片.是因为android 内部有一个 扫描机制, 你下载之后图片已经存在了,但是没有被扫描到.所以你马上打开图库 看不到 下载的图片: 需啊哟加入下面的 代码 下载完成的hanlder 中处理: 直接调用就可以 MediaScannerConnection.scanFile( ShowBigImage.this, new String[] {url}, null, null);

Android开发解决加载图片OOM问题(非常全面 兼顾4.0以下系统)(by 星空武哥)

转载请标明:http://blog.csdn.net/lsyz0021/article/details/51295402 我们项目中经常会加载图片,有时候如果加载图片过多的话,小则导致程序很卡,重则OOM导致App挂了,今天翻译https://developer.Android.com/training/displaying-bitmaps/index.html,学习Google高效加载大图片的方法. 图片有各种形状和大小,但在大多数情况下,这些图片都会大于我们程序所需要的大小.比如说系统图片库

android开发 两张bitmap图片合成一张图片

场景:对android4.4解码gif(解码文章见前面一篇)后的图片进行每帧处理,android4.3 解码出来的每帧都很完整,但是到android4.4版本就不完整了,每帧都是在第一帧的基础上把被改变的显示出来了,所以需要再次合成每帧 如图效果: 合成后: 代码直接看: /** * 将2张图片合成 * @param downBitmap 底部图片 * @param upBitmap 置顶的图片 * @return */ public static Bitmap compoundBitmap(B

android开发之——获取相册图片和路径

Android开发获取相册图片的方式网上有很多种,这里说一个Android4.4后的方法,因为版本越高,一些老的api就会被弃用,新的api和老的api不兼容,导致出现很多问题. 比如:managedQuery()现在已经被getContentResolver().query()替代了,不过它们的参数都是一样的 再比如Android4.4后Intent(Intent.ACTION_GET_CONTENT);和Intent(Intent.ACTION_OPEN_DOCUMENT);两个方法所得到的

android 开发入门之背景图片

针对网上对于Activity设置背景图片的例子比较少,特献上自己的代码. android APP开发,在显示界面的时候,一般都会用到背景图片,而背景图片一般是全屏显示的.例如应用开启的欢迎屏幕. 原理: 在Activity初始化布局对象的时候,获取该布局实例,然后设置背景图片. 优点:可以动态加载图片. 示例代码如下:以下代码放置在Activity,onCreate方法中. //设置无标题栏 requestWindowFeature(Window.FEATURE_NO_TITLE); //加载布

Android开发教程--设置ImageView图片的显示比例

为适应不同屏幕的手机,ImageView图片的显示比例,可以使用android:scaleType属性来处理,处理方式的有以下几种: 1.在xml配置中使用:android:scaleType="centerCrop" 2.在代码中使用:   imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); ScaleType的值分别代表的意义:ImageView是Android中的基础图片显示控件,该控件有个重要的属性是ScaleTyp

Android开发学习之路-图片颜色获取器开发(1)

系列第一篇,从简单的开始,一步一步完成这个小项目. 颜色获取就是通过分析图片中的每个像素的颜色,来分析整个图片的主调颜色,有了主调颜色,我们可以用于图片所在卡片的背景或者标题颜色,这样整体感更加强烈. 有兴趣的可以学习下使用谷歌提供的Palette,也是做同样的工作,博客地址:http://www.cnblogs.com/Fndroid/p/5201236.html 先看效果图: 分析原理比较简单,就是获取图片的所有像素的颜色,然后统计,把统计的数目排序,然后返回给用户. 但是这里要先注意几个问