ทำไมวิธีการบีบอัด (ไม่สูญเสีย) เหล่านี้ของรูปภาพ png ที่คล้ายกันหลาย ๆ แบบจึงไม่มีประสิทธิภาพ


21

ฉันเพิ่งเจอสิ่งต่อไปนี้: ฉันใส่รูปภาพ png ที่เหมือนกันหลายชุดลงในโฟลเดอร์แล้วพยายามบีบอัดโฟลเดอร์นั้นด้วยวิธีการต่อไปนี้:

  • tar czf folder.tar.gz folder/
  • tar cf folder.tar folder/ && xz --stdout folder.tar > folder.tar.xz (อันนี้ทำงานได้ดีสำหรับภาพที่เหมือนกัน แต่สำหรับภาพที่คล้ายกันกำไรจะเป็นศูนย์)
  • zip -r folder.zip folder/

เมื่อผมตรวจสอบขนาดของ.tar.gz, .tar.xz, ฉันรู้ว่ามันเป็นเกือบเดียวกันเป็นหนึ่งใน.zip ฉันเข้าใจว่ารูปภาพ png เองอาจมีการบีบอัดในระดับสูงดังนั้นจึงไม่สามารถบีบอัดเพิ่มเติมได้ อย่างไรก็ตามเมื่อรวมภาพ png ที่คล้ายกันจำนวนมาก (ในกรณีนี้เหมือนกัน) ไปยังไฟล์เก็บถาวรแล้วบีบอัดไฟล์เก็บถาวรฉันคาดว่าขนาดที่ต้องการจะลดลงอย่างชัดเจน ในกรณีของภาพที่เหมือนกันฉันคาดว่าจะมีขนาดประมาณขนาดของภาพเดียวfolder/


2
ลักษณะการทำงานนี้จะแสดงด้วยไฟล์ png เท่านั้น
pdexter

7
ไม่ทำให้คำตอบนี้เป็นคำตอบสำหรับคำถามที่ยังไม่ได้ถาม แต่ถ้าคุณรู้ว่าคุณกำลังบีบอัดรูปภาพที่เหมือนกันเกือบจำนวนมากคุณสามารถแทนที่รูปภาพทั้งหมดได้เสมอ สมมติว่าภาพไม่รบกวนคุณจะจบลงด้วยเอาต์พุตที่บีบอัดได้มากและภาพต้นฉบับจะยังคงทำซ้ำได้
Baldrickk

หากคุณใช้ไฟล์ที่ไม่บีบอัด (เช่น.bmp) ไฟล์ tar.gz ควรสามารถใช้ประโยชน์จากความคล้ายคลึงกันได้ (อย่างน้อยถ้าความเหมือนกันของพิกเซลเหมือนกันมาก)
CodesInChaos

1
ฉันไม่รู้อะไรเลย แต่ตาม Wikipedia รูปแบบการเก็บถาวร "ZPAQ" รองรับการขจัดข้อมูลซ้ำซ้อนซึ่งฉันเชื่อว่าเป็นสิ่งที่คุณต้องการ en.wikipedia.org/wiki/ZPAQ#Dupuplication
coneslayer

คุณกำลังพยายามบีบอัดบางสิ่งที่ถูกบีบอัดอยู่แล้ว ดูที่นี่
Kyle Khalaf

คำตอบ:


34

ดูว่าอัลกอริทึมการบีบอัดทำงานอย่างไร อย่างน้อยผู้ที่อยู่ในครอบครัว Lempel-Ziv ( gzip ใช้ LZ77 , zipเห็นได้ชัดว่าส่วนใหญ่ไม่ได้เป็นอย่างดีและxz ใช้ LZMA ) การบีบอัดค่อนข้างท้องถิ่น : ความคล้ายคลึงกันที่อยู่ห่างไกลจากการไม่ได้แต่ละคนสามารถอื่น ๆ ที่ระบุได้

รายละเอียดแตกต่างกันระหว่างวิธีการ แต่บรรทัดล่างคือเมื่อถึงอัลกอริทึมถึงภาพที่สองมันได้ "ลืม" จุดเริ่มต้นของครั้งแรก และอื่น ๆ

คุณสามารถลองและเปลี่ยนพารามิเตอร์ของวิธีการบีบอัดด้วยตนเอง; ถ้าขนาดหน้าต่าง (LZ77) ขนาดบล็อก / ก้อน (วิธีการในภายหลัง) อย่างน้อยใหญ่เท่ากับสองภาพคุณอาจจะเห็นการบีบอัดเพิ่มเติม


โปรดทราบว่าสิ่งที่กล่าวมาข้างต้นมีผลเฉพาะในกรณีที่คุณมีภาพที่เหมือนกันหรือภาพที่ไม่มีการบีบอัดเกือบจะเหมือนกัน หากมีความแตกต่างภาพที่บีบอัดอาจดูไม่เหมือนกันในหน่วยความจำ ฉันไม่รู้ว่าการบีบอัด PNG ทำงานอย่างไร; คุณอาจต้องการตรวจสอบการแสดงภาพฐานสิบหกของรูปภาพที่คุณมีสำหรับสตริงย่อยที่แชร์ด้วยตนเอง

