欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Android Bitmap像素级操作详解

程序员文章站 2022-04-29 09:12:50
一:什么是bitmap像素级的操作相信大家都知道一张jpg或png放大后会是一个个小格子,称为一个像素(px),而且一个小格子是一种颜色,也就是一张jpg或png图片就是很多颜色的合集,而这些合集信息...

一:什么是bitmap像素级的操作

相信大家都知道一张jpg或png放大后会是一个个小格子,称为一个像素(px),而且一个小格子是一种颜色,也就是一张jpg或png图片就是很多颜色的合集,而这些合集信息都被封装到了bitmap类中。你可以使用bitmap获取任意像素点,并修改它,对与某像素点而言,颜色信息是其主要的部分。所以像素级操作就是对一个个点的颜色超过。

二:载入与像素读写

在android sdk中,图像的像素读写能够通过getpixel与setpixel两个bitmap的api实现。

2.1 getpixel读取像素

bitmap api读取像素的代码例如以下:

得到像素pixel是32位的整数,四个字节分别相应透明通道、红色、绿色、蓝色通道。

getpixel参数说明:

  • col 表示的是第几行,下标从0开始。
  • row 表示的是第几列,下标从0开始。

比如获取第一个元素,也就是第一行第一列。

获取所有的颜色就是如下这样:

这里i代表列数,j代表行数,mcolarr[i][j]代表是一个图片第i列,第j行的像素颜色值。

2.2 setpixel写入像素

在讲写入像素前,我们先看一下如何创建一个bitmap,创建bitmap代码如下:

比如我们创建一个2*2的argb_8888图片:颜色分别是黑(0,0)、白(0,1)、红(1,0)、蓝(1,1)

如此,我们就创建了一个2行2列的bitmap。通过setpixel(col, row,color)方法为对应的点写入像素。

你是否会好奇,这样写入是否成功,那简单,通过上面我们知道getpixel可以读取像素点,我们验证一下。

首先,我们把创建的bitmap保存下来:

然后,对保存的bitmap做像素的读取工作,代码如下:

你会发现控制台的输出结果如下:

pixel_0_0 is:-16777216   

pixel_1_0 is:-65536   

pixel_0_1 is:-1   

看了这些你可能比较模糊,不懂这么长一串是什么意思,都是负数,其实那就是颜色值。color类中有几个方法可以方便获取argb分别对应的值,下面测试一下你就明白了。其实就是将int进行了位运算,分离出argb四个通道的值这里我简单转换一下:

通过上面的列子,你会发现,通过setpixel(col, row)可以写入像素,当然,写入像素同时也是可以指定透明度的,代码例如以下:

通过color.argb又一次组装成一个int的像素值。

使用bitmapfactory.decodefile或者decoderesource等方法实现载入图像的bitmap对象时。这些方法就会为要构建的bitmap对象分配合适大小的内存。假设原始的图像文件数据非常大,就会导致dvm不能分配请求的内存大小。从而导致oom(out of memory)问题。而通过配置bitmapfactory.option预先读取图像高度与宽带,图像进行适当的下採样,就能够避免oom问题的发生。预先仅仅获取图像高度与宽带的代码例如以下:

基于下採样载入超大bitmap图像的缩小版本号:

三:像素操作

通过上面的讲解,我们知道如何获取设写入像素颜色信息,拿到像素颜色信息,不就等于天下就是我的了吗?下面来电高级一点的像素操作。首先先讲一下android彩色图像灰度化。

3.1:android彩色图像灰度化

android彩色图像灰度化的三个简单方法:

  1. 灰度化方法一:灰度值gray = (max(red, green, blue) + min(red, green, blue))/2
  2. 灰度化方法二:灰度值gray = (red + green + blue)/3
  3. 灰度化方法三:灰度值gray = red0.3 + green0.59 + blue*0.11

代码实现例如以下:

bitmap图像镜像映射与亮度调整的代码实现例如以下:

3.2:bitmap的花样复刻

bitmap的花样复刻大致分如下几步实现:

1.bitmap复刻的粒子载体

2.初始化粒子:

3.正方形粒子的绘制(原图复刻)

4.复刻其他图片资源文件

只要是bitmap就行了,我们可以decode图片变成bitmap。注意:此处只是演示,画一张bitmap还是用原生的好,像素级的粒子化也有它的优势,比如运动。具体更具实际情况而定。

5.圆形复刻

注意: 在第四步复刻其他图片资源文件时,图片已经不是bitmap了,而是由一个个小正方形堆积而成并且拥有自己的颜色。我们可以利用它实现很多有趣的定西,比如画正方形,画个圆…。现在你明白像素级操作什么了吧。也许你会感叹,还能有更好玩的吗,当然有,后面还有更惊叹的呢。

6.其他形状复刻
更具像素单元,你可以用任意的图形更换粒子单元,或者各种形状的粒子混合适用,画出你喜欢的形状。比如我们绘制一个五角星:

四:颜色操作

关于颜色操作,可以使用colorfilter和colormatrix改变图片颜色,也可以采用“旁门左道”方式,毕竟通过上面的操作我们已经货可以获取像素点的颜色。

那就先将colorfilter和colormatrix改变图片颜色,然后再讲采用“旁门左道”方式。

