Mengapa metode kompresi (lossless) dari banyak gambar png serupa ini tidak efektif?


21

Saya baru saja menemukan hal berikut: Saya meletakkan beberapa salinan identik gambar png ke dalam folder dan kemudian mencoba untuk mengompresi folder itu dengan metode berikut:

  • tar czf folder.tar.gz folder/
  • tar cf folder.tar folder/ && xz --stdout folder.tar > folder.tar.xz (yang ini bekerja dengan baik untuk gambar yang identik, namun untuk gambar yang sama, keuntungannya nol)
  • zip -r folder.zip folder/

Ketika saya memeriksa ukuran .tar.gz, .tar.xz, .zipsaya menyadari bahwa itu adalah hampir sama dengan salah satu folder/.
Saya mengerti bahwa gambar png itu sendiri mungkin memiliki tingkat kompresi yang tinggi dan karena itu tidak dapat dikompresi lebih lanjut. Namun ketika menggabungkan banyak gambar png yang serupa (dalam hal ini bahkan identik) ke arsip dan kemudian mengompresi arsip saya akan mengharapkan ukuran yang diperlukan berkurang secara nyata. Dalam hal gambar identik, saya harapkan ukuran kira-kira ukuran gambar tunggal.


2
Perilaku ini hanya hadir dengan file png?
pdexter

7
Tidak membuat ini sebagai jawaban karena menjawab pertanyaan yang tidak diminta, tetapi jika Anda tahu Anda akan mengompres banyak gambar yang hampir identik, Anda selalu bisa mengganti semua gambar tetapi yang pertama dengan biner berbeda dengan gambar pertama. Dengan asumsi gambar tidak berisik, Anda akan mendapatkan output yang sangat dapat dikompresi, dan gambar asli masih dapat direproduksi.
Baldrickk

Jika Anda menggunakan file yang tidak dikompresi (mis. .bmp) File tar.gz harus dapat memanfaatkan kesamaan tersebut. (Setidaknya jika kesamaannya banyak piksel yang identik)
CodesInChaos

1
Saya tidak tahu apa-apa tentang itu, tetapi menurut Wikipedia, format arsip "ZPAQ" mendukung deduplikasi, yang saya percaya adalah yang Anda cari. en.wikipedia.org/wiki/ZPAQ#Deduplication
coneslayer

Anda mencoba mengompres sesuatu yang sudah dikompres. Lihat Di Sini
Kyle Khalaf

Jawaban:


34

Lihat bagaimana cara kerja algoritma kompresi. Setidaknya mereka dalam keluarga Lempel-Ziv ( gzip menggunakan LZ77 , ziptampaknya sebagian besar juga , dan xz menggunakan LZMA ) mengompres secara lokal : Persamaan yang terletak jauh satu sama lain tidak dapat diidentifikasi.

Rinciannya berbeda antara metode, tetapi intinya adalah bahwa pada saat algoritma mencapai gambar kedua, sudah "lupa" awal yang pertama. Dan seterusnya.

Anda dapat mencoba dan secara manual mengubah parameter dari metode kompresi; jika ukuran jendela (LZ77) resp. ukuran blok / bongkahan (metode yang lebih baru) setidaknya sebesar dua gambar, Anda mungkin akan melihat kompresi lebih lanjut.


Perhatikan bahwa hal di atas hanya benar-benar berlaku jika Anda memiliki gambar identik atau hampir tidak terkompresi gambar identik . Jika ada perbedaan, gambar yang dikompresi mungkin tidak terlihat sama dalam memori. Saya tidak tahu bagaimana kompresi PNG bekerja; Anda mungkin ingin memeriksa representasi hex dari gambar yang Anda miliki untuk substring bersama secara manual.

