Matrix_java matrix.setrecttorect是如何计算得到的-程序员宅基地

技术标签: android  matrix  Android  

初识Matrix

第一次见到Matrix是在图片缩放的时候,Matrix(矩阵),在网上搜索一番,觉得还是直接写下记录一下方便以后复习翻阅

public class MyView extends View {

Bitmap mBitmap;

public MyView(Context context) {
    super(context);
}

public MyView(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
}

public Bitmap getBitmap() {
    return mBitmap;
}

public void setBitmap(Bitmap bitmap) {
    mBitmap = bitmap;
}

public boolean isEmpty() {
    return mBitmap == null;
}

@Override
protected void onDraw(Canvas canvas) {

    if (mBitmap != null) {
        Matrix matrix = new Matrix();
        canvas.drawBitmap(mBitmap, matrix, null);
    }
}
}  

xml布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.jinxiong.matric.MainActivity">

   <com.example.jinxiong.matric.MyView

       android:layout_width="match_parent"
       android:layout_height="match_parent"
       android:id="@+id/myImageView"
       />
</RelativeLayout>  

Activity

public class MainActivity extends AppCompatActivity {

ImageLoader mImageLoader;
MyView mImageView;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ImageLoaderConfiguration imageLoaderConfiguration = ImageLoaderConfiguration.createDefault(this);
    ImageLoader.getInstance().init(imageLoaderConfiguration);

    mImageLoader = ImageLoader.getInstance();
    mImageView = (MyView) this.findViewById(R.id.myImageView);

    Bitmap bitmap = mImageLoader.loadImageSync("drawable://" + R.drawable.test);
    mImageView.setBitmap(bitmap);

}
}


可以看到这张图片是大于手机屏幕的,需要对图片进行缩小,那么就要使用到Matrix了

 @Override
    protected void onDraw(Canvas canvas) {
    if (mBitmap != null) {
        Matrix matrix = new Matrix();
        matrix.setScale(0.5f, 0.5f);
        canvas.drawBitmap(mBitmap, matrix, null);
    }
}  

那么就可以看到
这里写图片描述
那么Matrix那么厉害,他究竟是什么?

走进Matrix

matrix就是矩阵的意思,
这里写图片描述
正常我们通过

Matrix matrix = new Matrix();  

创建的矩阵式单位矩阵:
这里写图片描述
我们可以通过

matrix.toShortString()  

打印出来

[1.0, 0.0, 0.0][0.0, 1.0, 0.0][0.0, 0.0, 1.0]  

我认为Matrix最重要的就是实现变换,基本的变换有四种
1. 缩放
2. 错切
3. 平移
4. 旋转
参数控制:
这里写图片描述

缩放

在初次创建Matrix 对象的时候,Matrix的缩放两个参数都是1,表示按原本尺寸显示,

matrix.setScale();
matrix.postScale();
matrix.preScale();

有这三个方法,参数都是一样,先说下两个参数的情况
这里写图片描述
setScale 就是在你原有的矩阵中 插入两个值,一个是1行2列 ,一个是2行1列中的值
而preScale 就是矩阵的乘,把原有的矩阵放在乘的左边,目标矩阵放在右边(因为矩阵的左乘和右乘是不一样的),
这里写图片描述
左边的第一行与右边的第一列的值相乘相加后变成结果矩阵的第一行第一列的值,左边第一行与右边第二列的值相乘相加结果变成借股票矩阵的第一行第二列的值,左边的第一行和右边的第三列相乘相加的值变为结果矩阵的第一行第三列的值,以此类推

而postScale 也是这样,只不过把源矩阵和目标矩阵的位置交换,那么结果自然是不一样的了

而当它为四个参数的时候

public void setScale(float sx, float sy, float px, float py) {
    native_setScale(native_instance, sx, sy, px, py);
}

后面两个新参数就是缩放中心的坐标,如果使用两位参数的setScale的话,默认的缩放中心坐标就是(0,0)

