How Run-Length Encoding (RLE) is used in Image Compression
Let’s see how Run-Length Encoding (RLE) — the same logic as the String Compression problem — is applied in image compression.
🧩 What Is Run-Length Encoding (RLE)?
Run-Length Encoding is a lossless compression algorithm that reduces file size by storing consecutive repeating values as one value + count.
It’s used in formats like:
- BMP, TIFF, and PDF
- Fax machines
- Early video game graphics
- Simple icons, pixel art, and mask images
🖼️ Example: A Tiny 2D Black & White Image
Let’s imagine a 6×6 image made of only black (1) and white (0) pixels:
Image matrix:
0 0 0 1 1 0
0 0 1 1 1 0
0 0 0 0 0 0
1 1 0 0 0 0
1 1 1 0 0 0
1 0 0 0 0 0
🧠 Step 1 — Flatten the image into a 1D sequence:
000110 001110 000000 110000 111000 100000
→ 000110001110000000110000111000100000
🧮 Step 2 — Apply Run-Length Encoding (count consecutive runs):
| Value | Count | Encoded |
|---|---|---|
| 0 | 3 | 03 |
| 1 | 2 | 12 |
| 0 | 1 | 01 |
| 0 | 2 | 02 |
| 1 | 3 | 13 |
| 0 | 1 | 01 |
| 0 | 6 | 06 |
| 1 | 2 | 12 |
| 0 | 4 | 04 |
| 1 | 3 | 13 |
| 0 | 3 | 03 |
| 1 | 1 | 11 |
| 0 | 5 | 05 |
So the RLE encoded sequence is:
[(0,3), (1,2), (0,1), (0,2), (1,3), (0,1), (0,6), (1,2), (0,4), (1,3), (0,3), (1,1), (0,5)]
Or, compact form:
03 12 01 02 13 01 06 12 04 13 03 11 05
🧩 Step 3 — Decoding (Decompression)
To reconstruct the image:
- Read pair by pair
- Expand each
(value, count)→ e.g.,(1,3)→111 - Rebuild into the original 6×6 grid
Result → Exactly same image! ✅ That’s why RLE is called lossless.
⚙️ Real-World Example in Code
Python Implementation
def rle_encode(data):
encoding = []
count = 1
for i in range(1, len(data)):
if data[i] == data[i - 1]:
count += 1
else:
encoding.append((data[i - 1], count))
count = 1
encoding.append((data[-1], count))
return encoding
def rle_decode(encoded):
result = []
for value, count in encoded:
result.extend([value] * count)
return result
pixels = [0,0,0,1,1,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0]
encoded = rle_encode(pixels)
decoded = rle_decode(encoded)
print("Encoded:", encoded)
print("Decoded == Original:", decoded == pixels)
✅ Output:
Encoded: [(0, 3), (1, 2), (0, 1), (0, 2), (1, 3), ...]
Decoded == Original: True
🧠 Why It Works Well
RLE works best when:
- There are lots of consecutive identical values
- e.g. black-and-white icons, drawings, QR codes, barcodes, etc.
But it fails (i.e., no compression benefit) when:
- Data is highly varied (like photos with noise or color gradients)
🖌️ Visual Analogy
Imagine describing a line of pixels to someone:
👩💻 “There are 5 white pixels, then 3 black pixels, then 10 white pixels.”
That’s RLE — it saves space by describing runs, not listing every pixel.