Juga perhatikan bahwa bahkan dengan parameter yang diubah dan redundansi untuk dieksploitasi, Anda tidak akan turun ke ukuran satu gambar. Kamus yang lebih besar berarti ukuran kata-kata yang lebih besar, dan bahkan jika dua gambar persis sama, Anda mungkin harus menyandikan yang kedua menggunakan beberapa kata-kata (yang menunjuk ke yang pertama).


3
Jawaban yang lebih akurat: gzip dan zip menggunakan codec DEFLATE yang sama, yang didasarkan pada teori LZ77 + Huffman.
Nayuki

Ya! Itu setengah dari cerita; lihat jawaban saya untuk bagian yang lain, atau jawaban yang bagus dari Nayuki .
DW

1
for posterity: format arsip yang mengeksploitasi redudansi di antara file dengan menggabungkan file menjadi satu gumpalan dan mengompresi yang disebut solid . tidak yakin apakah ada istilah lain untuk tingkat 'soliditas' menengah, dll.
underscore_d

22

Kenapa ini terjadi? Sebenarnya ada dua efek berbeda yang terjadi di sini:

  • Setiap file dikompresi secara independen. Beberapa program arsip - termasuk zip - kompres setiap file secara independen, tanpa memori dari satu file ke file lain. Dengan kata lain, setiap file dikompresi secara terpisah, maka file yang dikompresi tersebut disatukan menjadi arsip.

  • Ingatan jangka pendek. Beberapa program arsip dapat menggunakan informasi tentang satu file untuk membantu mengompres file berikutnya dengan lebih baik. Mereka secara efektif menyatukan file, lalu mengompres hasilnya. Ini merupakan peningkatan.

    Lihat juga jawaban Nayuki untuk diskusi lebih lanjut tentang ini.

    Namun, ada masalah kedua. Beberapa skema kompresi - termasuk zip, gzip, dan bzip2 - memiliki memori terbatas. Mereka memampatkan data saat itu juga, dan mengingat data 32KB yang lalu, tetapi mereka tidak mengingat apa pun tentang data yang terjadi jauh lebih awal dalam file. Dengan kata lain, mereka tidak dapat menemukan data duplikat jika duplikat terjadi lebih jauh dari 32KB terpisah. Akibatnya, jika file yang identik pendek (lebih pendek dari sekitar 32KB), algoritma kompresi dapat menghapus data yang digandakan, tetapi jika file yang sama panjang, algoritma kompresi disemprot dan menjadi tidak berharga: tidak dapat mendeteksi semua duplikat dalam data Anda. (Bzip mengingat data 900KB yang lalu, bukan 32KB.)

    Semua algoritma kompresi standar memiliki beberapa ukuran memori maksimum, di luar itu mereka gagal mendeteksi pola ... tetapi untuk beberapa, jumlah ini jauh lebih besar daripada yang lain. Untuk Bzip, kira-kira seperti 900KB. Untuk xz, kira-kira 8MB (dengan pengaturan default). Untuk 7z, kira-kira 2GB. 2GB lebih dari cukup besar untuk mengenali duplikat file PNG (yang biasanya jauh lebih kecil dari 2GB). Selain itu, 7z juga mencoba untuk pandai menempatkan file yang cenderung mirip satu sama lain di dalam arsip, untuk membantu kompresor bekerja lebih baik; tar tidak tahu apa-apa tentang itu.

    Lihat juga jawaban Raphael dan jawaban Nayuki untuk penjelasan lebih lanjut tentang efek ini.

Bagaimana ini berlaku untuk pengaturan Anda. Untuk contoh spesifik Anda, Anda bekerja dengan gambar PNG. Gambar PNG sendiri dikompresi, sehingga Anda dapat menganggap setiap file PNG pada dasarnya adalah urutan byte yang tampak acak, tanpa pola atau duplikasi di dalam file tersebut. Tidak ada yang bisa dieksploitasi kompresor, jika terlihat pada gambar PNG tunggal. Jadi, jika Anda mencoba untuk mengompres file PNG tunggal (atau membuat arsip zip / tar / ... yang hanya berisi file PNG tunggal), Anda tidak akan mendapatkan kompresi apa pun.