@Override
protected void onDraw(Canvas canvas) {

    if (mBitmap != null) {
        Matrix matrix = new Matrix();
        matrix.setScale(0.5f, 0.5f, mBitmap.getWidth() / 2, mBitmap.getHeight() / 2);
        canvas.drawBitmap(mBitmap, matrix, null);
    }

} 

将刚刚那张图片以图片中心为缩放中心缩小一半,
这里写图片描述
对于这三种方法设置图片的缩放,对于set方法,是直接将值付给相应的矩阵的位置的值,对源矩阵来说,改变的只是那两个缩放的值,但是对于pre 和 post的话,因为涉及到矩阵的乘法,还是会对源矩阵一些本来的值会造成影响,可能这并不是你想要的,至于什么时候使用哪一种,具体还是看自己想要怎么样

错切

错切也有三个方法和两种参数格式,跟scale 是一样的,这里就以setSkew为例子

matrix.setSkew(0.5f,0f);

这里写图片描述

matrix.setSkew(0f,0.5f);

这里写图片描述

matrix.setSkew(0.5f,0.5f);

这里写图片描述

matrix.setSkew(0.5f, 0.5f, mBitmap.getWidth() / 2, mBitmap.getHeight() / 2);   

这里写图片描述

旋转

旋转也是对应着三个方法

matrix.setRotate(45);   

这里写图片描述原点为中心旋转45度

matrix.setRotate(180, mBitmap.getWidth() / 2, mBitmap.getHeight() / 2);  

这里写图片描述图片中心为中心,180度

平移

这个也是很简单的方法

matrix.setTranslate(0,200);  

这里写图片描述
这里的translation 和 view.setTranslation 相似,但是移动 的偏移量是不同的位置
这里写图片描述

setPolyToPoly

这里写图片描述
这个特效怎么实现尼 ,答案就是setPolyToPoly

@Override
protected void onDraw(Canvas canvas) {

    if (mBitmap != null) {
        Matrix matrix = new Matrix();

        float[] src = new float[]{
                0,0,
                mBitmap.getWidth(),0,
                mBitmap.getWidth(),mBitmap.getHeight(),
                0,mBitmap.getHeight()
        };

        float[] dst = new float[]{
                0, 0,
                mBitmap.getWidth()/2, 100,
                mBitmap.getWidth()/2, mBitmap.getHeight() - 100,
                0, mBitmap.getHeight()
        };

        matrix.setPolyToPoly(src, 0, dst, 0, 4);

        canvas.drawBitmap(mBitmap, matrix, null);
    }

} 

poly就是多边形的意思,

/**
 * Set the matrix such that the specified src points would map to the
 * specified dst points. The "points" are represented as an array of floats,
 * order [x0, y0, x1, y1, ...], where each "point" is 2 float values.
 *
 * @param src   The array of src [x,y] pairs (points)
 * @param srcIndex Index of the first pair of src values
 * @param dst   The array of dst [x,y] pairs (points)
 * @param dstIndex Index of the first pair of dst values
 * @param pointCount The number of pairs/points to be used. Must be [0..4]
 * @return true if the matrix was set to the specified transformation
 */
public boolean setPolyToPoly(float[] src, int srcIndex,
                             float[] dst, int dstIndex,
                             int pointCount)  

src:代表的是一个坐标数组,这个多边形的点的坐标,srcIndex代表的是从前面的数组哪一个下标开始,而
dst就是你想要变成的多边形的坐标数组,

setRectToRect

这里写图片描述
也是使用一个源矩形和目标矩形进行变换,这是使图片居中(感觉微信的图片是不是这样实现尼?)

@Override
protected void onDraw(Canvas canvas) {

    if (mBitmap != null) {
        Matrix matrix = new Matrix();

        RectF src = new RectF(0, 0, mBitmap.getWidth(), mBitmap.getHeight());
        RectF dst = new RectF(0, 0, getWidth(), getHeight());

        matrix.setRectToRect(src, dst, Matrix.ScaleToFit.CENTER);

        canvas.drawBitmap(mBitmap, matrix, null);
    }

}
} 

