Bitmap类是对图像进行处理的类,可以获取图像信息,进行图像颜色变换等操作
在安卓中,Bitmap指的是一张图片,可以是 .png 或者 .jpg 等其他常见的图像格式
参考API:
Bitmap | Android Developers
Bitmap - Android中文版 - API参考文档 (apiref.com)
如何使用Bitmap加载图片需要使用 BitmapFactory 类提供的四个方法:
decodeFile() :从文件中加载Bitmap对象
decodeResource() :从资源中加载Bitmap对象
decodeStream() :从输入流中加载Bitmap对象
decodeByteArray() :从字节数组中加载Bitmap对象
使用举例:
从资源中加载一张命名为 test 的图片,再加载到 ImageView 控件中
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.test); imageView.setImageBitmap(bitmap);Bitmap颜色配置
Bitmap类中有两个枚举类,其中一个为Config类,用于配置颜色信息:
解析:
Bitmap.Config.ALPHA_8 :颜色信息只由透明度组成,占8位。
Bitmap.Config.ARGB_4444:颜色信息由透明度与R(Red),G(Green),B(Blue)四部分组成,每个部分都占4位,总共占16位。
Bitmap.Config.ARGB_8888:颜色信息由透明度与R(Red),G(Green),B(Blue)四部分组成,每个部分都占8位,总共占32位。是Bitmap默认的颜色配置信息,也是最占空间的一种配置。
Bitmap.Config.RGB_565:颜色信息由R(Red),G(Green),B(Blue)三部分组成,R占5位,G占6位,B占5位,总共占16位。
通常我们优化Bitmap时,当需要做性能优化或者防止OOM,通常会使用 RGB_565 这个配置,因为 ALPHA_8 只有透明度,显示一般图片没有意义,而 ARGB_4444 显示图片不清楚,ARGB_8888 则占用内存最多。
测试一下:
主要代码如下:
// 加载原图
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.test);
imageView.setImageBitmap(bitmap);
// 测试其他颜色模式
Bitmap bitmap1 = bitmap.copy(Bitmap.Config.ALPHA_8, true);
Bitmap bitmap2 = bitmap.copy(Bitmap.Config.ARGB_4444, true);
Bitmap bitmap3 = bitmap.copy(Bitmap.Config.ARGB_8888, true);
Bitmap bitmap4 = bitmap.copy(Bitmap.Config.RGB_565, true);
imageView1.setImageBitmap(bitmap1);
imageView2.setImageBitmap(bitmap2);
imageView3.setImageBitmap(bitmap3);
imageView4.setImageBitmap(bitmap4);
运行后点击按钮效果如下:
(可能由于图片原因,或者显示器等问题,似乎除了ALPHA_8都没啥区别)
Bitmap压缩方式配置除了 Config 类的另一个枚举类则是 CompressFormat ,用于配置压缩方式:
解析:
Bitmap.CompressFormat.JPEG:表示以JPEG压缩算法进行图像压缩,压缩后的格式可以是 .jpg 或者 .jpeg ,是一种有损压缩。
Bitmap.CompressFormat.PNG:表示以PNG压缩算法进行图像压缩,压缩后的格式可以是 .png ,是一种无损压缩。
Bitmap.CompressFormat.WEBP:表示以WebP压缩算法进行图像压缩,压缩后的格式可以是 .webp ,是一种有损压缩。
关于三种格式的优劣,可以在自行搜索,或者参考Webp 相对于 PNG、JPG 有什么优势? - 知乎 (zhihu.com)
使用Bitmap的方法操作图片 裁剪:使用 createBitmap(Bitmap source, int x, int y, int width, int height) 方法可以对Bitmap位图进行裁剪
其中x,y为裁剪时,x和y轴开始的第一个像素
width 和 height 则是剪切时的宽度和高度
(ps:x+width要小于source的宽度,y+height同理)
使用:
主要代码:
TextView textView = findViewById(R.id.text1); ImageView imageView1 = findViewById(R.id.image_1); ImageView imageView2 = findViewById(R.id.image_2); ImageView imageView3 = findViewById(R.id.image_3); Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.test); Bitmap bitmap1 = Bitmap.createBitmap(bitmap, 0, 0, 100, 100); Bitmap bitmap2 = Bitmap.createBitmap(bitmap, 0, 0, 530, 530); // 530也可以使用bitmap.getHeight()和bitmap.getWidth()代替 String out = "Height = " + bitmap.getHeight() + " and Width = " + bitmap.getWidth(); textView.setText(out); imageView1.setImageBitmap(bitmap); imageView2.setImageBitmap(bitmap1); imageView3.setImageBitmap(bitmap2);
效果呈现:
缩放、旋转、移动:通过 createBitmap(Bitmap source, int x, int y, int width, int height, Matrix m, boolean filter) 方法,不但能实现裁剪
还能够实现如缩放等其他效果
其中,Matrix类代表一个矩阵对象,对其的简述可以参考本文下方的Matrix类简析
而参数 filter 为 true 时表示 source 会被过滤,仅仅当 m 操作不仅包含移动操作,还包含别的操作时才适用。
使用:
主要代码:
Matrix matrix = new Matrix(); // 向左旋转45度,参数为正时表示向右旋转 matrix.postRotate(-45); Bitmap bitmap3 = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); imageView4.setImageBitmap(bitmap3);
效果呈现:
图像的保存与释放请参考之后关于缓存的文章
BitmapFactory类对BitmapFactory类的使用主要是上述的四个方法加载图片
BitmapFactory.decodeResource 加载的图片可能会经过缩放,该缩放目前是放在 java 层做的,效率比较低,而且需要消耗 java 层的内存。因此,如果大量使用该接口加载图片,容易导致OOM错误
BitmapFactory.decodeStream 不会对所加载的图片进行缩放,相比之下占用内存少,效率更高。
这两个接口各有用处,如果对性能要求较高,则应该使用 decodeStream;如果对性能要求不高,且需要 Android 自带的图片自适应缩放功能,则可以使用 decodeResource。
BitmapFactory.option类BitmapFactory.Options 类是 BitmapFactory 对图片进行解码时使用的一个配置参数类,其中定义了一系列的public成员变量,每个成员变量代表一个配置参数。
参考API:
BitmapFactory.Options | Android Developers
BitmapFactory.Options - Android中文版 - API参考文档 (apiref.com)
Matrix类简述Matrix类本身不能对图片进行操作,但是可以结合其他的API实现图片的旋转平移等效果
Matrix类中包含一个3X3的矩阵,对图片的操作分为四种:
(1)Translate :平移变换
方法为 setTranslate() ,该方法接收两个浮点数作为参数,分别表示x和y轴上移动的数量
第一个参数若为整数则表示在x轴上向右移动相应距离,第二个参数同理
(2)Scale :缩放变换
方法为 setScale() 接收两个浮点数作为参数,分别表示在每个轴上所产生的缩放量
第一个参数是x轴的缩放比例,而第二个参数是y轴的缩放比例
(3)Rotate :旋转变换
方法之一为 setRotate() 接收一个浮点数表示旋转的角度
也可以在角度后再传入两个参数作为旋转的中心点
默认围绕点(0,0),正数将顺时针旋转图像,而负数将逆时针旋转图像
使用举例:
其中默认点是图像的左上角,如:
Matrix matrix = new Matrix(); matrix.setRotate(15);
另外,也可以使用旋转的角度及围绕的旋转点作为参数调用setRotate方法。选择图像的中心点作为旋转点,如:
matrix.setRotate(15, bmp.getWidth()/2, bmp.getHeight()/2);
(4)Skew :错切变换
在数学上又称为 Shear mapping (可译为“剪切变换”)或者 Transvection(缩并),是一种比较特殊的线性变换
错切变换的效果就是让所有点的 x 坐标(或者 y 坐标)保持不变,而对应的 y 坐标(或者 x 坐标)则按比例发生平移
平移的大小和该点到 x 轴(或 y 轴)的垂直距离成正比
错切变换,属于等面积变换,即一个形状在错切变换的前后,其面积是相等的
而在Android的API中对于每一种变换都提供了三种操作方式:
(1)set(用于设置Matrix中的值)
(2)post(后乘,根据矩阵的原理,相当于左乘)
(3)pre(先乘,相当于矩阵中的右乘)
默认时,这四种变换都是围绕(0,0)点变换的,当然可以自定义围绕的中心点,通常围绕中心点。
参考API:
Matrix | Android Developers
Matrix - Android中文版 - API参考文档 (apiref.com)
本文参考文章:Android Bitmap最全面详解 - 掘金 (juejin.cn)
玩转Android Bitmap - 简书 (jianshu.com)
聊聊 Bitmap 的一些知识点 - 掘金 (juejin.cn)
浅谈BitmapFactory.Options - 简书 (jianshu.com)
Android—Matrix类的使用 - mmy–博客园 - 博客园 (cnblogs.com)



