Два самых простых варианта, которые сработают именно для этой картинки:
1) RLE (run-length encoding). Любой поисковик выдаст кучу страниц по этой теме. А на пальцах - записываются пары: "значение" и "сколько раз подряд встретилось значение". Для указанного примера каждая строка превратится либо в 6, либо в 4, либо даже в 2 (последняя строка) числа.
2) Некоторый вариант создания-хранения "палитры". Возможные значения нумеруются (в данном случае будет всего 3 уникальных числа), и в зависимости от числа уникальных значений выбирается минимально необходимое количество битов, которыми можно будет представить данное число значений (в данном случае - 2 бита на число). Далее исходные данные записываются в виде двух блоков:
a) "Палитра". Число значений в палитре (одно число), вектор реальных значений (позиция в векторе будет являться уникальным "кодом" для значения, этот уникальный "код" будет при сжатии содержимого изображения записываться меньшим числом байт)
б) Сжатое изображение. Каждое исходное значение представляется меньшим числом битов, а значение этого набора битов будет отражать номер позиции этого исходного значения в палитре (чтобы можно было восстановить истинное значение при распаковке изображения).
Но тут при программировании будет много гемора с битовыми операциями