โปรดทราบว่าแม้จะมีการเปลี่ยนแปลงพารามิเตอร์และความซ้ำซ้อนในการใช้ประโยชน์ แต่คุณจะไม่ต้องกังวลถึงขนาดของภาพเดียว พจนานุกรมที่ใหญ่ขึ้นหมายถึงขนาดของคำรหัสที่ใหญ่กว่าและแม้ว่าภาพสองภาพจะเหมือนกันทุกประการคุณอาจต้องเข้ารหัสรูปที่สองโดยใช้คำรหัสหลาย ๆ คำ


3
คำตอบที่แม่นยำยิ่งขึ้น: gzip และ zip ใช้ตัวแปลงสัญญาณ DEFLATE พื้นฐานเดียวกันซึ่งอยู่บนพื้นฐานของทฤษฎี LZ77 + Huffman
Nayuki

ได้! นั่นเป็นครึ่งหนึ่งของเรื่องราว ดูคำตอบของฉันสำหรับครึ่งอื่น ๆ หรือคำตอบที่ดี Nayuki ของ
DW

1
สำหรับลูกหลาน: เก็บรูปแบบที่ใช้ประโยชน์จากความซ้ำซ้อนในหมู่ไฟล์โดยเชื่อมโยงไฟล์ลงในหยดเดียวและการบีบอัดที่จะเรียกว่าเป็นของแข็ง ไม่แน่ใจว่ามีคำอื่น ๆ สำหรับระดับกลางของ 'solidity' หรือไม่
underscore_d

22

ทำไมสิ่งนี้เกิดขึ้น จริงๆแล้วมีเอฟเฟกต์ต่างกันสองอย่างเกิดขึ้นที่นี่

  • แต่ละไฟล์ถูกบีบอัดอย่างอิสระ บางโปรแกรมเก็บถาวร - รวมถึง zip - บีบอัดแต่ละไฟล์แยกกันโดยไม่มีหน่วยความจำจากไฟล์หนึ่งไปยังไฟล์อื่น ในคำอื่น ๆ แต่ละไฟล์จะถูกบีบอัดแยกต่างหากจากนั้นไฟล์ที่ถูกบีบอัดจะถูกตัดแบ่งเป็นไฟล์เก็บถาวร

  • หน่วยความจำระยะสั้น. โปรแกรมเก็บถาวรบางโปรแกรมสามารถใช้ข้อมูลเกี่ยวกับไฟล์เดียวเพื่อช่วยบีบอัดไฟล์ถัดไปได้ดียิ่งขึ้น พวกเขาเชื่อมไฟล์อย่างมีประสิทธิภาพจากนั้นบีบอัดผลลัพธ์ นี่คือการปรับปรุง

    ดูคำตอบของ Nayukiสำหรับการสนทนาเพิ่มเติมในเรื่องนี้

    อย่างไรก็ตามมีปัญหาที่สอง รูปแบบการบีบอัดบางรูปแบบรวมถึง zip, gzip และ bzip2 มีหน่วยความจำ จำกัด พวกเขาบีบอัดข้อมูลแบบทันทีและจดจำข้อมูล 32KB ที่ผ่านมา แต่พวกเขาไม่จำข้อมูลใด ๆ เกี่ยวกับข้อมูลที่เกิดขึ้นก่อนหน้านี้ในไฟล์ กล่าวอีกนัยหนึ่งพวกเขาไม่สามารถค้นหาข้อมูลที่ซ้ำกันได้หากสิ่งที่ซ้ำกันนั้นเกิดขึ้นไกลกว่า 32KB ด้วยเหตุนี้หากไฟล์ที่เหมือนกันสั้น (สั้นกว่าประมาณ 32KB) อัลกอริทึมการบีบอัดสามารถลบข้อมูลที่ซ้ำกัน แต่ถ้าไฟล์ที่เหมือนกันนั้นยาว ซ้ำในข้อมูลของคุณ (Bzip จดจำข้อมูล 900KB ที่ผ่านมาหรือมากกว่านั้นแทน 32KB)

    อัลกอริธึมการบีบอัดมาตรฐานทั้งหมดมีขนาดหน่วยความจำสูงสุดบางส่วนซึ่งเกินกว่าที่จะตรวจจับรูปแบบ ... แต่สำหรับบางคนตัวเลขนี้มีขนาดใหญ่กว่าขนาดอื่น ๆ สำหรับ Bzip มันเหมือนกับ 900KB สำหรับ xz คล้ายกับ 8MB (พร้อมการตั้งค่าเริ่มต้น) สำหรับ 7z มันเหมือนกับ 2GB 2GB มีขนาดใหญ่เกินพอที่จะรับรู้สำเนาไฟล์ PNG ที่ซ้ำกัน (ซึ่งโดยทั่วไปแล้วจะเล็กกว่า 2GB) นอกจากนี้ 7z ยังพยายามอย่างชาญฉลาดเกี่ยวกับการวางไฟล์ที่มีแนวโน้มที่จะคล้ายกันซึ่งอยู่ติดกันในไฟล์เก็บถาวรเพื่อช่วยให้คอมเพรสเซอร์ทำงานได้ดีขึ้น กลาสีเรือไม่รู้อะไรเกี่ยวกับเรื่องนั้น

    ดูคำตอบของ RaphaelและคำตอบของNayukiสำหรับคำอธิบายเพิ่มเติมของเอฟเฟกต์นี้