Sekarang mari kita lihat apa yang terjadi jika Anda mencoba menyimpan banyak salinan dari file PNG yang sama:

  • File kecil.Jika file PNG sangat kecil, maka semuanya kecuali zip akan bekerja dengan baik. Zip akan gagal secara spektakuler: ia mengkompres setiap file secara independen, sehingga tidak memiliki peluang untuk mendeteksi redundansi / duplikasi di antara file-file tersebut. Selain itu, ketika mencoba untuk mengompresi setiap file PNG, itu tidak mencapai kompresi; ukuran arsip zip akan sangat besar. Sebaliknya, ukuran arsip tar (apakah dikompresi dengan gzip, bzip2, atau xz) dan arsip 7z akan kecil, karena pada dasarnya menyimpan satu salinan file dan kemudian memperhatikan bahwa yang lainnya semuanya identik - mereka mendapat manfaat dari mempertahankan memori dari satu file ke file lainnya.

  • File besar. Jika file PNG besar, maka hanya 7z yang berfungsi dengan baik. Secara khusus, zip terus gagal secara spektakuler. Juga, tar.zip dan tar.bzip2 gagal dengan buruk, karena ukuran file lebih besar dari jendela memori kompresor: karena kompresor melihat salinan file pertama, itu tidak dapat menyusutkan (karena sudah dikompresi) ); pada saat mulai melihat awal dari salinan kedua file, ia sudah lupa urutan byte yang terlihat di awal file pertama dan tidak dapat membuat koneksi bahwa data ini sebenarnya merupakan duplikat.

    Sebaliknya, tar.xz dan 7z terus melakukan yang terbaik dengan banyak salinan file PNG besar. Mereka tidak memiliki batasan "ukuran memori kecil" dan dapat melihat bahwa salinan kedua file identik dengan salinan pertama, jadi tidak perlu menyimpannya untuk yang kedua kalinya.

Apa yang dapat Anda lakukan tentang ini? Gunakan 7z. Ini memiliki banyak heuristik yang akan membantu mendeteksi file yang identik atau serupa dan kompres dengan sangat baik dalam kasus itu. Anda juga dapat melihat lrzip dengan kompresi lzop.

Bagaimana aku tahu? Saya dapat memverifikasi ini dengan mencoba beberapa percobaan dengan 100 salinan file yang berisi byte acak. Saya mencoba 100 salinan file 4KB, 100 salinan file 1MB, dan 100 salinan file 16MB. Inilah yang saya temukan:

Size of file      Size of compressed archive (with 100 copies)
                  zip  tar.gz  tar.bz2  tar.xz    7z
         4KB    414KB     8KB     10KB     5KB    5KB
         1MB    101MB   101MB    101MB     1MB    2MB
        16MB    1.6G    1.6GB    1.6GB   1.6GB  401MB

Seperti yang Anda lihat, zip itu mengerikan, sekecil apa pun file Anda. 7z dan xz keduanya baik jika gambar Anda tidak terlalu besar (tetapi xz akan rapuh dan bergantung pada urutan penempatan gambar dalam arsip, jika Anda memiliki beberapa duplikat dan beberapa non-duplikat yang digabungkan menjadi satu). 7z sangat bagus, bahkan untuk file besar.

Referensi. Ini juga dijelaskan dengan baik dalam banyak posting di Super User. Lihatlah:


5
Mungkin perlu diingat juga bahwa format ZIP dirancang kembali sekitar tahun 1990 (PKZIP memperkenalkan format ZIP pada tahun 1989 mengatakan Wikipedia, dan DEFLATE diperkenalkan pada tahun 1993). Pada periode ini, PC yang cukup umum mungkin adalah 286 atau 386 (486 diperkenalkan pada 1989, tetapi seperti biasa, membutuhkan waktu untuk menjalankannya) menjalankan DOS dengan RAM mungkin 2-4 MB, hanya mungkin 400- 500 KB di antaranya langsung dapat digunakan tanpa dukungan pemrograman pintar (EMS, XMS) yang tidak dijamin akan tersedia. Dalam lingkungan itu, ukuran jendela kompresi kecil cukup banyak persyaratan.
CVn