最后

基本的使用就是这样 ,更多详细可以看着个大神blog
http://www.gcssloop.com/customview/Matrix_Basic
http://www.gcssloop.com/customview/Matrix_Method

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/lijinxiong520/article/details/52727859

智能推荐

解决报错ImportError: unique_cuda.cpython-37m-x86_64-linux-gnu.so: undefined symbol: _ZN6caffe28T_undefined symbol: _zn6caffe28typemeta21_typemetada-程序员宅基地

文章浏览阅读3.1k次。最近在调试有关pytorch-geometric包的代码的时候遇到了这个错误,具体报错如下所示:ImportError: /home/amax/.conda/envs/SGE/lib/python3.7/site-packages/torch_sparse/unique_cuda.cpython-37m-x86_64-linux-gnu.so: undefined symbol: _ZN6caffe28TypeMeta21_typeMetaDataInstanceIN3c108BFloat16EEEP_undefined symbol: _zn6caffe28typemeta21_typemetadatainstanceideepkns_6detail

vS2015+Tesseract4编译及配置步骤_cppan下载-程序员宅基地

文章浏览阅读1.3k次。vS2015+Tesseract4编译及配置一、第一步就是下载相关工具1.下载cppan。https://cppan.org/client/这里下载的是cppan-master-Windows-client.zip。解压后是cppan.exe。将cppan.exe所在的文件路径加入到环境变量Path中,cppan就设置完成了。下载Cmake。https://cmake.org/downlo..._cppan下载

php:扩展的安装与使用_php 安装第三方扩展怎me使用?-程序员宅基地

文章浏览阅读468次。什么是扩展php扩展就是php核心并不支持的功能,然后可以通过扩展的方式进行扩展PHP的功能,常见的扩展如MySQL,gb2等等。查看php安装了那些扩展方法一:通过phpinfo()函数,进行查看方法二:执行php -m 命令:php -m配置扩展php.ini 文件路径(mac为例):/usr/local/etc/php/7.3/php.iniphp扩展路径:开启某个扩展,把..._php 安装第三方扩展怎me使用?

利用Sklearn对MNIST手写数据集开始一个简单的二分类判别器项目(在这个过程中学习关于模型性能的评价指标,如accuracy,precision,recall,混淆矩阵)_sklearn实现二分类 知乎-程序员宅基地