วิธีนี้ใช้กับการตั้งค่าของคุณ สำหรับตัวอย่างเฉพาะของคุณคุณกำลังทำงานกับรูปภาพ PNG รูปภาพ PNG นั้นถูกบีบอัดด้วยตนเองดังนั้นคุณสามารถคิดได้ว่าไฟล์ PNG แต่ละไฟล์นั้นเป็นลำดับของไบต์ที่ดูสุ่มโดยไม่มีรูปแบบหรือการทำซ้ำภายในไฟล์ ไม่มีสิ่งใดที่คอมเพรสเซอร์จะเอาเปรียบหากดูจากภาพ PNG เพียงภาพเดียว ดังนั้นหากคุณพยายามบีบอัดไฟล์ PNG ไฟล์เดียว (หรือสร้างไฟล์ zip / tar / ... ที่มีไฟล์ PNG ไฟล์เดียว) คุณจะไม่ได้รับการบีบอัดใด ๆ

ตอนนี้เรามาดูกันว่าจะเกิดอะไรขึ้นถ้าคุณพยายามจัดเก็บไฟล์ PNG เดียวกันหลาย ๆ ชุด:

  • ไฟล์ขนาดเล็ก หากไฟล์ PNG เล็กมากทุกอย่างยกเว้น zip จะใช้งานได้ดี Zip จะล้มเหลวอย่างน่าทึ่ง: มันบีบอัดไฟล์แต่ละไฟล์แยกกันดังนั้นจึงไม่มีโอกาสตรวจจับความซ้ำซ้อน / การทำซ้ำระหว่างไฟล์ ยิ่งกว่านั้นเมื่อพยายามบีบอัดไฟล์ PNG แต่ละไฟล์จะไม่สามารถบีบอัดได้ ขนาดของไฟล์ zip จะมีขนาดใหญ่ ในทางตรงกันข้ามขนาดของไฟล์เก็บถาวร tar (ไม่ว่าจะถูกบีบอัดด้วย gzip, bzip2 หรือ xz) และไฟล์เก็บถาวร 7z จะมีขนาดเล็กเนื่องจากโดยทั่วไปแล้วจะเก็บสำเนาไฟล์หนึ่งชุดแล้วสังเกตว่าไฟล์อื่นนั้นเหมือนกันทั้งหมด จากการเก็บรักษาหน่วยความจำจากไฟล์หนึ่งไปยังอีก

  • ไฟล์ขนาดใหญ่ หากไฟล์ PNG มีขนาดใหญ่แสดงว่า 7z เท่านั้นที่ทำงานได้ดี โดยเฉพาะอย่างยิ่ง zip ยังคงล้มเหลวอย่างน่าทึ่ง นอกจากนี้ tar.zip และ tar.bzip2 ก็ล้มเหลวไม่ดีเนื่องจากขนาดของไฟล์มีขนาดใหญ่กว่าหน้าต่างหน่วยความจำของคอมเพรสเซอร์เนื่องจากคอมเพรสเซอร์เห็นสำเนาแรกของไฟล์จึงไม่สามารถย่อขนาดได้ (เนื่องจากถูกบีบอัดไปแล้ว ); เมื่อถึงเวลาที่จะเห็นจุดเริ่มต้นของสำเนาไฟล์ที่สองมันได้ลืมลำดับไบต์ที่เห็นที่จุดเริ่มต้นของไฟล์แรกและไม่สามารถทำการเชื่อมต่อที่ข้อมูลนี้ซ้ำกันจริง ๆ

    ในทางตรงกันข้าม tar.xz และ 7z ยังคงทำได้ดีกับไฟล์ PNG ขนาดใหญ่หลายสำเนา พวกเขาไม่มีข้อ จำกัด "ขนาดหน่วยความจำขนาดเล็ก" และสามารถสังเกตได้ว่าสำเนาที่สองของไฟล์นั้นเหมือนกับสำเนาแรกดังนั้นจึงไม่จำเป็นต้องจัดเก็บอีกเป็นครั้งที่สอง

คุณสามารถทำอะไรเกี่ยวกับเรื่องนี้ ใช้ 7z มันมีฮิวริสติกมากมายที่จะช่วยตรวจจับไฟล์ที่เหมือนหรือคล้ายกันและบีบอัดได้ดีในกรณีนี้ คุณยังสามารถดู lrzip ด้วยการบีบอัด lzop

ฉันจะรู้ได้อย่างไร ฉันสามารถตรวจสอบสิ่งนี้ได้โดยทดลองกับไฟล์ 100 ไฟล์ที่มีการสุ่มไบต์ ฉันลอง 100kb ของไฟล์ 4KB, 100 สำเนาของไฟล์ 1MB และ 100 สำเนาของไฟล์ 16MB นี่คือสิ่งที่ฉันพบ:

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