"Setiap file dikompresi secara independen" - Ini tampaknya sangat bervariasi antara standar dan alat. Pengalaman saya dengan perangkat lunak pengemasan default Ubuntu adalah sepertinya ia mendekompresi semuanya saat membuka arsip. Saya sering berpikir bahwa itu harus mengkompres setiap file secara independen, karena keuntungan kegunaan biasanya lebih besar daripada kelemahan kompresi.
Raphael

"100 salinan file yang berisi byte acak" - bagaimana dengan file "mirip"? (Menjelang pertanyaan yang sebenarnya, betapa miripnya adalah PNG dari gambar yang sama?)
Raphael

Raphael membuat poin bagus tentang ini dalam jawabannya. Sebenarnya saya memiliki banyak gambar yang mirip (tidak identik) yang ingin saya simpan. Serupa dalam hal mereka menunjukkan struktur yang sama dengan sedikit variasi (juga berkenaan dengan intensitas dan latar belakang). Namun perbedaannya sangat kecil sehingga mereka hampir tidak terlihat. Saya mencoba untuk tarmereka dan kemudian kompres dengan xz(yang bekerja sangat baik untuk gambar yang identik) namun dalam kasus gambar yang sama keuntungannya nol. Saya mencoba dengan 71 gambar masing-masing memiliki ukuran ~ 831KB.
a_guest

2
@ a_guest - itu tidak akan berjalan dengan baik. Gambar PNG yang tampak serupa akan memiliki konten byte yang sangat berbeda (karena kompresi PNG). Lihat juga superuser.com/q/730592/93541 , superuser.com/q/418286/93541 , superuser.com/q/893206/93541 , superuser.com/q/921140/93541 - pada dasarnya, tidak ada solusi yang baik.
DW

10

Pertama, perhatikan bahwa format gambar PNG pada dasarnya adalah piksel RGB mentah (dengan beberapa penyaringan cahaya) didorong melalui format kompresi DEFLATE. Secara umum, file terkompresi (PNG, JPEG, MP3, dll.) Tidak akan mendapat manfaat dari dikompres lagi. Jadi untuk maksud praktis, kami dapat memperlakukan file PNG Anda sebagai data acak yang tidak dapat dimampatkan untuk sisa percobaan.

Kedua, perhatikan bahwa format ZIP dan gzip juga menggunakan codec DEFLATE. (Ini akan menjelaskan mengapa zipping versus gzipping satu file pada dasarnya akan menghasilkan ukuran output yang sama.)


Sekarang izinkan saya untuk mengomentari setiap kasus uji secara individual:

  • tar czf folder.tar.gz folder/

    Ini membuat file TAR (tidak terkompresi) yang menggabungkan semua file PNG identik Anda (dengan sedikit metadata dan penambahan ditambahkan). Kemudian file tunggal ini dikirim melalui kompresor gzip untuk membuat satu file output terkompresi.

    Sayangnya, format DEFLATE hanya mendukung jendela kamus LZ77 sebesar 32768 byte. Jadi meskipun TAR berisi data berulang, jika file PNG Anda lebih besar dari 32 KiB maka pasti DEFLATE kompresor tidak dapat mengingat data cukup jauh untuk mengambil keuntungan dari fakta bahwa data identik berulang.

    Di sisi lain, jika Anda mencoba kembali pengalaman ini dengan, katakanlah, file PNG 20 KB digandakan 10 kali, maka sangat mungkin Anda akan mendapatkan file gzip hanya sedikit lebih besar dari 20 KB.

  • tar cf folder.tar folder/ && xz --stdout folder.tar > folder.tar.xz

    Ini menciptakan file TAR seperti sebelumnya, dan kemudian menggunakan format xz dan kompresor LZMA / LZMA2. Saya tidak dapat menemukan informasi tentang LZMA dalam situasi ini, tetapi dari 7-Zip untuk Windows saya tahu itu dapat mendukung ukuran jendela kamus besar (misalnya 64 MiB). Jadi ada kemungkinan bahwa Anda menggunakan pengaturan suboptimal, dan bahwa LZMA codec mungkin dapat mengurangi file TAR menjadi hanya ukuran satu file PNG.

  • zip -r folder.zip folder/

    Format ZIP tidak mendukung arsip "solid"; artinya, setiap file dikompresi secara independen. Kami mengasumsikan setiap file tidak dapat dimampatkan. Oleh karena itu fakta bahwa setiap file identik tidak dapat dieksploitasi, dan file ZIP akan sebesar gabungan langsung dari semua file.


