- Код: (c) CIWH 2018, MIT License
- Тестовые изображения: все права принадлежат создателям
- Интерфейс
- Открытие и сохранение обычных и сжатых изображений
- 3 цветовых пространства RGB, YCbCr, HSV
- 2 алгоритма: FastHaarTransform, DiscreteCosineTransform
- Выбор целевого качества в процентах для каждого канала
- Разбиение изображения на блоки указанного размера
- Пиксели, не вошедшие в блоки, не теряются
- Обход каждого блока построчно или зиг-загом
- Линейный или сквозной мердж блоков перед сжатием
- Сжатие с помощью gzip
- Отображение MSE, PSNR
- Изображение конвертируется в
float[]
с нужной цветовой схемой - Разбиение на блоки и остаток
- К каждому блоку применяется прямое преобразование
- Малозначящие коэффициенты обнуляются
- Если надо, каждый блок обходится зиг-загом
- Блоки укладываются в байтовый плоский массив
- За ним укладывается остаток
- Всё это сжимается gzip
- Перед сжатыми данными записывается заголовок c мета-данными
- Считывается заголовокс мета-данными
- Сжатые данные разжимаются gzip
- Массив байт представляется в виде массива флоатов
- Восстанавливаются блоки
- Если надо - зигзаговый обход блоков восстанавливается на линейный
- К каждому блоку применяется обратное преобразование
- Блоки восстанавливаются в изображение
- В изображение дописывается остаток
float[]
с получившимися данными переводится в Image и отображается на экране
-
Заголовк (11 байт):
u8 version
версия программы, в которой был сохранен файлu16 width
ширина в пикселяхu16 height
высота в пикселяхu8 colorScheme
(0 = RGB | 1 = YCbCr | 2 = HSV) - цветовая схемаu8 method
(0 = FHT | 1 = DCT) - вид преобразованияu16 blockSize
(2 | 4 | 8 | 16 | 32 | 64 | 128 | 256 | 512) - размер стороны блокаu8 travelMode
(0 = Линейный | 1 = Зиг-заг) - обход блоковu8 crossMerge
(0 = false, 1 = true) - линейный или сквозной мердж
-
Сжатые данные (остальные байты):
byte[] compressedBytes
байты сжатые gzip
После разжатия byte[] compressedBytes
его нужно кастануть в float[]
, он будет иметь размер width * height * 3
Общее количество блоков totalBlocksAmount
можно узнать с помщью ImageUtils.getTotalBlocksAmount(width, height, blockSize)
В первых totalBlocksAmount * blockSize * blockSize * 3
элементах будут лежать уложенные блоки
В оставшихся элементах будет лажать остаток, не влезший в блоки, его размер можно узнать с помощью ImageUtils.getRemainderSize(width, height, blockSize)
- Остаток записывается построчно и состоит из 2 секций:
- a
horizontalBlocksAmount * blockSize <= x < width
0 <= y < verticalBlocksAmount * blockSize
- b
0 <= x < width
verticalBlocksAmount * blockSize <= y < height
- a