【Android】Android图像处理—图像变换处理探究


Android图像处理—图像变换处理探究

此篇博客主要研究了通过各种方式来达到对图像形状变换的效果。

矩阵变换基础

图像的变换同样可以通过矩阵来实现。下面将介绍 平移变换、旋转变换 缩放变换以及错切变换四种变换方式。

1.平移变换

当我们要将一个点从x0,y0移动到x,y的时候,可以通过下图的矩阵变换来实现:

当如图的矩阵左乘原坐标矩阵后,就会得到一个平移到x,y的新坐标矩阵。

2.旋转变换

当我们想要将一个图像顺时针旋转θ角时, 通过如下的矩阵运算可以得到旋转后的坐标点的位置x,y。

3.缩放变换

想要将一个图片进行缩放就比较简单了,通过如下矩阵运算即可得到:

4.错切变换

错切变换比较少接触,效果大概是这样:

仍然是通过矩阵运算,将图像的坐标矩阵左乘如图的矩阵,即可得到:

通过矩阵方法调整图像

界面的实现

首先,我们新建一个ImageMatrixView,代码如下,用于显示一个原图和改变后的图像,用于对比变换前后的情况。

然后,再用如下的布局文件,以达到和之前颜色变换矩阵处一样的效果。

实现通过矩阵来改变图像

我们在代码中,分别通过两个数组来存储矩阵的值以及EditText,给每个EditText一个初始值,也就是我们的初等矩阵。然后当按下改变按钮后,则获取每个EditText的值并应用在ImageMatrixView中。

效果

如图,分别是图像的四种变换后的效果:

平移变换

旋转变换

缩放变换

错切变换

Android API来实现

其实,Android自带了api来给我们实现这四种变换:

  • matrix.setRotation() 旋转,参数为角度的值
  • matrix.setTranslate() 平移,参数分别为x轴、y轴的偏移量
  • matrix.setScale() 缩放,参数为横向与纵向的放大倍数
  • matrix.setSkew() 错切,参数为横向与纵向的k值
  • post 矩阵组合

前面四种与前文大同小异,但矩阵的组合运算在这里需要了解一下。

矩阵的组合运算

之前用矩阵进行图像变换的运算时,可以通过多种运算来达到图像变换叠加的作用,在这里同样可以,用法就是第一种变换用正常的setXXX方法,而后面的方法则用postXXX的方法即可,如:

Xfermode画笔风格处理图片

图层混合结构图

里面的第三张图以后的都是通过Src与Dst通过不同的混合形成的不同效果。

使用Xfermode将图片处理为圆角矩形

使用Xfermode之前,我们最好先将硬件加速关闭。通过setLayerType这个方法,传入LAYER_TYPE_SOFTWARE这个参数,第二个参数传入0,来禁用掉硬件加速。

这里,我们新建一个RoundXferModeView,目的是制作一个以圆角矩形的方式显示图片的View,首先让它继承自View,在里面定义一个原始的Bitmap以及处理后的Bitmap,以及一个画笔。之所以定义两个Bitmap是因为从资源文件获得的Bitmap是默认不可修改的,因此需要一个新的Bitmap来保存。

在initView中,我们做了一些之前颜色变换用到的初始化工作,如新建Canvas等等。通过我们之前的图层混合结构图可以知道,当两张图片进行混合的时候,如果我们选择了SrcIn这个模式,取的就是两张图片交集的部分。如果我们下面绘制一个圆角矩形,而上面绘制一张图片,则产生的效果就是一个圆角矩形的图片。(在Android的设计中,第一个绘制的就是Dst,第二个则是Src)因此,我们先在Canvas上绘制一个圆角矩形,之后再为mPaint调用setXfermode方法,传入一个PorterDuffDuffXfermode,将我们的SRC_IN模式传递进去。最后在Canvas中绘制我们的Bitmap。

效果如图:

Shader风格处理图片

主要为了达成渐变的效果,有诸如线性渐变,环形渐变,扫描渐变,组合渐变等。虽然名字不同,显示的效果也不同,但是它们都属于颜色的一种渐变效果。而只有BitmapShader比较特殊,它属于图像渐变。通过BitmapShader,我们同样可以实现一个圆角矩形的图片显示View。

使用BitmapShader将图片处理为圆角矩形

实际上BitmapShader就是以Bitmap为背景绘制某个形状。

这里我们新建了一些变量后,直接重写onDraw方法。初始化了bitmap以及paint后,在初始化BitmapShader时我们传入bitmap,并把x,y轴都设置为CLAMP模式,然后为Painter设置这个shader。最后绘制一个圆,然后将画笔设置为绑定了shader的paint。

BitmapShader的三种模式
- CLAMP 拉伸(这里的拉伸是以最后一个像素点的颜色来填充)
- REPEAT 重复
- MIRROR 镜像

效果如图:


Android Developer in GDUT