本篇博客主要讲解一下如何处理对一个Bitmap对象进行处理,包括:缩放、旋转、位移、倾斜等。在最后将以一个简单的Demo来演示图片特效的变换。

1. Matrix概述

对于一个图片变换的处理,需要Matrix类的支持,它位于"android.graphics.Matrix"包下,是Android提供的一个3*3 矩阵工具类:

它本身不能对图像或View进行变换,但它可与其他API结合来控制图形、View的变换,如Canvas。Matrix提供了一些方法来控制图片变换:

  • setTranslate(float dx,float dy):控制Matrix进行位移。
  • setSkew(float kx,float ky):控制Matrix进行倾斜,kx、ky为X、Y方向上的比例。
  • setSkew(float kx,float ky,float px,float py):控制Matrix以px、py为轴心进行倾斜,kx、ky为X、Y方向上的倾斜比例。
  • setRotate(float degrees):控制Matrix进行depress角度的旋转,轴心为(0,0)。
  • setRotate(float degrees,float px,float py):控制Matrix进行depress角度的旋转,轴心为(px,py)。
  • setScale(float sx,float sy):设置Matrix进行缩放,sx、sy为X、Y方向上的缩放比例。
  • setScale(float sx,float sy,float px,float py):设置Matrix以(px,py)为轴心进行缩放,sx、sy为X、Y方向上的缩放比例。

  之前有提过,图片在内存中存放的就是一个一个的像素点,而对于图片的变换主要是处理图片的每个像素点,对每个像素点进行相应的变换,即可完成对图像的变换。上面已经列举了Matrix进行变换的常用方法,下面以几个Demo来讲解一下如何通过Matrix进行变换。

2. Matrix缩放

private void bitmapScale(Bitmap bitmap, float x, float y) {Bitmap afterBitmap = Bitmap.createBitmap((int) (bitmap.getWidth() * x),(int) (bitmap.getHeight() * y), bitmap.getConfig());Canvas canvas = new Canvas(afterBitmap);Matrix matrix = new Matrix();matrix.setScale(x, y);printMatrixValue(matrix, "bitmapScale");Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);canvas.drawBitmap(bitmap, matrix, paint);iv_preview.setImageBitmap(afterBitmap);}

3. Matrix旋转

