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:
- Quality compression: unchanged memory, reduced bytes.length after compression, suitable for transmission, PNG invalid
- Sampling rate compression (Options) : Change the width and height, reduce the number of pixels, and use a certain sampling algorithm
- Scaling compression (Matrix) : change width and height, reduce pixels, adopt certain scaling algorithm (related to digital image processing)
- 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