文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Android 基于Bitmap的四种图片压缩方式

2024-04-02 19:55

关注

知识点介绍

Android 中图片主要以 Bitmap 的形式存在,所以压缩图片主要就是减少 Bitmap 的大小。Bitmap 的大小可以通过如下的公式计算得到:size = width * height * 单个像素所占字节数。因此压缩图片通过改变公式中的三个变量即可实现。

单个像素所占空间大小在 Android 中有多种,详见如下

格式 所占空间 说明
Bitmap.Config.ALPHA_8 1B 该种格式表示图片只有透明度没有颜色,1个像素占用8位
Bitmap.Config.ARGB_4444 2B 该种格式表示图片透明通道 A 及颜色 R、G、B 各占用4位,共16位
Bitmap.Config.ARGB_8888 4B 该种格式表示图片透明通道 A 及颜色 R、G、B 各占用8位,共32位
Bitmap.Config.RGB_565 2B 该种格式表示图片没有透明通道,颜色 R、G、B 各占用5、6、6位,共16位

Android 中加载图片默认用的是 ARGB_8888 格式,所以加载一张3000 * 4000 的图片默认占用的空间为 45MB 左右,这个值还是很大的😂

测试代码


fun showBitmapInfo(bitmap: Bitmap){
        Log.d("Tag","压缩后的图片大小:${bitmap.byteCount/1024/1024}MB,宽度:${bitmap.width},高度:${bitmap.height}")
}

结果

正文

接下来介绍四种压缩方式

1、质量压缩

质量压缩主要通过 Bitmap.compress()实现,方法介绍



public boolean compress(CompressFormat format, int quality, OutputStream stream) {
}

CompressFormat 表示图片压缩格式,Android 源码中包含了五种格式

格式名 解释
CompressFormat.JPEG 压缩为JPEG格式。 quality 0表示压缩为最小大小。 100表示压缩以获得最大视觉质量。
CompressFormat.PNG 压缩为PNG格式。 PNG是无损的,因此quality被忽略。
CompressFormat.WEBP 压缩为WEBP格式。 quality 0表示压缩为最小大小。 100表示压缩以获得最大视觉质量。 从Build.VERSION_CODES.Q ,值100导致文件采用无损WEBP格式。 否则,文件将为有损WEBP格式
CompressFormat.WEBP_LOSSY 压缩为WEBP有损格式。 quality 0表示压缩为最小大小。 100表示压缩以获得最大视觉质量。
CompressFormat.WEBP_LOSSLESS 压缩为WEBP无损格式。 quality是指投入多少精力进行压缩。 值0表示快速压缩,导致文件大小相对较大。 100表示要花费更多时间进行压缩,从而使文件更小。

测试代码



fun getCompressBitmap(bitmap: Bitmap,quality:Int): Bitmap {
    val baos = ByteArrayOutputStream()
    bitmap.compress(Bitmap.CompressFormat.JPEG, quality, baos)
    val byte = baos.toByteArray()
    val ins = ByteArrayInputStream(byte)
    val bm = BitmapFactory.decodeStream(ins)
    ins.close()
    baos.close()
    return bm
}

效果

根据上面的日志,你会看到质量压缩并不能改变图片在内存中的大小,因为质量压缩既不能改变图片分辨率也不能改变图片的单个像素大小。

那么你可能有些疑问:既然不能改变大小,那么还费这么大功夫转化而且图片还失真是为了什么?

答:源码中对于compress方法的解释是,将位图的压缩版本写入指定的输出流。所以应该是对输出流中的字节数有影响

验证


val baos = ByteArrayOutputStream()
bitmap.compress(Bitmap.CompressFormat.JPEG, quality, baos)
val byte = baos.toByteArray()
Log.d("Tag","quality=$quality,byte-size=${byte.size}")

结果真的是对输出流的字节数有影响

2、采样率压缩

BitmapFactory.Options 中有个属性 inSampleSize,系统中采样率压缩就是通过该属性



 public int inSampleSize;

直接上代码


    
    fun calculateInSampleSize(options: BitmapFactory.Options, reqWidth: Int, reqHeight: Int): Int {
        val height = options.outHeight
        val width = options.outWidth
        var inSampleSize = 1
        if (height > reqHeight || width > reqWidth) {
            val heightRatio = round(height.toFloat() / reqHeight.toFloat()).toInt()
            val widthRatio = round(width.toFloat() / reqWidth.toFloat()).toInt()
            inSampleSize = if (heightRatio < widthRatio) heightRatio else widthRatio
        }
        return inSampleSize
    }

    
    fun getSmallBitmap(filePath: String,reqWidth: Int,reqHeight: Int): Bitmap {
        val options = BitmapFactory.Options()
        options.inJustDecodeBounds = true //不加载 bitmap 进内存,只获取他的基本信息
        BitmapFactory.decodeFile(filePath, options)
        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight)
        options.inJustDecodeBounds = false
        return BitmapFactory.decodeFile(filePath, options)
    }

结果

采样率压缩的方式使用的还是挺多的,因为我们获取到的图片它的尺寸可能很大,但是我们在手机上显示的可能不需要那么大,那我们就将图片缩放成我们需要的大小。

3、缩放法压缩

这种方法主要是依赖 Matrix 矩阵变换的方式对图片进行处理。Matrix 中有很多对图片变换的 api 这里只使用它的缩放功能,其他功能可以自行了解

代码


    
    fun matrixBitmap(bitmap: Bitmap,scale:Float):Bitmap{
        val matrix = Matrix()
        matrix.setScale(scale,scale)
        var bm = Bitmap.createBitmap(bitmap,0,0,bitmap.width,bitmap.height,matrix,true)
        return bm
    }

当设置缩放比为0.5时,图片整体就缩放为原来的1/4

4、RGB_565 通过改变图片格式来实现压缩

系统默认使用的是ARGB_8888的格式,所以我们只要改变这个 options 值就能实现


fun rgb565Bitmap(filePath: String):Bitmap{
        val options = BitmapFactory.Options()
        options.inPreferredConfig = Bitmap.Config.RGB_565
        var bitmap = BitmapFactory.decodeFile(filePath,options)
        return bitmap
}

结果图片变成了原图的一半

总结

对于图片的压缩,首先可以先将图片格式改为 RGB_565,这样图片先减小一半,然后对于图片的显示可以使用采样率压缩或者缩放压缩的方式将图片的分辨率改为我们显示的大小,如果是要将图片上传服务器那么可以使用质量压缩的方式,但是这种方式不支持 png 格式的图片。

以上就是Android 基于Bitmap的四种图片压缩方式的详细内容,更多关于Android Bitmap图片压缩的资料请关注编程网其它相关文章!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-移动开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