private void bitmapRotate(Bitmap bitmap, float degree) {Bitmap afterBitmap = Bitmap.createBitmap(bitmap.getWidth(),bitmap.getHeight(), bitmap.getConfig());Canvas canvas = new Canvas(afterBitmap);Matrix matrix = new Matrix();// degree: 角度// px:      中心点的X// py:      中心点的Ymatrix.setRotate(degree, (float) bitmap.getWidth() / 2, (float) bitmap.getHeight() / 2);printMatrixValue(matrix, "bitmapRotate");Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);canvas.drawBitmap(bitmap, matrix, paint);iv_preview.setImageBitmap(afterBitmap);}

4. Matrix位移

private void bitmapTranslate(Bitmap bitmap, float dx, float dy) {// 需要根据移动的距离来创建图片的拷贝图大小Bitmap afterBitmap = Bitmap.createBitmap((int) (bitmap.getWidth() + dx),(int) (bitmap.getHeight() + dy), bitmap.getConfig());Canvas canvas = new Canvas(afterBitmap);Matrix matrix = new Matrix();matrix.setTranslate(dx, dy);printMatrixValue(matrix, "bitmapTranslate");Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);canvas.drawBitmap(bitmap, matrix, paint);iv_preview.setImageBitmap(afterBitmap);}

5. Matrix倾斜

private void bitmapSkew(Bitmap bitmap, float dx, float dy) {// 根据图片的倾斜比例,计算变换后图片的大小,Bitmap afterBitmap = Bitmap.createBitmap(bitmap.getWidth()+ (int) (bitmap.getWidth() * dx), bitmap.getHeight()+ (int) (bitmap.getHeight() * dy), bitmap.getConfig());Canvas canvas = new Canvas(afterBitmap);Matrix matrix = new Matrix();// 设置图片倾斜的比例
        matrix.setSkew(dx, dy);printMatrixValue(matrix, "bitmapSkew");Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);canvas.drawBitmap(bitmap, matrix, paint);iv_preview.setImageBitmap(afterBitmap);}

6. Matrix变换注意事项

  上面几个小方法演示了如何使用Matrix进行变换,但是还有几点需要额外注意一下:

  • 对于一个从BitmapFactory.decodeXxx()方法加载的Bitmap对象而言,它是一个只读的,无法对其进行处理,必须使用Bitmap.createBitmap()方法重新创建一个Bitmap对象的拷贝,才可以对拷贝的Bitmap进行处理。
  • 因为图像的变换是针对每一个像素点的,所以有些变换可能发生像素点的丢失,这里需要使用Paint.setAnitiAlias(boolean)设置来消除锯齿,这样图片变换后的效果会好很多。
  • 在重新创建一个Bitmap对象的拷贝的时候,需要注意它的宽高,如果设置不妥,很可能变换后的像素点已经移动到"图片之外"去了。

7. 示例代码

package com.yongdaimi.android.ffapitest;import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;import java.util.Arrays;import javax.security.auth.login.LoginException;public class MatrixDemoActivity extends AppCompatActivity implements View.OnClickListener {private ImageView iv_preview;private ImageView iv_origin_view;private Button bt_scale;private Button bt_rotate;private Button bt_translate;private Button bt_skew;@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_matrix_demo);initView();}private void initView() {iv_preview = findViewById(R.id.iv_preview);iv_origin_view = findViewById(R.id.iv_origin_view);bt_scale = findViewById(R.id.bt_scale);bt_scale.setOnClickListener(this);bt_rotate = findViewById(R.id.bt_rotate);bt_rotate.setOnClickListener(this);bt_translate = findViewById(R.id.bt_translate);bt_translate.setOnClickListener(this);bt_skew = findViewById(R.id.bt_skew);bt_skew.setOnClickListener(this);}@Overridepublic void onClick(View view) {// Bitmap bitmap = ((BitmapDrawable) iv_origin_view.getDrawable()).getBitmap();Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);switch (view.getId()) {case R.id.bt_scale:bitmapScale(bitmap, 4, 4);break;case R.id.bt_rotate:bitmapRotate(bitmap, 180);break;case R.id.bt_translate:bitmapTranslate(bitmap, 200, 200);break;case R.id.bt_skew:bitmapSkew(bitmap, 0.2f, 0.4f);break;default:break;}}private void bitmapScale(Bitmap bitmap, float x, float y) {Bitmap afterBitmap = Bitmap.createBitmap((int) (bitmap.getWidth() * x),(int) (bitmap.getHeight() * y), bitmap.getConfig());Canvas canvas = new Canvas(afterBitmap);Matrix matrix = new Matrix();matrix.setScale(x, y);printMatrixValue(matrix, "bitmapScale");Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);canvas.drawBitmap(bitmap, matrix, paint);iv_preview.setImageBitmap(afterBitmap);}private void bitmapRotate(Bitmap bitmap, float degree) {Bitmap afterBitmap = Bitmap.createBitmap(bitmap.getWidth(),bitmap.getHeight(), bitmap.getConfig());Canvas canvas = new Canvas(afterBitmap);Matrix matrix = new Matrix();// degree: 角度// px:      中心点的X// py:      中心点的Ymatrix.setRotate(degree, (float) bitmap.getWidth() / 2, (float) bitmap.getHeight() / 2);printMatrixValue(matrix, "bitmapRotate");Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);canvas.drawBitmap(bitmap, matrix, paint);iv_preview.setImageBitmap(afterBitmap);}private void bitmapTranslate(Bitmap bitmap, float dx, float dy) {// 需要根据移动的距离来创建图片的拷贝图大小Bitmap afterBitmap = Bitmap.createBitmap((int) (bitmap.getWidth() + dx),(int) (bitmap.getHeight() + dy), bitmap.getConfig());Canvas canvas = new Canvas(afterBitmap);Matrix matrix = new Matrix();matrix.setTranslate(dx, dy);printMatrixValue(matrix, "bitmapTranslate");Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);canvas.drawBitmap(bitmap, matrix, paint);iv_preview.setImageBitmap(afterBitmap);}private void bitmapSkew(Bitmap bitmap, float dx, float dy) {// 根据图片的倾斜比例,计算变换后图片的大小,Bitmap afterBitmap = Bitmap.createBitmap(bitmap.getWidth()+ (int) (bitmap.getWidth() * dx), bitmap.getHeight()+ (int) (bitmap.getHeight() * dy), bitmap.getConfig());Canvas canvas = new Canvas(afterBitmap);Matrix matrix = new Matrix();// 设置图片倾斜的比例
        matrix.setSkew(dx, dy);printMatrixValue(matrix, "bitmapSkew");Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);canvas.drawBitmap(bitmap, matrix, paint);iv_preview.setImageBitmap(afterBitmap);}public void printMatrixValue(Matrix matrix, String methodName) {float[] empty_matrix = new float[9];matrix.getValues(empty_matrix);Log.i("xp.chen", "methodName: "+methodName + ", " +Arrays.toString(empty_matrix));}}

运行结果: 

2019-05-09 16:16:40.142 8279-8279/com.yongdaimi.android.ffapitest I/xp.chen: methodName: bitmapScale, [4.0, 0.0, 0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 1.0]
2019-05-09 16:16:44.015 8279-8279/com.yongdaimi.android.ffapitest I/xp.chen: methodName: bitmapRotate, [-1.0, -0.0, 192.0, 0.0, -1.0, 192.0, 0.0, 0.0, 1.0]
2019-05-09 16:16:50.593 8279-8279/com.yongdaimi.android.ffapitest I/xp.chen: methodName: bitmapTranslate, [1.0, 0.0, 200.0, 0.0, 1.0, 200.0, 0.0, 0.0, 1.0]
2019-05-09 16:16:53.470 8279-8279/com.yongdaimi.android.ffapitest I/xp.chen: methodName: bitmapSkew, [1.0, 0.2, 0.0, 0.4, 1.0, 0.0, 0.0, 0.0, 1.0]