xzsecara default berjalan dalam xz -6mode, yang menggunakan kamus LZMA2 8 MiB . Saya tidak dapat segera menemukan di halaman manual yang tersedia di sistem Debian saya berapa ukuran jendela default untuk kompresor.
CVn

Jawaban yang bagus! Untuk kasus kedua saya benar-benar melakukan hal berikut: tar czf folder.tar.gz folder/ && xz --stdout folder.tar.gz > folder.tar.gz.xztanpa efek (yang masuk akal sesuai dengan apa yang Anda jelaskan). Saya kira saya sedikit tersesat dalam semua hal kompresi ini: D Ketika menggunakan tar cf folder.tar folder/ && xz --stdout folder.tar > folder.tar.xzsaya sebenarnya berakhir dengan sedikit lebih dari ukuran satu gambar (yang juga masuk akal sesuai dengan ukuran jendela dict default 64 MiB). Saya memperbarui pertanyaan saya sesuai. Terima kasih!
a_guest

@ a_guest Oke, komentar Anda menjelaskan kasus kedua yang berbeda. Masalahnya adalah bahwa di tar -> gzip -> xz, gzip DEFLATE mungkin memampatkan setiap salinan data PNG dengan cara yang berbeda, sehingga xz tidak akan dapat mendeteksi redundansi.
Nayuki

6

Masalahnya adalah, skema kompresi (sebagian besar) tidak memiliki pengetahuan tentang data yang Anda miliki. Bahkan jika Anda mendekompres PNG Anda ke bitmap dan mengompresnya di tarball, Anda tidak akan mendapatkan (secara signifikan) hasil yang lebih kecil.

Dalam kasus banyak gambar yang serupa, skema kompresi yang sesuai adalah codec video.

Menggunakan pengkodean lossless Anda harus mencapai hampir hasil kompresi sempurna yang Anda harapkan.

Jika Anda ingin mengujinya, gunakan sesuatu seperti ini:

ffmpeg -i img%03d.png -c:v libx264 -c:v libx264 -profile:v high444 -crf 0 out.mp4

https://trac.ffmpeg.org/wiki/Create%20a%20video%20slideshow%20from%20images


Poin bagus menggunakan encoder video! Saya akan mencobanya ketika saya memutakhirkan Ubuntu saya penyebab 14.04 tidak termasuk ffmpeg secara default. Saya kira video encoder ini menggunakan kompresi lossless atau setidaknya memiliki saklar untuk itu? Apakah anda tahu
a_guest

Ya, -crf 0 menjadikannya lossless (atau seperti yang disebutkan dalam dokumen -qp 0 melakukan hal yang sama (-qp 0 lebih disukai)). trac.ffmpeg.org/wiki/Encode/H.264
Jonas

4

PNG adalah kombinasi dari Filter + LZ77 + Huffman (kombinasi dari LZ77 + Huffman disebut Deflate) dengan urutan:

langkah 1) jika filter berbeda dari Tidak Ada, nilai piksel digantikan oleh perbedaan dari piksel yang berdekatan (untuk lebih jelasnya lihat http://www.libpng.org/pub/png/book/chapter09.html ) . Yang meningkatkan kompresi gambar dengan gradien (jadi ... 4 5 6 7 menjadi ... 1 1 1 1) dan itu dapat membantu di area dengan warna yang sama (... 3 3 3 5 5 5 5 5 menjadi 0 0 0 2 0 0 0 0 0). Secara default filter diaktifkan dalam gambar 24-bit dan dinonaktifkan dalam gambar 8-bit dengan palet.

langkah 2) data dikompres dengan LZ77 yang menggantikan string byte (match) yang diulang dengan tuple yang berisi jarak ke pertandingan dan panjang pertandingan.

langkah 3) hasil langkah 2 dikodekan dengan kode Huffman yang menggantikan simbol panjang tetap dengan kode panjang variabel, semakin sering simbol semakin pendek kode.

Ada beberapa masalah:

Perubahan kecil yang memengaruhi beberapa piksel akan menghasilkan perubahan hasil dari 3 langkah kompresi png:

1) Nilai yang disaring dari piksel yang berdekatan akan berubah (tergantung pada filter yang digunakan). Itu akan memperkuat efek dari perubahan kecil.

2) Perubahan akan berarti bahwa kecocokan dengan area itu akan berbeda. Misalnya mengubah 333333 menjadi 333533 menyebabkan kemunculan 333333 yang lain tidak lagi cocok sehingga akan memilih kecocokan lain menjadi 333333 dengan jarak yang berbeda atau akan memilih kecocokan yang sama tetapi dengan panjang yang lebih pendek dan kemudian kecocokan lainnya untuk 3 byte terakhir. Dengan sendirinya itu akan banyak mengubah hasil.

3) Masalah terbesar adalah pada langkah 3. Kode huffman menggunakan sejumlah variabel bit sehingga bahkan perubahan kecil akan menghasilkan bahwa segala sesuatu yang mengikuti tidak lagi selaras. AFAIK Kebanyakan algoritma kompresi tidak dapat mendeteksi kecocokan yang tidak selaras byte sehingga akan mencegah (atau setidaknya mengurangi banyak) kompresi pada data yang sudah dikompresi yang mengikuti perubahan kecuali kompresor dapat mendeteksi kecocokan yang tidak selaras byte.

Masalah lain sudah dicakup oleh balasan lain:

4) Gzip menggunakan algoritma Deflate yang sama dengan kamus 32KB, jadi jika file png lebih besar dari 32KB, kecocokan tidak akan terdeteksi meskipun mereka identik. Bzip2 lebih baik dalam aspek itu karena menggunakan blok 900 KB. XZ menggunakan LZMA, yang IIRC memiliki kamus 4 MB di tingkat kompresi standar. 5) Format zip tidak menggunakan kompresi padat sehingga tidak akan mengkompres file yang sama atau identik lebih baik.

Mungkin kompresor dari keluarga PAQ atau PPMD ​​akan memampatkan lebih baik tetapi jika Anda perlu mengompres banyak file gambar yang serupa maka Anda dapat mempertimbangkan 3 pendekatan:

1) Simpan gambar tanpa kompresi (dengan PNG -0 atau dalam format tanpa kompresi) dan kompres dengan kompresor dengan kamus besar atau ukuran blok. (LZMA akan bekerja dengan baik)

2) Pilihan lain adalah menyimpan filter tetapi menghapus kompresi Deflate dari PNG. Itu bisa dilakukan misalnya dengan utilitas ( AdvDef ). Lalu Anda kompres PNGs terkompresi yang dihasilkan. Setelah dekompresi, Anda dapat menyimpan PNG yang tidak terkompresi atau mengompresnya lagi dengan AdvDef (tetapi itu akan memakan waktu).

Anda perlu menguji kedua pendekatan untuk melihat kompres mana yang paling banyak.