อย่างที่คุณเห็นซิปน่ากลัวไม่ว่าไฟล์ของคุณจะเล็กเพียงใด ทั้ง 7z และ xz นั้นดีถ้าภาพของคุณไม่ใหญ่เกินไป (แต่ xz จะบอบบางและขึ้นอยู่กับลำดับที่ภาพจะถูกเก็บไว้ในที่เก็บถ้าคุณมีบางส่วนที่ซ้ำกัน 7z นั้นค่อนข้างดีทีเดียวสำหรับไฟล์ขนาดใหญ่

อ้างอิง นี่เป็นคำอธิบายที่ดีในกลุ่มข้อความที่ Super User ลองดูสิ:


5
อาจเป็นสิ่งที่ควรคำนึงถึงด้วยเช่นกันว่ารูปแบบ ZIP ได้รับการออกแบบในช่วงปี 1990 (PKZIP แนะนำรูปแบบ ZIP ในปี 1989 กล่าวว่า Wikipedia และ DEFLATE เปิดตัวในปี 1993) ในช่วงเวลานี้พีซีทั่วไปที่มีเหตุผลอาจเป็น 286 หรือ 386 (เปิดตัว 486 ในปี 1989 แต่เช่นเคยใช้เวลาสักครู่ในการจับ) การเรียกใช้ DOS ที่มี RAM 2-4 MB อาจจะเพียง 400- 500 KB ซึ่งสามารถใช้งานได้โดยตรงโดยไม่ต้องสนับสนุนการเขียนโปรแกรมอย่างชาญฉลาด (EMS, XMS) ซึ่งไม่รับประกันว่าจะมีให้ใช้งาน ในสภาพแวดล้อมนั้นขนาดของหน้าต่างการบีบอัดขนาดเล็กนั้นเป็นข้อกำหนด
CVn

"แต่ละไฟล์ถูกบีบอัดอย่างอิสระ" - ดูเหมือนว่าจะแตกต่างกันอย่างมากระหว่างมาตรฐานและเครื่องมือ ประสบการณ์ของฉันกับซอฟต์แวร์บรรจุภัณฑ์เริ่มต้นของ Ubuntu คือดูเหมือนว่าจะแตกทุกอย่างเมื่อเปิดไฟล์เก็บถาวร ฉันมักจะคิดว่ามันควรบีบอัดไฟล์ทุกไฟล์อย่างอิสระเนื่องจากการใช้งานมักจะมากกว่าข้อเสียของการบีบอัด
กราฟิลส์

"100 สำเนาของไฟล์ที่มีการสุ่มไบต์" - แล้วไฟล์ที่ "คล้ายกัน" ล่ะ? (ต่อคำถามที่เกิดขึ้นจริงวิธีการที่คล้ายกันเป็น PNGs ของภาพที่คล้ายกัน?)
ราฟาเอล

ราฟาเอลทำดีในเรื่องนี้ในคำตอบของเขา จริงๆแล้วฉันมีภาพคล้ายกัน (ไม่เหมือนกัน) มากมายที่ฉันต้องการเก็บ คล้ายกันในแง่ของพวกเขาแสดงโครงสร้างเดียวกันกับรูปแบบที่แตกต่างกันเล็กน้อย (ยังเกี่ยวกับความเข้มและพื้นหลัง) อย่างไรก็ตามความแตกต่างนั้นเล็กมากจนแทบมองไม่เห็น ฉันลองtarพวกเขาแล้วบีบอัดด้วยxz(ซึ่งทำงานได้ดีมากสำหรับภาพที่เหมือนกัน) แต่ในกรณีของภาพที่คล้ายกันอัตราขยายจะเป็นศูนย์ ฉันลองด้วย 71 ภาพแต่ละภาพมีขนาดประมาณ ~ 831KB
a_guest

2
@a_guest - นั่นจะไม่เป็นไปด้วยดี ภาพ PNG ที่ดูคล้ายกันนั้นจะมีเนื้อหาไบต์ที่แตกต่างกันมาก (เนื่องจากการบีบอัด PNG) ดูเพิ่มเติมที่superuser.com/q/730592/93541 , superuser.com/q/418286/93541 , superuser.com/q/893206/93541 , superuser.com/q/921140/93541 - โดยทั่วไปไม่มีวิธีแก้ปัญหาที่ดี
DW

10

ประการแรกโปรดทราบว่ารูปแบบภาพ PNG นั้นเป็นพิกเซล RGB แบบดิบ (โดยมีการกรองแสง) ผ่านรูปแบบการบีบอัด DEFLATE โดยทั่วไปไฟล์ที่ถูกบีบอัด (PNG, JPEG, MP3, ฯลฯ ) จะไม่ได้รับประโยชน์จากการบีบอัดอีกครั้ง ดังนั้นสำหรับเจตคติเชิงปฏิบัติเราสามารถถือว่าไฟล์ PNG ของคุณเป็นข้อมูลสุ่มที่ไม่สามารถบีบอัดได้สำหรับการทดลองที่เหลือ

ประการที่สองโปรดทราบว่ารูปแบบ ZIP และ gzip ยังใช้ตัวแปลงสัญญาณ DEFLATE (นี่จะอธิบายว่าทำไมการซิปกับ gzipping ไฟล์เดียวจะสร้างขนาดเอาต์พุตที่เหมือนกันเป็นหลัก)


ตอนนี้ให้ฉันแสดงความคิดเห็นในแต่ละกรณีทดสอบ:

  • tar czf folder.tar.gz folder/

    สิ่งนี้จะสร้างไฟล์ TAR (ไม่บีบอัด) ที่เชื่อมไฟล์ PNG ที่เหมือนกันทั้งหมดของคุณ (ด้วยข้อมูลเมตาดาต้าและการเพิ่มส่วนขยายเล็กน้อย) จากนั้นไฟล์เดียวนี้จะถูกส่งผ่านคอมเพรสเซอร์ gzip เพื่อสร้างไฟล์เอาต์พุตหนึ่งไฟล์ที่บีบอัด

    ขออภัยรูปแบบ DEFLATE สนับสนุนเฉพาะหน้าต่างพจนานุกรม LZ77 ขนาด 32768 ไบต์ ดังนั้นแม้ว่า TAR จะมีข้อมูลซ้ำ ๆ กันหากไฟล์ PNG ของคุณมีขนาดใหญ่กว่า 32 KiB ดังนั้นตรวจสอบว่าคอมเพรสเซอร์ DEFLATE ไม่สามารถจำข้อมูลได้ไกลพอที่จะใช้ประโยชน์จากข้อมูลที่เหมือนกัน

    ในทางตรงกันข้ามถ้าคุณลองการทดลองนี้อีกครั้งด้วยไฟล์ PNG ขนาด 20 KB ที่ซ้ำกัน 10 ครั้งก็มีโอกาสมากที่คุณจะได้ไฟล์ gzip ที่ใหญ่กว่า 20 KB เพียงเล็กน้อยเท่านั้น

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

    สิ่งนี้สร้างไฟล์ TAR เหมือนก่อนหน้านี้จากนั้นใช้รูปแบบ xz และคอมเพรสเซอร์ LZMA / LZMA2 ฉันไม่สามารถหาข้อมูลเกี่ยวกับ LZMA ในสถานการณ์นี้ แต่จาก 7-Zip สำหรับ Windows ฉันรู้ว่าสามารถรองรับขนาดหน้าต่างพจนานุกรมขนาดใหญ่ (เช่น 64 MiB) ดังนั้นจึงเป็นไปได้ว่าคุณกำลังใช้การตั้งค่าที่ไม่ดีและตัวแปลงสัญญาณ LZMA อาจสามารถลดไฟล์ TAR ให้มีขนาดเท่ากับไฟล์ PNG เพียงไฟล์เดียว

  • zip -r folder.zip folder/

    รูปแบบ ZIP ไม่รองรับไฟล์เก็บถาวร "solid" กล่าวคือทุกไฟล์ถูกบีบอัดอย่างอิสระ เราสันนิษฐานว่าทุกไฟล์นั้นไม่สามารถบีบอัดได้ ดังนั้นความจริงที่ว่าทุกไฟล์เหมือนกันไม่สามารถใช้ประโยชน์ได้และไฟล์ ZIP จะมีขนาดใหญ่เท่ากับการต่อไฟล์ทั้งหมดเข้าด้วยกัน


xzโดยเริ่มต้นการทำงานในxz -6โหมดที่ใช้ 8 เอ็มไอ LZMA2 พจนานุกรม ฉันไม่สามารถค้นหาได้ทันทีในหน้า man ที่มีอยู่ในระบบ Debian ของฉันว่าขนาดหน้าต่างเริ่มต้นสำหรับคอมเพรสเซอร์คืออะไร
CVn

คำตอบที่ดี! สำหรับกรณีที่สองฉันทำสิ่งต่อไปนี้จริง ๆ : tar czf folder.tar.gz folder/ && xz --stdout folder.tar.gz > folder.tar.gz.xzโดยไม่มีผลกระทบใด ๆ (ซึ่งสมเหตุสมผลตามสิ่งที่คุณอธิบาย) ฉันเดาว่าฉันได้สูญเสียข้อมูลการบีบอัดไปนิดหน่อย: D เมื่อใช้tar cf folder.tar folder/ && xz --stdout folder.tar > folder.tar.xzจริง ๆ แล้วฉันก็จบลงด้วยขนาดที่มากกว่าหนึ่งขนาดของรูปภาพ ฉันปรับปรุงคำถามของฉันตาม ขอบคุณ!
a_guest

@a_guest โอเคดังนั้นความคิดเห็นของคุณจะอธิบายถึงกรณีที่สองที่แตกต่างกัน ปัญหาที่เกิดขึ้นคือในtar -> gzip -> xzgzip DEFLATE อาจบีบอัดข้อมูล PNG แต่ละสำเนาในวิธีที่ต่างกันดังนั้น xz จะไม่สามารถตรวจจับความซ้ำซ้อนได้
Nayuki

6

ปัญหาคือว่าแผนการบีบอัด (ส่วนใหญ่) ขาดความรู้มากกว่าข้อมูลที่คุณมี แม้ว่าคุณจะบีบอัด PNG ของคุณเป็นบิตแมปและบีบอัดมันใน tarball คุณจะไม่ได้ผลลัพธ์ที่เล็กลง (อย่างมีนัยสำคัญ)

ในกรณีของภาพที่คล้ายกันหลายรูปแบบการบีบอัดที่เหมาะสมจะเป็นตัวแปลงสัญญาณวิดีโอ

การใช้การเข้ารหัสแบบไม่สูญเสียข้อมูลคุณควรบรรลุผลการบีบอัดข้อมูลที่สมบูรณ์แบบที่คุณคาดหวัง

หากคุณต้องการทดสอบใช้สิ่งนี้:

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


จุดดีที่ใช้โปรแกรมเปลี่ยนไฟล์วิดีโอ! ฉันจะลองดูเมื่อฉันอัพเกรด Ubuntu เพราะ 14.04 ไม่ได้รวม ffmpeg ตามค่าเริ่มต้น ฉันเดาตัวเข้ารหัสวิดีโอนี้ใช้การบีบอัดแบบไม่สูญเสียข้อมูลหรืออย่างน้อยก็มีสวิตช์สำหรับสิ่งนั้น คุณรู้หรือไม่
a_guest

ใช่ -crf 0 ทำให้ไม่มีความสูญเสีย (หรือเหมือนกับที่กล่าวไว้ในเอกสาร -qp 0 ทำเช่นเดียวกัน (ต้องการ -qp 0)) trac.ffmpeg.org/wiki/Encode/H.264
Jonas

4

PNG คือการรวมกันของตัวกรอง + LZ77 + Huffman (การรวมกันของ LZ77 + Huffman เรียกว่า Deflate) ตามลำดับ:

ขั้นตอนที่ 1) หากตัวกรองแตกต่างจากไม่มีค่าของพิกเซลจะถูกแทนที่ด้วยความแตกต่างจากพิกเซลที่อยู่ติดกัน (สำหรับรายละเอียดเพิ่มเติมดูhttp://www.libpng.org/pub/png/book/chapter09.html ) . ที่เพิ่มการบีบอัดของภาพที่มีการไล่ระดับสี (ดังนั้น ... 4 5 6 7 กลายเป็น ... 1 1 1 1) และอาจช่วยในพื้นที่ที่มีสีเดียวกัน (... 3 3 3 5 5 5 5 5 5 กลายเป็น 0 0 0 2 0 0 0 0 0) โดยค่าเริ่มต้นตัวกรองจะเปิดใช้งานในรูปภาพ 24 บิตและปิดใช้งานในรูปภาพ 8 บิตพร้อมจานสี

ขั้นตอนที่ 2) ข้อมูลถูกบีบอัดด้วย LZ77 ที่แทนที่สตริงซ้ำ (จับคู่) ของไบต์ด้วย tuple ที่มีระยะห่างจากการจับคู่และความยาวของการจับคู่