文章浏览阅读1.9k次,点赞2次,收藏9次。Sklearn实现MNIST手写数据集的二分类判别器项目一、获取MNIST手写数据集二、分割数据集,创建测试集三、训练一个二分类器一、获取MNIST手写数据集需要注意的是直接运行下面的代码可能不能直接下载成功,可以从这里先提前(https://download.csdn.net/download/x454045816/10157075) 下载,放到mldata文件夹中,就不会报错了from ..._sklearn实现二分类 知乎

android逆向终极版,x32dbg/x64dbg之条件断点生成器改良第三终结版-程序员宅基地

文章浏览阅读1k次。本帖最后由 冥界3大法王 于 2021-4-15 08:27 编辑image.png (503.65 KB, 下载次数: 0)2021-4-14 12:48 上传大家好接下来我们说的是条件断点。还不会用的同学们注意了,其实这个东西还是比较简单的。无论你之前是否使用过OllyDbg或x32dbg/x64dbg应该对这个东西并不陌生。当我们来到某个VA地址(虚拟地址时)此时你会对当前的寄存器的某个数值..._x32dbg 条件断点

Failed to read artifact descriptor for org.apache.maven.plugins:maven-resources-plugin:jar:2.6-程序员宅基地

文章浏览阅读1.4k次。新建或导入maven项目失败,并出现如下错误:Could not calculate build plan: Plugin org.apache.maven.plugins:maven-resources-plugin:2.7 or one of its dependencies could not be resolved: Failed to read artifact descriptor..._failed to read artifact descriptor for org.apache.maven.plugins:maven-resour

随便推点

电离层穿刺点坐标计算_电离层穿刺点的经纬度计算-程序员宅基地

文章浏览阅读3.8k次,点赞2次,收藏25次。转载自:http://yinflying.top/2017/09/709电离层穿刺点(ionospheric pierce point,IPP)的定义:电磁波源由外空间向地球上某点传播时,该电磁波束射入电离层时的交点。显然,电离层穿刺点是建立在电离层单层薄壳模型的基础上的,如图所示:图中(\varphi_{PP} , \lambda_{PP}) 代表电离层穿刺点的纠度和经度坐标,而(\va..._电离层穿刺点的经纬度计算

Project build error: Non-resolvable parent POM for com.gzl.cn:springboot01:0.0.1-SNAPSHOT: Could not_non-resolvable parent pom for com.itheima:springbo-程序员宅基地

文章浏览阅读6.3k次,点赞2次,收藏3次。问题描述这是在通过maven来构建springboot项目的时候报的错,有的时候xml报些小红×没啥,但是这次不一样了。以下是报错截图导完依赖发现连maven dependencies都没有,这就更别说运行了,就是纯属的pom依赖错误。下面截图是调试好之后的样子。解决过程首先这块我的依赖是从别的地方复制的,网上很多说法都是说让更换依赖版本,更改完就好了,其实不是,我就不信这个邪,同样都是空项目为啥别的版本就可以,然后最终找到了结果,就是复制的依赖可能中间产生空格导致的。特别是pdf文件复制依_non-resolvable parent pom for com.itheima:springboot_01_quickstart:0.0.1-sna

基于CUBEMX和STM32C8T6的同轴麦轮小车制作(二)——HAL库接受jy61p陀螺仪数据,并解决数据溢出卡死问题。_麦轮陀螺仪pid-程序员宅基地

文章浏览阅读5.6k次,点赞8次,收藏42次。基于CUBEMX和STM32C8T6的同轴麦轮小车制作(二)——HAL库接受jy61p陀螺仪数据,并解决数据溢出卡死问题本文利用STM32C8T6中的串口1于JY61P实时通信,并用串口2将其角度打印出来,期间遇到了串口数据溢出卡死的问题,在编写ORE错误回调函数后得到有效解决,其分为CUBEMX基本配置、函数编写、效果展示3个部分。一、CUBEMX基本配置1.配置串口1、2,此处要注意串口1的波特率要和JY61P的一致(默认是9600,具体可以在上位机中调节),开启串口1的接收中断。2.配置时_麦轮陀螺仪pid

TypeScript----类型注解之数组与对象_typescript数组包对象的注解怎么写-程序员宅基地

文章浏览阅读267次。TypeScript类型注解之数组// 初始化为空数组的时候需要添加类型注解let baskec: string[] = ['mike', 'james'];const dates = [new Date(), new Date()];// 二维数组const students = [['mike', 'nike'],['zhang'],['lise', 'san']];//提取值的时候帮助推断const player = baskec[0];const players = baske_typescript数组包对象的注解怎么写

使用array_multisort来根据数组中的两个字段排序_数组按照两个字段排序-程序员宅基地

文章浏览阅读484次。array_multisort(array_column($rankList, 'score'), SORT_DESC, array_column($rankList, 'topInvestorScore'), SORT_DESC, $rankList);如果数组中的score相等,那么按照topInvestorScore排序_数组按照两个字段排序

从零搭建vue框架_vue 如何从头开始搭建框架-程序员宅基地

文章浏览阅读219次。框架搭建vue-cli创建项目命令:vue create newnft根据需要回车选择打包路径配置1.router.js配置const router = new VueRouter({ mode: 'history', base: 'mobile',//路径配置 routes})2.vue.config.js配置publicPath: "/mobile/",// 与router.js一致服务器环境区分1.建立.env系列文件根据项目需求,在根目录新建3个文件,.en_vue 如何从头开始搭建框架

推荐文章

热门文章

相关标签