3) Opsi terakhir adalah mengonversi gambar png dalam video, mengompresnya dengan kompresor video lossless seperti x264 lossless (dengan hati-hati menggunakan format warna yang tepat) dan kemudian mengekstraksi ekstrak frame ke gambar png individu. Itu bisa dilakukan dengan ffmpeg. Anda juga perlu menjaga pemetaan antara nomor bingkai dan nama asli.

Itu akan menjadi pendekatan yang paling kompleks tetapi jika pngs semua bagian dari animasi itu mungkin yang paling efektif. Namun Anda akan memerlukan format video yang mendukung transparansi jika Anda membutuhkannya.

Sunting: Ada juga format MNG yang tidak sering digunakan.


2

Saat Anda memiliki kumpulan data khusus, Anda menggunakan algoritme khusus, bukan alat multiguna.

Jawabannya adalah bahwa kompresi lossless yang Anda pilih tidak dibuat untuk apa yang Anda lakukan. Noone mengharapkan Anda untuk mengompres gambar yang sama dua kali, dan bahkan jika Anda melakukannya (secara tidak sengaja) memeriksa semua input sebelumnya akan membuat algoritma Anda O (n ^ 2) (mungkin sedikit lebih baik, tetapi pendekatan naif setidaknya akan menjadi n ^ 2).

Sebagian besar program kompresi yang Anda uji dijalankan di O (n), mereka menekankan kecepatan dibandingkan rasio kompresi yang optimal. Tidak seorang pun ingin menjalankan komputernya selama 5 jam hanya untuk menghemat beberapa mb, terutama hari-hari ini. Untuk input yang lebih besar, apa pun di atas O (n) menjadi masalah runtime.

Masalah lainnya adalah ram. Anda tidak dapat mengakses setiap bagian dari input Anda kapan saja, ketika inputnya cukup besar. Bahkan mengabaikan hal ini, kebanyakan orang tidak mau menyerahkan seluruh ram atau cpu mereka hanya untuk mengompres sesuatu.

Jika Anda memiliki pola dalam file yang ingin Anda kompres, Anda harus melakukan operasi manuel padanya, menulis kompresi Anda sendiri atau berpotensi menggunakan "arsip" -tipe-kompresi (nano). Kompresi untuk penyimpanan jangka panjang, itu terlalu lambat untuk penggunaan sehari-hari.

Pilihan lain yang berpotensi adalah kompresi video tanpa kehilangan.


1
Mengingat bahwa sangat umum bagi struktur direktori untuk memuat banyak file identik di tempat yang berbeda, sepertinya utilitas gaya zip yang baik harus menyediakan opsi untuk memeriksa apakah file yang ditambahkan ke arsip telah dikompresi / nilai dan ukuran hash yang tidak dikompresi. yang cocok dengan file yang ada. Jika hash dan kedua ukuran cocok, akan berguna untuk melampirkan nama kedua ke blok data yang terkait dengan file pertama. Bahkan jika ZIP tidak dapat mengakomodasi itu, itu akan tampak fitur yang berguna dalam format apa pun di masa depan.
supercat

1
Jawaban Anda menyiratkan algoritma kompresi tar baik untuk mengompresi beberapa jenis redundansi, tetapi tidak untuk jenis yang terjadi dalam skenario OP. Anda mungkin ingin menggambarkan jenis redundansi apa yang Anda pikir itu adalah baik untuk, karena itu sama sekali tidak jelas. Untuk seseorang yang mungkin tidak pernah menggunakan kompresor ini dengan sukses, yang mereka lihat adalah mereka mencobanya pada sesuatu yang secara teori cukup bisa dikompresi, itu tidak berhasil, jadi apa sih yang baik untuk kompresor ini?
Don Hatch