本文转自:

Android--Matrix图片变换处理

转载于:https://www.cnblogs.com/yongdaimi/p/10839479.html

Matrix: android 中的Matrix (android.graphics.Matrix) (转)相关推荐

  1. android中的滤镜,android 实现滤镜效果

    最近在看关于自定义控件的东西,顺便看到了关于滤镜的东西,就写出来分享一下 这个有三个已知子类,写一个滤镜效果,只需要第一个已知子类就够用了,这个类构造方法public ColorMatrixColor ...

  2. android中oncreate方法,Android textView 中 onCreate 方法的改变

    我在main.xml上使用 Layout Editor创建了一个textview名称是textView1. 我想使用一个自定义的字体,所以我在onCreate方法中创建了下面的代码,但是好像不能识别t ...

  3. android中textcolor属性,android – EditText和TextView textColorPrimary不遵循API lt;21的主题颜色...

    在设计工具栏视图以使其适用于API 21及以下版本时存在一些问题,但我认为我有这个styles.xml @color/colorPrimary @color/colorPrimaryDark @col ...

  4. android中px单位,android中像素单位dp、px、pt、sp的比较

    dp(dip): device independent pixels(设备独立像素). 不同设备有不同的显示效果,这个和设备硬件有关,一般我们为了支持WVGA.HVGA和QVGA 推荐使用这个,不依赖 ...

  5. android中内存泄露,Android中的内存泄露

    编辑推荐: 本文来自于csdn,本文主要从java的内存模型讲起,最终举出几个内存泄露的例子和解决方案. java运行时内存模型 具体信息:http://gityuan.com/2016/01/09/ ...

  6. android中的 listview,Android中ListView的初步认识(一)

    ListView是安卓开发中常用的组件之一,它的作用是在一个垂直的列表中展现出所需的项目.接下来,我们看一下ListView的实现方法: 第一种 是常见的在XML中定义然后在activity中使用fi ...

  7. android中viewpager+fragment,Android开发之ViewPager+Fragment

    使用步骤 1.Activity的布局文件 android:id="@+id/viewpager" android:layout_width="wrap_content&q ...

  8. android ffmpeg 优点_在Android中使用FFmpeg(android studio环境)

    1.首先我们需要一个已经编译好的libffmpeg.so文件.(怎么编译是个大坑,可以参考windows环境下编译android中使用的FFmpeg,也可以用网上下载的现成的,本文相关的github项 ...

  9. android中自定义 toast,android 自定义Toast样式和显示方式

    问题: 1.android 开发中如果不停的触发显示Toast,会造成Toast一个接一个的弹出,非常影响用户体验. 2.android设备有千万个,每个设备的Toast的背景有可能不一样,造成在应用 ...

  10. android中搜索对话框,android – 如何使用onSearchRequested()调用搜索对话框

    我正在尝试实现搜索对话框,我无法显示活动中的搜索. 我在我的清单文件中定义了我的主要活动,此活动向用户显示他们必须选择的选项列表.其中一个选项是"搜索"选项. android:na ...

最新文章

  1. excel如何输入毫秒级时间
  2. bert 是单标签还是多标签 的分类_标签感知的文档表示用于多标签文本分类(EMNLP 2019)...
  3. oracle存储过程转mysql存储过程修改方法
  4. 免费2款标注工具实操(内含下载链接)
  5. matlab 图像分块及恢复
  6. Delphi程序开启XP的ClearType显示效果
  7. 基于SSM的大学拍卖网站(含文档)
  8. layui 工具条实现分页
  9. ff14服务器延迟滑步,ff14滑步是什么意思
  10. linux定时执行脚本
  11. python selenium无头浏览器
  12. ppt背景图片php,ppt背景图片怎么设置 ppt幻灯片制作视频
  13. Oauth2认证图解
  14. 硬件基础知识-二极管基础
  15. ZVK13(参考VK13)查销售价格
  16. 替罪羊树(Scapegoat Tree)
  17. Golang面试题整理
  18. abc云支付php,凉秋易支付,免签约支付平台,彩虹易支付,abc云支付云钱包,云支付,云结算,支付接口,支付营销,易支付,微信支付,支付宝,QQ钱包,个人支付接口,免签支付接口...
  19. 计算机桌面图标出现蓝框,win10桌面快捷图标蓝框怎么去除 附黑色方块去除/白色方块修复的方法步骤...
  20. 微策略2017年秋招线下笔试+技术面+在线测评+主管面总结

热门文章

  1. HTMLCSS常见问题整理(四)
  2. PHP 二分查找(详细)
  3. CodeForces 362B Petya and Staircases
  4. Retrofit:类型安全的REST客户端for 安卓Java
  5. issues:close 云端 STS 启动报找不到 jdk
  6. 如何通过一个结构体成员变量的地址找到该结构体的首地址?[备忘]
  7. [bzoj1008] [HNOI2008]越狱
  8. canvas学习之柱状图
  9. 总结常见的ES6新语法特性
  10. JavaScript程序开发(十四)—函数声明与函数表达式