ขั้นตอนที่ 3) ผลลัพธ์ของขั้นตอนที่ 2 ถูกเข้ารหัสด้วยรหัส Huffman ที่แทนที่สัญลักษณ์ความยาวคงที่ด้วยรหัสความยาวผันแปรยิ่งสัญลักษณ์ยิ่งรหัสสั้นลง

มีหลายประเด็น:

การเปลี่ยนแปลงเล็กน้อยที่มีผลต่อพิกเซลเพียงเล็กน้อยจะส่งผลให้เกิดการเปลี่ยนแปลงในผลลัพธ์จากการบีบอัด png 3 ขั้นตอน:

1) ค่าตัวกรองของพิกเซลที่อยู่ติดกันจะเปลี่ยน (ขึ้นอยู่กับตัวกรองที่ใช้) ที่จะขยายผลของการเปลี่ยนแปลงเล็กน้อย

2) การเปลี่ยนแปลงจะหมายถึงการจับคู่กับพื้นที่นั้นจะแตกต่างกัน ตัวอย่างเช่นการเปลี่ยน 333333 เป็น 333533 สาเหตุที่เกิดขึ้นอีก 333333 จะไม่ตรงกันอีกต่อไปดังนั้นมันจะเลือกการแข่งขันอื่นเป็น 333333 ด้วยระยะทางที่แตกต่างกันหรือจะเลือกการแข่งขันเดียวกัน แต่มีความยาวที่สั้นกว่าและอีกคู่สำหรับ 3 ไบต์สุดท้าย โดยตัวของมันเองนั้นจะเปลี่ยนผลลัพธ์ได้มากมาย