1
@leftaroundabout: Tidak ada cara di Unix yang saya tahu untuk menggunakan semantik "copy-on-write" dengan file yang cocok. Dalam banyak kasus, salinan yang berlebihan ada untuk berurusan dengan fakta bahwa hal-hal yang mungkin sama hari ini, mungkin tidak akan sama besok, dan tidak ada symlink atau hardlink yang cocok dalam kasus tersebut.
supercat

1
@supercat: dengan banyak file seperti itu, itu adalah solusi yang sangat baik untuk menggunakan symlink ke satu "resmi", versi read-only. Jika Anda kemudian ingin mengubah salinan Anda, ganti symlink dengan salinan fisik.
leftaroundabout

1
@leftaroundabout: Satu hal yang kadang-kadang saya pikir akan menarik jika seseorang dapat mengurangi bahaya tabrakan hash yang direkayasa ke tingkat yang dapat diterima adalah memiliki pengenal referensi universal berbasis hash, sehingga alih-alih menyatu dengan nama file "logis" orang akan membuat tautan berdasarkan hash. Arsip kemudian akan menyimpan 256 byte atau lebih dari hash sebagai pengganti menyimpan file yang sangat besar. Variasi dari pendekatan semacam itu juga dapat digunakan untuk memungkinkan caching file yang perlu dijaga terhadap perubahan.
supercat

2

Format file PNG sudah menggunakan algoritma kompresi DEFLATE secara internal. Ini adalah algoritma yang sama seperti yang digunakan oleh xz, gzip, dan zip - hanya dalam beberapa variasi. tar.gzdan dan tar.xzmemanfaatkan kesamaan antara file, yang ziptidak.

Jadi, pada kenyataannya, Anda melakukan kompresi DEFLATE di atas file terkompresi DEFLATE - inilah mengapa file tersebut mempertahankan ukuran hampir aslinya.

The bzip2Program (juga algoritma terkait) lebih baik ketika datang ke (hampir) file identik.

# for i in $(seq 4); do cp test.png test$i.png; done
# tar -cjf archive.tar.bz2 *.png
# ls -l
-rw-r--r-- 1 abcde users  43813 15. Jul 08:45 test.png
-rw-r--r-- 1 abcde users  43813 15. Jul 08:45 test1.png
-rw-r--r-- 1 abcde users  43813 15. Jul 08:46 test2.png
-rw-r--r-- 1 abcde users  43813 15. Jul 08:46 test3.png
-rw-r--r-- 1 abcde users  43813 15. Jul 08:46 test4.png
-rw-r--r-- 1 abcde users  68115 15. Jul 08:47 archive.tar.bz2

PNG - harap diingat bahwa ada filter yang digunakan, deflate non-standar (yang mana yang merupakan standar?) Dan Anda benar bahwa menjalankan algoritma yang sama dua kali tidak menghasilkan apa-apa (atau setidaknya seharusnya tidak bermanfaat), tetapi menjalankan algoritma yang sama dengan pengaturan yang berbeda tidak dijamin gagal. Juga ada perbedaan antara deflate32, deflate64, LZW, LZMA, Anda tidak bisa hanya mengatakan bahwa semuanya menggunakan deflate yang sama.
Evil

Itu sebabnya saya mengatakan "dalam beberapa variasi". Tentu saja, DEFLATE mengacu pada semacam algoritma daripada implementasi tertentu.
rexkogitans

3
Ini meleset saat saya memahaminya. Ya, satu file PNG saja sudah dikompres jadi saya tidak akan mengharapkan kompresi lebih lanjut dalam bentuk apa pun untuk banyak efek. Tetapi gabungan dari beberapa file PNG yang identik (yang pada dasarnya adalah situasi di sini) mungkin cukup diharapkan untuk dikompres menjadi tidak lebih dari ukuran salah satunya.
Don Hatch

Jelas, algoritma kompresi tersebut kehilangan titik itu. bzip2menangkap itu: tar -cjf archive.tar.bz2 *.png. Diperbarui dalam jawaban saya.
rexkogitans
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.