This article introduces four ways of Bitmap compression, the relevant code can be seen: githhub-gdtesthub

Android images exist in the form of bitmap, so the memory occupied by bitmap directly affects the memory occupied by the application. First of all, we need to know how to calculate the memory occupied by Bitmap:

Number of pixels x Pixel Size = Image length (in pixels) x Image width (in pixels) x number of bytes occupied by a pixel

Possible compression methods:

  1. Quality compression: unchanged memory, reduced bytes.length after compression, suitable for transmission, PNG invalid
  2. Sampling rate compression (Options) : Change the width and height, reduce the number of pixels, and use a certain sampling algorithm
  3. Scaling compression (Matrix) : change width and height, reduce pixels, adopt certain scaling algorithm (related to digital image processing)
  4. RGB_565: Changes the number of bytes

First, quality compression

Boilerplate code

val baos = ByteArrayOutputStream()
// Mass compression method, where 100 means no compression, the compressed data is stored in baOS
bmRaw.compress(Bitmap.CompressFormat.JPEG, 50, baos)
val bais = ByteArrayInputStream(baos.toByteArray())
val bmScaled = BitmapFactory.decodeStream(bais, null.null)
Copy the code

Description:

Quality compression using JPEG format

bmRaw.compress(Bitmap.CompressFormat.JPEG, 50, baos)
Copy the code
  • For a transparent image (PNG), the memory, width and height remain the same, and bytes.length is reduced. The image will lose transparency, the transparency will go black,
  • For an opaque image (PNG, JPG), the memory, width and height remain unchanged, and bytes.length is reduced.

Quality compression using PNG format

bmRaw.compress(Bitmap.CompressFormat.PNG, 50, baos)
Copy the code
  • For a transparent image (PNG), there is no effect
  • It has no effect on an opaque image (PNG, JPG)

Second, sampling rate

Boilerplate code

val options = BitmapFactory.Options()
options.inSampleSize = 2
val bmScaled = BitmapFactory.decodeResource(resources, drawableId, options)
// Decode method:
BitmapFactory.decodeFile()
BitmapFactory.decodeRecourse()
BitmapFactory.decodeStream()
BitmapFactory.decodeByteArray()
Copy the code

Description:

That is, if inSampleSize = 2, a sampled pixel is equal to 2 pixels on the X-axis and 2 pixels on the Y-axis. That is, one pixel after sampling is equal to the previous 2*2=4 pixels.

Three, scaling method

Boilerplate code

val bmRaw = BitmapFactory.decodeResource(resources, drawableId, null)
val matrix = Matrix()
matrix.setScale(0.5f, 0.5f)
val bmScaled = Bitmap.createBitmap(bmRaw, 0.0, bmRaw.width, bmRaw.height, matrix, true)
Copy the code

Description:

Similar to the sampling rate method.

Four, RGB_565

Boilerplate code

val options = BitmapFactory.Options()
options.inPreferredConfig = Bitmap.Config.RGB_565
val bmNew = BitmapFactory.decodeResource(resources, drawableId, options)
Copy the code

Description:

ALPHA_8 represents an 8-bit Alpha bitmap, 1 byte per pixel ARGB_4444 represents a 16-bit ARGB bitmap, 2 bytes per pixel ARGB_8888 represents a 32-bit ARGB bitmap, 4 bytes per pixel RGB_565 represents a 16-bit RGB bitmap, 2 bytes per pixel

So set RGB_565 directly:

  • For a transparent image (PNG), the memory, width and height remain the same, and the Bitmap does not lose its transparency.
  • For an opaque image (PNG, JPG), the width and height of the same, memory reduced.

A copy reduces memory, but the resulting bitmap loses transparency and becomes black.

val bmScaled = bmRaw.copy(Bitmap.Config.RGB_565, true)
Copy the code