У меня есть этот код Scala, который использует Java Deflator/Inflator.
def compress(bytes: Array[Byte]): Array[Byte] = {
val deflater = new java.util.zip.Deflater
val baos = new ByteArrayOutputStream
val dos = new DeflaterOutputStream(baos, deflater)
dos.write(bytes)
baos.close
dos.finish
dos.close
baos.toByteArray
}
def decompress(bytes: Array[Byte]): String /*Array[Byte]*/ = {
val deflater = new java.util.zip.Inflater()
val baos = new ByteArrayOutputStream(512)
val bytesIn = new ByteArrayInputStream(bytes)
val in = new InflaterInputStream(bytesIn, deflater)
var go = true
while (go) {
val b = in.read
if (b == -1)
go = false
else
baos.write(b)
}
baos.close
in.close
// String(byte[] bytes, Charset charset)
new String(baos.toByteArray, "ASCII")
}
Мне нужно сжать BitSet, который имеет только один бит (100-й бит из 13 x 8 = 104 бит).
val bs = new util.BitSet()
bs.set(100)
val ba = bs.toByteArray
val z = gzip.compress(ba)
println(ba.size)
println(ba.mkString(":"))
println(z.size)
println(z.mkString(":"))
Я ожидаю резкого уменьшения размера, но в результате я сохраняю только один байт.
13
0:0:0:0:0:0:0:0:0:0:0:0:16
12
120:-100:99:96:64:0:1:0:0:29:0:17
Являются ли ожидаемые результаты для Java Deflator? Есть ли лучший компрессор для этого случая?
Являются ли ожидаемые результаты для Java Deflator?
Это то, чего я ожидал бы. Алгоритм сжатия "спящий" предназначен для сжатия больших файлов. Для крошечного файла (13 байт) накладные расходы в кодировке, вероятно, будут сбалансированы (или даже превышают) сжатие, которое будет достигнуто.
Есть ли лучший компрессор для этого случая?
Я бы не ожидал, что любой из алгоритмов сжатия, поддерживаемых стандартными библиотеками Java, будет намного лучше. Если вам нужна хорошая производительность на крошечных растровых изображениях, вам, вероятно, понадобится создать собственный компрессор с первых принципов.
Например, разреженное растровое изображение может быть представлено в виде последовательности чисел (в данном случае byte
значений), которые обозначают биты, которые были установлены, или как последовательность чисел, представляющих прогоны последовательных или нулей.
Я думаю, что проблема в кодированных данных GZIP содержит информацию заголовка, которая занимает байты. Это обычно не имеет значения, поскольку размер данных для сжатия обычно намного больше.
ЕСЛИ у вас есть в основном нули (или любые прогоны одинаковых значений) и несколько байтов чего-то другого, возможно, кодировка длины пробега лучше.
Если у вас действительно есть только 1 бит, тогда вы можете придумать свою собственную кодировку, которая кодирует только смещение этого единственного бита, если битсет установлен на фиксированную длину.