Bitmap的图片压缩汇总

前言

Bitmap是Android中一种重要的图片处理机制,它可以用来获取图片的相关信息,同时可以对图片进行裁剪、缩放等操作,也可以指定图片格式进行保存。相信对于OOM再熟悉不过了,OOM的产生是一个非常头疼的事情,如果在加载图片的时候未对大图进行处理,它将会占用非常大的内存,这样就非常容易产生OOM。所以我们必须要有意识的对大图进行压缩加载,这样才能更好的保证App的正常运行与性能的稳定。

Bitmap大小计算

那么如果计算一张图片加载过程中所占的内存大小呢?在这之前,我们先来了解一下关于Bitmap两个主要配置。

CompressFormat

这是用来指定Bitmap的图片的压缩格式,在Bitmap中是一个Enum结构,主要表现为以下三种格式。

    public enum CompressFormat {
        JPEG    (0),
        PNG     (1),
        WEBP    (2);

        CompressFormat(int nativeInt) {
            this.nativeInt = nativeInt;
        }
        final int nativeInt;
    }
  • JPEG: 以JPEG算法进行压缩,压缩后的图片格式可以为.jpeg或者.jpg,这是一种有损压缩,没有透明度。
  • PNG:以PNG算法进行压缩,压缩后的图片格式是.png,这是一种无损压缩,可以有透明度。
  • WEBP:以WEBP算法进行压缩,压缩后的图片格式是.webp,这是一种有损压缩。相同质量下,webp比jpeg图像小40%,但webp图片的编码时间比jpeg长8倍。

Config

这是关于Bitmap像素存储的方式配置,不同的像素存储,对图片的质量也会有不同的影响。在Bitmap中是一个Enum结构,主要表现于以下四种格式。

  • ALPHA_8:每一个像素都只储存单一的透明度,即只有透明度,总共占8位,1字节。
  • ARGB_4444:每一个像素都以A(透明度)R(Red)G(Green)B(Blue)四部分组成,每部分占4位,总共占16位,2字节。由于这种格式的图片质量太差,所以中API 13就已经废弃了,推荐使用ARGB_8888。
  • ARGB_8888:每一个像素都以A(透明度)R(Red)G(Green)B(Blue)四部分组成,每部分占8位,总共32位,4字节。
  • RGB_565:每一个像素都以R(Red)G(Green)B(Blue)三部分组成,各个部分分别占5位,6位,5位,总共16位,2字节。

所以如果为了防止OOM对图片进行压缩,一般会使用RGB_565格式,因为ALPHA_8只有透明度,对于正常图片未意义;ARGB_4444显示的图片质量太差;ARGB_8888占用的内存最多。

如果加载的图片的宽度为1080、高度为675、Config为ARGB_8888。那么它占的内存为:1080 x 675 x 4 = 2916000.折算成M为2916000 / 1024 / 1024 = 2.78M。一种图片就近3M,如果加载10张或者100张,所占的内存可想而知。这样的话会很容易将内存消耗殆尽,同时对于Android App来说根本就不需要这么高清的图片,所以我们在加载图片的时候可以对其进行相应的处理,例如:对宽高进行缩放,亦或者将Config改我RGB_565。这样不仅有效的减小了内存的占用,同时也不影响图片的清晰度的展示。

下面我们来看下如何通过Bitmap与BitmapFactory来对图片进行处理

Bitmap相关

对于使用Bitmap进行图片的压缩处理,它主要提供了以下有效方法。

status return method name
boolean compress(Bitmap.CompressFormat format, int quality, OutputStream stream)
static Bitmap createBitmap(DisplayMetrics display, int[] colors, int width, int height, Bitmap.Config config)
static Bitmap createBitmap(DisplayMetrics display, int[] colors, int offset, int stride, int width, int height, Bitmap.Config config)
static Bitmap createBitmap(Bitmap source, int x, int y, int width, int height)
static Bitmap createBitmap(Bitmap src)
static Bitmap createBitmap(DisplayMetrics display, int width, int height, Bitmap.Config config)
static Bitmap createBitmap(Bitmap source, int x, int y, int width, int height, Matrix m, boolean filter)
static Bitmap createBitmap(int width, int height, Bitmap.Config config)
static Bitmap createBitmap(int[] colors, int offset, int stride, int width, int height, Bitmap.Config config)
static Bitamp createBitmap(int[] colors, int width, int height, Bitmap.Config config)
static Bitmap createScaledBitmap(Bitmap src, int dstWidth, int dstHeight, boolean filter)

compress

compress方法通过指定图片的CompressFormat格式与压缩百分比来对图片进行压缩处理,同时将压缩的图片保存到指定的outputStream中。我们来看下具体用法

val fs = FileOutputStream(path)
val out = ByteArrayOutputStream()
scaleBitmap.compress(Bitmap.CompressFormat.JPEG, 30, 

你可能感兴趣的:(Android,Android,Kotlin,Bitmap,图片压缩,源码解析)