3) ปัญหาที่ใหญ่ที่สุดคือในขั้นตอนที่ 3 รหัส huffman ใช้จำนวนตัวแปรของบิตดังนั้นแม้การเปลี่ยนแปลงเล็กน้อยจะส่งผลให้ทุกอย่างที่ตามมาไม่ได้จัดแนวอีกต่อไป AFAIK อัลกอริธึมการบีบอัดส่วนใหญ่ไม่สามารถตรวจจับคู่ที่ไม่ได้จัดแนวไบต์เพื่อป้องกันการบีบอัด (หรืออย่างน้อยก็ลดจำนวนมาก) ในข้อมูลที่บีบอัดแล้วซึ่งตามหลังการเปลี่ยนแปลงเว้นแต่คอมเพรสเซอร์จะตรวจจับคู่ที่ไม่ได้จัดแนวไบต์

ปัญหาอื่น ๆ ได้รับการครอบคลุมโดยการตอบกลับอื่น ๆ :

4) Gzip ใช้อัลกอริธึม Deflate เดียวกันกับพจนานุกรม 32KB ดังนั้นหากไฟล์ png ใหญ่กว่า 32KB การจับคู่จะไม่ถูกตรวจจับแม้ว่าจะเหมือนกันก็ตาม Bzip2 ดีกว่าในด้านนั้นเนื่องจากใช้บล็อกขนาด 900 KB XZ ใช้ LZMA ซึ่ง IIRC มีพจนานุกรม 4 MB ในระดับการบีบอัดเริ่มต้น 5) รูปแบบ Zip ไม่ใช้การบีบอัดที่เป็นของแข็งดังนั้นมันจะไม่บีบอัดไฟล์ที่คล้ายกันหรือเหมือนกันกว่านี้

บางทีคอมเพรสเซอร์จากตระกูล PAQ หรือ PPMD ​​อาจบีบอัดได้ดีกว่า แต่ถ้าคุณต้องการบีบอัดไฟล์รูปภาพที่คล้ายกันจำนวนมากคุณสามารถพิจารณาได้ 3 วิธี:

1) จัดเก็บรูปภาพที่ไม่บีบอัด (ด้วย PNG -0 หรือในรูปแบบที่ไม่มีการบีบอัด) และบีบอัดด้วยคอมเพรสเซอร์ที่มีพจนานุกรมหรือบล็อกขนาดใหญ่ (LZMA จะทำงานได้ดี)

2) ตัวเลือกอื่นจะเก็บตัวกรองไว้ แต่เอาการบีบอัดแบบยุบออกจาก PNG ที่สามารถทำได้เช่นกับยูทิลิตี้( AdvDef ) จากนั้นคุณบีบอัด PNG ที่ไม่ได้บีบอัด หลังจากคลายการบีบอัดคุณสามารถเก็บ PNG ที่ไม่บีบอัดหรือบีบอัดอีกครั้งด้วย AdvDef (แต่จะใช้เวลา)

คุณต้องทดสอบทั้งสองวิธีเพื่อดูว่ามีการบีบอัดมากที่สุด

3) ตัวเลือกสุดท้ายคือการแปลงภาพ png ในวิดีโอบีบอัดด้วยวิดีโอแบบ lossless เช่น x264 lossless (ดูแลเป็นพิเศษโดยใช้รูปแบบสีที่ถูกต้อง) จากนั้นในการแยกเฟรมไปยังรูปภาพ png แต่ละภาพ สามารถทำได้ด้วย ffmpeg คุณจะต้องทำการจับคู่ระหว่างหมายเลขเฟรมกับชื่อเดิมต่อไป

นั่นจะเป็นวิธีที่ซับซ้อนที่สุด แต่ถ้า pngs เป็นส่วนหนึ่งของอนิเมชั่นมันอาจจะมีประสิทธิภาพที่สุด อย่างไรก็ตามคุณจะต้องใช้รูปแบบวิดีโอที่รองรับความโปร่งใสหากคุณต้องการ

แก้ไข: นอกจากนี้ยังมีรูปแบบ MNG ที่ไม่ได้ใช้บ่อย


2

เมื่อคุณมีชุดข้อมูลพิเศษที่คุณใช้อัลกอริทึมพิเศษไม่ใช่เครื่องมืออเนกประสงค์

คำตอบคือการบีบอัดแบบไม่สูญเสียที่คุณเลือกไม่ได้ทำเพื่อสิ่งที่คุณทำ ไม่มีใครคาดหวังให้คุณบีบอัดภาพเดียวกันสองครั้งและแม้ว่าคุณทำ (โดยไม่ได้ตั้งใจ) การตรวจสอบกับอินพุตก่อนหน้านี้ทั้งหมดจะทำให้อัลกอริทึมของคุณ O (n ^ 2) (อาจจะดีกว่านิดหน่อย แต่วิธี naiv 2)

โปรแกรมบีบอัดส่วนใหญ่ที่คุณทดสอบเมื่อใช้งานใน O (n) จะเน้นความเร็วในอัตราส่วนการอัดที่เหมาะสมที่สุด ไม่มีใครต้องการที่จะใช้คอมพิวเตอร์ของเขาเป็นเวลา 5 ชั่วโมงเพื่อเพียงไม่กี่ MB โดยเฉพาะอย่างยิ่งวันนี้ สำหรับอินพุตที่มีขนาดใหญ่กว่าสิ่งใดก็ตามที่อยู่เหนือ O (n) จะกลายเป็นปัญหาของรันไทม์

ปัญหาอีกประการคือ ram คุณไม่สามารถเข้าถึงทุกส่วนของข้อมูลของคุณได้ตลอดเวลาเมื่อข้อมูลมีขนาดใหญ่พอ แม้จะไม่สนใจสิ่งนี้ผู้คนส่วนใหญ่ไม่ต้องการที่จะยอมแพ้ทั้ง ram หรือ cpu เพื่อบีบอัดบางอย่าง

หากคุณมีรูปแบบในไฟล์ที่คุณต้องการบีบอัดคุณจะต้องดำเนินการกับมานูเอลเขียนการบีบอัดของคุณเองหรืออาจใช้ "เก็บถาวร" -type-compression (nano) การบีบอัดสำหรับการจัดเก็บระยะยาวที่ช้าเกินไปสำหรับการใช้งานในชีวิตประจำวัน

ตัวเลือกอื่นอาจเป็นการบีบอัดวิดีโอแบบไม่สูญเสียข้อมูล


1
เนื่องจากมันเป็นเรื่องธรรมดามากที่โครงสร้างไดเรกทอรีจะมีไฟล์ที่เหมือนกันหลาย ๆ ไฟล์ในที่ต่างกันดูเหมือนว่ายูทิลิตี้สไตล์ซิปที่ดีควรมีตัวเลือกเพื่อตรวจสอบว่าไฟล์ที่ถูกเพิ่มเข้าไปในไฟล์เก็บถาวรนั้นมีค่าแฮช ที่ตรงกับของไฟล์ที่มีอยู่ หากทั้งแฮชและทั้งสองขนาดตรงกันน่าจะแนบชื่อที่สองไปยังบล็อกข้อมูลที่เชื่อมโยงกับไฟล์แรก แม้ว่า ZIP จะไม่สามารถรองรับได้ แต่ดูเหมือนว่าจะมีประโยชน์ในรูปแบบใด ๆ ในอนาคต
supercat