4.1 使用colorfilter和colormatrix改变图片颜色

1.colormatrix改变图片颜色
颜色矩阵m是一个5*4的矩阵,在android中,颜色矩阵m是以一维数组m=[a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t]的方式进行存储的。如下图所示:

Android Bitmap像素级操作详解

他通过rgba四个通道来直接操作对应颜色,达到修改图像的效果。

第一行决定红色 r

第二行决定绿色 g

第三行决定蓝色 b

第四行决定了透明度 a

第五列是颜色的偏移量

原图的rgba的colormatrix颜色矩阵数组为:

[ 1, 0, 0, 0, 0,  

0, 1, 0, 0, 0,  

0, 0, 1, 0, 0, 

 0, 0, 0, 1, 0

]

在一张图片中,图像的rgba(红色、绿色、蓝色、透明度)值决定了该图片所呈现出来的颜色效果。而图像的rgba值则存储在一个5*1的颜色分量矩阵c中,由颜色分量矩阵c可以控制图像的颜色效果。颜色分量矩阵c如下所示:

Android Bitmap像素级操作详解

要想改变一张图片的颜色效果,只需要改变图像的颜色分量矩阵即可。通过颜色矩阵可以很方便的修改图像的颜色分量矩阵。假设修改后的图像颜色分量矩阵为c1,则有如图3所示的颜色分量矩阵计算公式。

Android Bitmap像素级操作详解

通常,改变颜色分量时可以通过修改第5列的颜色偏移量来实现,如下图所示的颜色矩阵m1,通过计算后可以得知该颜色矩阵的作用是使图像的红色分量和绿色分量均增加100,这样的效果就是图片泛黄(因为红色与绿色混合后得到黄色)。

Android Bitmap像素级操作详解

除此之外,也可以通过直接对颜色值乘以某一系数而达到改变颜色分量的目的。如下图所示的颜色矩阵m2,将绿色分量放大了2倍,这样的效果就是图片泛绿色。

Android Bitmap像素级操作详解

讲了这么多,下面直入正题,聊聊如何使用colormatrix改变图片颜色。

使用colormatrix改变图片颜色的步骤大致如下:

  • 通过bitmap.createbitmap()方法获得一个空白的bitmap对象。
  • 使用bitmap对象创建画布canvas, 然后创建画笔paint。
  • 定义colormatrix,并指定rgba矩阵。
  • 使用colormatrix创建一个colormatrixcolorfilter对象, 作为画笔的滤镜 paint.setcolorfilter(new colormatrixcolorfilter(colormatrix))。
  • 使用canvas.drawbitmap()方法把原图使用定义的paint画到空白的bitmap对象上即可获得改变rgba值后的图像。

最后更具如上步骤附上简单的代码如下:

布局代码:

控制逻辑代码:

2.colorfilter 改变图片颜色
colorfilter 改变图片颜色非常简单,使用如下:

这样的的两行代码就可以改变颜色了。下面主要介绍一下的setcolorfilter的第二个参数porterduff.mode。

porterduff,一个陌生的单词,百度翻译和谷歌翻译都查无来处,原因在于它是一个组合词汇,来源于 tomas proter(托马斯波特)和 tom duff(汤姆达)两个名字。这俩人是在图形混合方面的大神级人物,他们在 1984 年发表了论文,第一次提出了图形混合的概念,也是取了两人的名字命名。

android porterduff.mode 便是提供了图片的各种混合模式,可以分为两类:

  • alpha compositing modes(由俩大神的定义,包含 alpha 通道因素)
  • blending modes(不是俩大神的作品,不包含 alpha 通道因素)

具体的可以看官方文档对 porterduff.mode的介绍,我这里只说涉及到的 src_atop。

既然混合,两个图片,源图片和目标图片,如下:

Android Bitmap像素级操作详解

src_atop 混合模式效果如下图,只保留源图片和目标图片的相交部分,其他部分舍弃:

Android Bitmap像素级操作详解

总结:

合理使用 setcolorfilter() ,可以为 ui 好搭档节省了不少切图工作量,而且,同样能缩小了 apk 的体积。

3.其他方式
简单的使用旁门左道的方式实现图片的颜色改变。

图片黑白化的算法
以前在javascript用过,在python用过,现在终于用到java上了,不免感慨,语言*限,真理永恒。就像1+1=2是永远不变的。所以大家最好收集一下相关的真理,不管何时都不会过时,也不会错误。

灰色处理函数

颜色反转

五:粒子运动

4.1 将一个图片粒子化的方法

这里速度x方向是正负等概率随机数值,所以粒子会呈现左右运动趋势。有一定的y方向速度,但加速度ay向下,导致粒子向下运动,综合效果就是两边四散加坠落。要改变粒子的运动方式,只要改变粒子的这些参数就行了。

4.2 更新小球

4.3初始化时间流:valueanimator

4.4点击开启valueanimator

总结

好了,到了这里关于bitmap的像素级超过基本介绍完毕,但你会像素级操作后,你发做成更多炫酷有趣的东西,比如各种美颜滤镜变量算法等。

以上就是android bitmap像素级操作详解的详细内容,更多关于android bitmap详解的资料请关注其它相关文章!

相关标签: Android Bitmap