Mobile Development 27 min read

Android Image Compression Techniques and Luban Algorithm Analysis

This article provides a comprehensive overview of Android image compression, covering bitmap fundamentals, ARGB color model, size calculations, quality and dimension compression methods, the Luban algorithm, its implementation details, performance considerations, and related JPEG Huffman coding techniques.

Sohu Tech Products
Sohu Tech Products
Sohu Tech Products
Android Image Compression Techniques and Luban Algorithm Analysis

The article begins with an introduction to image compression principles on Android, emphasizing the importance of understanding bitmap representation, ARGB color channels, and the distinction between bit depth and color depth for accurate memory usage calculations.

It explains how to compute the memory footprint of a bitmap using its resolution and pixel format, and clarifies common misconceptions about the formula "resolution * pixel size" by considering device DPI scaling and resource directory densities.

Two primary compression approaches are discussed: quality compression, which reduces file size without changing dimensions, and size (sampling) compression, which downsamples the image. Sample Java code demonstrates quality compression using Bitmap.compress(Bitmap.CompressFormat.JPEG, quality, outputStream); and highlights the differences between JPEG, PNG, and WEBP formats.

The article then details sampling techniques such as nearest‑neighbour and bilinear resampling, providing code examples for both BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = 2; and matrix‑based scaling with Matrix matrix = new Matrix(); matrix.setScale(0.5f, 0.5f); .

Following this, the Luban compression library is examined. Its background, motivation to emulate WeChat’s image handling, and the step‑by‑step algorithm (ratio classification, boundary checks, size calculations, and iterative compression) are described. The original Luban implementation issues—fixed quality, lack of format options, no parallel processing, and repeated InputStream creation—are identified.

Proposed improvements include pre‑emptive memory checks, configurable quality, support for multiple output formats, coroutine‑based parallelism, InputStream reuse, and lifecycle management. The revised engine code shows how to compute an optimal sampling size, rotate images based on EXIF orientation, and perform quality compression with a configurable quality factor.

Further sections explore the Android graphics stack: the role of Skia as a glue layer between Java and native libraries (libjpeg, libpng, etc.), and how bitmap compression ultimately invokes native JPEG functions. The importance of Huffman coding in JPEG is explained, noting that the optimize_coding flag generates image‑specific Huffman tables, which can halve file size compared to default tables.

Since Android 7.0, optimize_coding is enabled by default via libjpeg‑turbo, improving compression quality. The article concludes with a custom native JPEG encoder written in C++ that demonstrates setting up jpeg_compress_struct , configuring color space, enabling Huffman optimization, and writing scanlines from ARGB data.

Mobile developmentAndroidimage compressionbitmapJPEGLuban
Sohu Tech Products
Written by

Sohu Tech Products

A knowledge-sharing platform for Sohu's technology products. As a leading Chinese internet brand with media, video, search, and gaming services and over 700 million users, Sohu continuously drives tech innovation and practice. We’ll share practical insights and tech news here.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.