Bitmap类01_浅探

Bitmap类解析

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类,用于配置颜色信息:

image-20211118222049929

解析:

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都没啥区别)

image-20211118222651777

Bitmap压缩方式配置

除了 Config 类的另一个枚举类则是 CompressFormat ,用于配置压缩方式:

image-20211118223700906

解析:

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);

效果呈现:

image-20211119122028717

缩放、旋转、移动:

通过 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);

效果呈现:

image-20211119121952922

图像的保存与释放

请参考之后关于缓存的文章

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类简述

image-20211119174735069

(此处的坐标轴)

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)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值