1
คำตอบของคุณหมายถึงอัลกอริทึมการบีบอัดของ tar นั้นดีสำหรับการบีบอัดความซ้ำซ้อนบางประเภท แต่ไม่ใช่สำหรับชนิดที่เกิดขึ้นในสถานการณ์ของ OP คุณอาจต้องการที่จะอธิบายสิ่งที่ชนิดของความซ้ำซ้อนคุณคิดว่ามันเป็นสิ่งที่ดีสำหรับเนื่องจากที่ไม่ได้ทั้งหมดที่เห็นได้ชัด สำหรับคนที่อาจไม่เคยใช้คอมเพรสเซอร์นี้มาก่อนสิ่งที่พวกเขาเห็นคือพวกเขาลองในสิ่งที่ค่อนข้างบีบอัดได้ในทางทฤษฎีมันใช้งานไม่ได้
Don Hatch

1
@leftaroundabout: ไม่มีวิธีใดใน Unix ที่ฉันรู้ว่าจะใช้ซีแมนทิกส์ "copy-on-write" กับไฟล์ที่ตรงกัน ในหลายกรณีสำเนาที่ซ้ำซ้อนมีอยู่เพื่อจัดการกับความจริงที่ว่าสิ่งที่อาจเหมือนกันในวันนี้อาจจะไม่เหมือนกันในวันพรุ่งนี้และ symlink หรือ hardlink ดูเหมือนจะไม่เหมาะสมในกรณีเช่นนี้
supercat

1
@supercat: ด้วยไฟล์เหล่านี้หลายไฟล์มันเป็นทางออกที่ดีอย่างสมบูรณ์ในการใช้ symlink กับ "ทางการ" เวอร์ชันสำหรับอ่านอย่างเดียว หากคุณต้องการเปลี่ยนสำเนาของคุณให้แทนที่ symlink ด้วยสำเนาจริง
leftaroundabout

1
@leftaroundabout: สิ่งหนึ่งที่ฉันคิดว่าบางครั้งน่าสนใจถ้าใครสามารถลดอันตรายจากการชนของแฮชที่ได้รับการออกแบบมาให้อยู่ในระดับที่ยอมรับได้จะต้องมีตัวอ้างอิงสากลที่ใช้แฮชดังนั้นแทนที่จะเชื่อมโยงกับชื่อไฟล์ "ตรรกะ" จะสร้างลิงค์ตามแฮช จดหมายเหตุจะเก็บ 256 ไบต์หรือแฮชแทนการจัดเก็บไฟล์ขนาดใหญ่จริงๆ รูปแบบของวิธีการดังกล่าวยังสามารถใช้เพื่อเปิดใช้งานการแคชไฟล์ที่จำเป็นต้องได้รับการปกป้องจากการเปลี่ยนแปลง
supercat

2

รูปแบบไฟล์ PNG ใช้อัลกอริธึมการบีบอัด DEFLATE ภายในแล้ว นี่เป็นอัลกอริทึมเดียวกับที่ใช้โดย xz, gzip และ zip - ในบางรูปแบบเท่านั้น tar.gzและและtar.xzใช้ประโยชน์จากความคล้ายคลึงกันระหว่างไฟล์ซึ่งzipไม่ได้

ดังนั้นในความเป็นจริงคุณทำการบีบอัด DEFLATE บนไฟล์บีบอัด DEFLATE - นี่คือเหตุผลที่ไฟล์เก็บขนาดเดิมเกือบทั้งหมด

bzip2โปรแกรม (ยังมีขั้นตอนวิธีการที่เกี่ยวข้อง) จะดีกว่าเมื่อมันมาถึง (เกือบ) ไฟล์เหมือนกัน

# 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 - โปรดทราบว่ามีการใช้ตัวกรองแบบไม่ยุบมาตรฐาน (อันไหนเป็นแบบมาตรฐานอยู่แล้ว) และคุณคิดถูกว่าการใช้อัลกอริทึมแบบเดียวกันนั้นไม่มีประโยชน์อะไรเลยสองครั้ง (หรืออย่างน้อยก็ไม่เป็นประโยชน์) อัลกอริทึมเดียวกันกับการตั้งค่าที่แตกต่างกันไม่รับประกันว่าจะล้มเหลว นอกจากนี้ยังมีความแตกต่างระหว่าง deflate32, deflate64, LZW, LZMA คุณไม่สามารถพูดได้ว่าพวกมันทั้งหมดใช้ deflate เดียวกัน
Evil

นั่นคือเหตุผลที่ฉันพูดว่า "ในบางรูปแบบ" แน่นอน DEFLATE หมายถึงอัลกอริธึมชนิดหนึ่งแทนที่จะใช้งานบางอย่าง
rexkogitans

3
นี่เป็นจุดที่ฉันเข้าใจ ใช่หนึ่ง PNG ไฟล์คนเดียวที่ถูกบีบอัดแล้วดังนั้นฉันจะไม่คาดหวังการบีบอัดเพิ่มเติมใด ๆ จะมีผลกระทบมาก แต่การต่อไฟล์ PNG ที่เหมือนกันหลาย ๆ ไฟล์ (ซึ่งโดยพื้นฐานแล้วเป็นสถานการณ์ที่นี่) อาจถูกคาดหวังว่าจะบีบอัดให้มีขนาดไม่เกินหนึ่งไฟล์
Don Hatch

เห็นได้ชัดว่าอัลกอริทึมการบีบอัดเหล่านั้นพลาดจุดนั้น bzip2จับมัน: tar -cjf archive.tar.bz2 *.png. อัปเดตในคำตอบของฉัน
rexkogitans
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.