JPEG XL และ Pareto Front
(cloudinary.com)- libjxl 0.10 ลดคอขวดของการเข้ารหัส JPEG XL ที่เคยต้องประมวลผลภาพขนาดใหญ่ทั้งภาพในครั้งเดียวด้วย Streaming Encoding API พร้อมปรับปรุงการใช้หน่วยความจำและความเร็วของการบีบอัดแบบไม่สูญเสียอย่างมาก
- การเข้ารหัสแบบไม่สูญเสียของภาพโลกยามค่ำคืนจาก NASA ขนาด 13500×6750 ลดจาก RAM ราว 8GB·ใช้เวลากว่า 2 นาที ใน libjxl 0.9 เหลือ 0.7GB RAM, 30 วินาทีบนเธรดเดียว และ 5 วินาทีบน 8 เธรดใน libjxl 0.10
- การเปรียบเทียบวิธีบีบอัดดูจากขนาดไฟล์อย่างเดียวไม่พอ โดย ความเร็วในการเข้ารหัสและความหนาแน่นของการบีบอัด เมื่อพิจารณาร่วมกันผ่าน Pareto front กลายเป็นเกณฑ์สำคัญในการเลือกค่าที่เหมาะสมตามงบเวลา
- การบีบอัดแบบสูญเสียต้องดูทั้งอัตราการบีบอัด ความเร็ว และคุณภาพภาพพร้อมกัน โดยในช่วง SSIMULACRA2 60~90 นั้น JPEG XL ให้ผลลัพธ์ที่แข็งแกร่งเป็นพิเศษในช่วง คุณภาพสูง~ใกล้ไม่สูญเสียในเชิงสายตา
- ตัวเข้ารหัส JPEG รุ่นใหม่อย่าง jpegli ยังแข่งขันได้ดีในช่วงที่ต้องการความเร็วเข้ารหัสสูงมาก แต่ JPEG XL ก็ก้าวขึ้นมาเป็นตัวเลือกหลักทั้งสำหรับการบีบอัดแบบไม่สูญเสียและแบบสูญเสียในช่วงความเร็วที่กว้าง
การเปลี่ยนแปลงสำคัญใน libjxl 0.10
- libjxl 0.10 คือเวอร์ชันใหม่ของ reference implementation ของ JPEG XL และการเปลี่ยนแปลงที่ใหญ่ที่สุดคือการทำ Streaming Encoding API ให้สมบูรณ์
- API นี้เข้ารหัสภาพขนาดใหญ่เป็น ชังก์ แทนการประมวลผลทั้งภาพในครั้งเดียว
- ลดภาระ RAM ที่เกิดจากการโหลดภาพทั้งภาพไว้ในหน่วยความจำ
- ความเร็วการเข้ารหัสก็ดีขึ้นด้วย
- โดยเฉพาะกับการบีบอัดแบบไม่สูญเสียของภาพขนาดใหญ่จะเห็นผลชัดเจน
หน่วยความจำและเวลาที่ลดลงในการบีบอัดแบบไม่สูญเสีย
- ก่อนหน้า libjxl 0.10 การเข้ารหัส JPEG XL แบบไม่สูญเสียอาจมีปัญหาเรื่องการใช้หน่วยความจำสูงและใช้เวลานาน
- ภาพตัวอย่างคือ ภาพโลกยามค่ำคืนของ NASA ขนาด 13500×6750
- ไฟล์ TIFF มีขนาด 64MB
- ขนาดก่อนบีบอัดคือ 273MB
- ผลการบีบอัดภาพเดียวกันด้วยค่า effort เริ่มต้น e7:
- libjxl 0.9 ใช้ RAM ราว 8GB และใช้เวลากว่า 2 นาที โดยได้ไฟล์ผลลัพธ์ขนาด 33.7MB
- เธรดเดียวใช้เวลา 2 นาที 40 วินาที, 8 เธรดใช้เวลา 2 นาที 6 วินาที ซึ่งแปลว่าการเพิ่มเธรดช่วยได้ไม่มาก
- สภาพแวดล้อมที่ใช้วัดคือ MacBook Pro เดือนพฤศจิกายน 2023 ที่ใช้ CPU Apple M3 Pro 12 คอร์ และ RAM 36GB
- ใน libjxl 0.10 การบีบอัดภาพเดียวกันต้องใช้ RAM เพียง 0.7GB
- เธรดเดียว 30 วินาที
- 8 เธรด 5 วินาที
- ไฟล์ผลลัพธ์มีขนาด 33.2MB
- เมื่อเพิ่มค่า effort อัตราการบีบอัดจะดีขึ้น แต่ผลตอบแทนต่อเวลา CPU จะค่อย ๆ ลดลง
- จาก e1 ไป e2 ใช้เวลา 1 วินาทีแทน 0.1 วินาที แต่ลดขนาดได้ 22MB
- จาก e2 ไป e7 ใช้เวลา 5 วินาทีแทน 1 วินาที และลดเพิ่มได้อีก 11MB
- จาก e7 ไป e9 หากต้องการลดอีก 1MB ต้องรอเกือบ 2 นาที
จุดสมดุลที่ใช้งานได้จริงของค่า effort
- การตั้งค่าการบีบอัดคือโจทย์เรื่องการแลกเปลี่ยนระหว่าง เวลาและขนาดไฟล์
- ในเวิร์กโฟลว์งานสร้างสรรค์ที่บันทึกไฟล์ลงเครื่องระหว่างแก้ไขภาพ อาจไม่จำเป็นต้องบีบอัดแรงมาก ดังนั้นการเข้ารหัสด้วย effort ต่ำจึงสมเหตุสมผล
- แต่ในสถานการณ์ส่งต่อแบบหนึ่งต่อหลายคนหรือการเก็บระยะยาว การยอมใช้เวลา CPU เพิ่มเพื่อประหยัดอีกไม่กี่ MB อาจคุ้มค่า
เปรียบเทียบวิธีบีบอัดด้วย Pareto front
- เวลาเปรียบเทียบเทคนิคการบีบอัด หากดูแค่ขนาดไฟล์อย่างเดียวก็มักพลาดข้อมูลที่จำเป็นต่อการตัดสินใจจริง
-
แกนที่ใช้เปรียบเทียบและวิธีอ่านกราฟ
- แกนสำคัญคือ ความหนาแน่นของการบีบอัด และ ความเร็วในการเข้ารหัส
- ถ้าวิธีใดเป็น Pareto optimal หมายความว่าไม่มีวิธีอื่นที่ทำความหนาแน่นการบีบอัดได้เท่ากันหรือดีกว่าในเวลาที่สั้นกว่า
- ชุดของวิธีที่เป็น Pareto optimal เรียกว่า Pareto front
- ในกราฟ แกนตั้งคือความเร็วในการเข้ารหัส ส่วนแกนนอนคือค่าเฉลี่ย bits per pixel ของภาพหลังบีบอัด
- แกนตั้งใช้หน่วย megapixels per second และใช้สเกลลอการิทึมเพื่อรองรับช่วงความเร็วที่กว้าง
- ภาพ RGB 8 บิตก่อนบีบอัดมีค่า 24bpp
- ยิ่งอยู่สูงยิ่งเร็ว และยิ่งอยู่ซ้ายยิ่งบีบอัดได้ดี
ผลการเปรียบเทียบการบีบอัดแบบไม่สูญเสีย
- libjxl รุ่นก่อนหน้านี้ก็ให้ผลลัพธ์แบบ Pareto optimal ในทุกช่วงความเร็วอยู่แล้ว และสร้างไฟล์ที่เล็กกว่า PNG, AVIF แบบไม่สูญเสีย และ WebP แบบไม่สูญเสีย
- libjxl 0.10 แสดงผลลัพธ์ที่ดีกว่ารุ่นก่อนอย่าง ชัดเจน
- QOI ไม่ได้แสดงในกราฟ แต่ทำได้ 17bpp ที่ 154Mpx/s
- ค่าความพยายามต่ำสุดของ libjxl บีบอัดได้ถึง 11.5bpp ที่ 427Mpx/s
- ฝั่ง libjxl เร็วกว่า 2.7 เท่าและไฟล์ผลลัพธ์เล็กกว่าถึง 32.5%
การบีบอัดแบบไม่สูญเสียสำหรับภาพที่ไม่ใช่ภาพถ่าย
- ภาพถ่ายมีนอยส์ตามธรรมชาติมากจึงบีบอัดแบบไม่สูญเสียได้ยากกว่า และผลลัพธ์จะต่างออกไปในภาพที่ไม่ใช่ภาพถ่าย
- การทดสอบด้วยภาพการ์ตูน 41 ภาพจากหลายสไตล์ มีขนาดเฉลี่ย 7.3 เมกะพิกเซล
- ภาพประเภทนี้บีบอัดได้ถึงประมาณ 4bpp ซึ่งดีกว่าภาพถ่ายที่อยู่ราว 10bpp มาก
- AVIF แบบไม่สูญเสียไม่ค่อยมีประโยชน์กับภาพประเภทนี้
- อัตราการบีบอัดแย่กว่า PNG
- แม้จะไปถึงความหนาแน่นใกล้ QOI แต่ช้ากว่ามาก
- WebP แบบไม่สูญเสียให้ประสิทธิภาพการบีบอัดที่ดีมากกับภาพแบบนี้
- QOI พอใช้ได้หากให้ความสำคัญกับความเร็วและความเรียบง่าย แต่ยังห่างจากความเป็น Pareto optimal
- การเข้ารหัส JPEG XL ที่ effort ต่ำ เร็วกว่า QOI 2 เท่าและไฟล์เล็กกว่า 31%
- libjxl 0.10 ก็ปรับปรุงดีขึ้นมากจาก 0.9 ในภาพที่ไม่ใช่ภาพถ่ายเช่นกัน
- WebP effort เริ่มต้น: 4.30bpp, 2.3Mpx/s
- libjxl 0.9 effort 5: 4.27bpp, 2.6Mpx/s
- libjxl 0.10 effort 5: 4.25bpp, 12.2Mpx/s
- libjxl 0.10 effort 7: 4.04bpp, 5.9Mpx/s
การบีบอัดแบบสูญเสียมีแกนคุณภาพเพิ่มเข้ามา
- การบีบอัดแบบไม่สูญเสียดูแค่ขนาดที่บีบอัดได้กับความเร็วก็พอ แต่การบีบอัดแบบสูญเสียมี คุณภาพของภาพ เพิ่มเข้ามา
- image codec และ encoder แบบสูญเสียอาจให้ประสิทธิภาพต่างกันตามระดับคุณภาพ
- ตัวเข้ารหัสที่ดีในระดับคุณภาพสูง ไม่ได้แปลว่าจะดีในระดับคุณภาพต่ำด้วย
- และในทางกลับกันก็เช่นกัน
- กราฟ bitrate-distortion ที่ดูแค่อัตราการบีบอัดกับคุณภาพ ทำให้ประเมินจุดแลกเปลี่ยนระหว่าง effort ในการเข้ารหัสกับประสิทธิภาพการบีบอัดได้ยาก
- หากต้องการดู Pareto front ของการบีบอัดแบบสูญเสีย ต้องพิจารณาพื้นที่สามมิติของการบีบอัด ความเร็ว และคุณภาพ แล้วตัดดูตามหลายระดับคุณภาพ
วิธีวัดและสรุปผลคุณภาพภาพ
- คุณภาพของภาพเป็นเรื่องเชิงอัตวิสัยและอาจต่างกันไปในแต่ละคน
- วิธีวัดที่ดีที่สุดคือการให้คนจำนวนหลายสิบคนขึ้นไปเปรียบเทียบหรือให้คะแนนภาพตามโปรโตคอลทดสอบที่เข้มงวด
- แต่การทดลองแบบนี้ใช้เวลาและค่าใช้จ่ายสูง และยากจะทดสอบทุกค่าการตั้งของ encoder จึงต้องใช้ตัวชี้วัดเชิงวัตถุ
- ตัวชี้วัดแบบเปิดที่ถือว่าดี ได้แก่ SSIMULACRA2, Butteraugli, DSSIM
- ตัวชี้วัดเหล่านี้พยายามจำลองระบบการมองเห็นของมนุษย์ และมีความสอดคล้องกับการประเมินเชิงอัตวิสัยได้ดี
- ตัวชี้วัดแบบเก่าและง่ายกว่าอย่าง PSNR หรือ SSIM ไม่ค่อยสอดคล้องกับการตัดสินคุณภาพภาพของมนุษย์
- หากประเมินด้วยตัวชี้วัดที่ encoder ใช้ปรับแต่งภายในอยู่แล้ว ผลอาจเอนเอียงเข้าข้าง encoder นั้นได้
- libjxl ที่ effort สูงจะปรับให้เหมาะกับ Butteraugli
- libavif อาจปรับให้เหมาะกับ PSNR หรือ SSIM
- SSIMULACRA2 ถือว่าเป็นตัวชี้วัดที่ปลอดภัย เพราะ encoder ที่ทดสอบไม่ได้ใช้มันในการปรับแต่งภายใน
- ในการทดสอบ มีการเลือก การตั้งค่า encoder ให้เมื่อใช้กับชุดภาพทั้งหมดแล้ว ค่าเฉลี่ยคะแนน SSIMULACRA2 เข้าใกล้ค่าที่กำหนด
- การจัดตามคะแนนเฉลี่ยเป็นวิธีที่เอื้อกับ WebP และ AVIF
- งานวิจัยก่อนหน้านี้พบว่า AVIF และ WebP มีความสม่ำเสมอน้อยกว่า JPEG และ HEIC ขณะที่ JPEG XL เป็น encoder ที่สม่ำเสมอที่สุด
- ในการใช้งานจริง ผู้ใช้บางรายอาจอยากควบคุมคะแนนที่แย่ที่สุด หรือคุณภาพภาพที่แย่ที่สุดจริง ๆ มากกว่า
ช่วงคุณภาพที่ใกล้เคียงการใช้งานจริง
- การบีบอัดแบบสูญเสียสามารถทำอัตราการบีบอัดสูงมากอย่าง 50:1 หรือ 200:1 ได้ แต่ก็จะเกิด compression artifacts
- ช่วงที่เกี่ยวข้องกับการใช้งานจริงมากคือ SSIMULACRA2 60~90
- ลักษณะของแต่ละระดับคุณภาพ:
- SSIMULACRA2 90: คุณภาพระดับใกล้ไม่สูญเสียในเชิงสายตา โดย codec สมัยใหม่อย่าง AVIF และ JPEG XL ไปถึงได้ที่อัตราการบีบอัดราว 8:1 หรือ 3bpp
- SSIMULACRA2 80: คุณภาพสูง ไปถึงได้ที่อัตราการบีบอัดราว 16:1 หรือ 1.5bpp
- SSIMULACRA2 70: คุณภาพระดับกลางค่อนสูง ไปถึงได้ที่อัตราการบีบอัดราว 30:1 หรือ 0.8bpp
- SSIMULACRA2 60: คุณภาพระดับกลาง ไปถึงได้ที่อัตราการบีบอัดราว 40:1 หรือ 0.6bpp
- คุณภาพที่ต่ำกว่า SSIMULACRA2 60 อาจลดการใช้แบนด์วิดท์ได้มากขึ้น แต่ก็เสี่ยงทำลายภาพ
- บนเว็บในปี 2024 ช่วงคุณภาพระดับกลางถึงสูงยังมีความเกี่ยวข้องมาก
- ตามข้อมูลของ HTTP Archive ค่ามัธยฐานของ AVIF บนเว็บอยู่ที่ 1bpp ซึ่งเทียบได้กับคุณภาพระดับกลางค่อนสูง
- ค่ามัธยฐานของ JPEG อยู่ที่ 2.1bpp ซึ่งเทียบได้กับคุณภาพสูง
- ในกรณีการใช้งานนอกเว็บอย่างกล้องถ่ายภาพ ช่วงคุณภาพสูงถึงใกล้ไม่สูญเสียในเชิงสายตาจะเกี่ยวข้องมากกว่า
ผลลัพธ์ของ Pareto front สำหรับการบีบอัดแบบสูญเสีย
- การทดสอบการบีบอัดแบบสูญเสียใช้เวอร์ชันล่าสุดของแต่ละ encoder ณ ปลายเดือนกุมภาพันธ์ 2024
- ความเร็วในการเข้ารหัสวัดบน MacBook Pro เดือนพฤศจิกายน 2023 ที่ใช้ Apple M3 Pro โดยใช้ 8 เธรด
- AVIF ถูกทดสอบทั้งแบบใช้ไทล์และไม่ใช้ไทล์
- การตั้งค่าแบบใช้ไทล์ใช้มัลติเธรดได้ดีกว่าจึงเร็วกว่า
- แต่แลกมาด้วยความหนาแน่นการบีบอัดที่ลดลง
คุณภาพระดับกลาง: SSIMULACRA2 60
- แม้อยู่ในฟอร์แมตเดียวกัน ผลลัพธ์ก็แตกต่างกันมากตาม encoder และค่า effort
- การตั้งค่าเริ่มต้นของ libjpeg-turbo ซึ่งเป็น encoder JPEG ที่ใช้กันแพร่หลายมายาวนาน อยู่ในตำแหน่งที่เร็วที่สุดในกราฟ แต่มีความหนาแน่นการบีบอัดต่ำกว่า
- WebP ให้ความหนาแน่นการบีบอัดดีกว่า libjpeg-turbo
- mozjpeg ช้ากว่า libjpeg-turbo แต่ให้ผลการบีบอัดดีกว่า และสำหรับชุดภาพกับระดับคุณภาพนี้ก็มีประสิทธิภาพเชิง Pareto ดีกว่า WebP
- jpegli ซึ่งสร้างโดยทีม JPEG XL ของ Google เร็วกว่า mozjpeg และมีอัตราการบีบอัดดีกว่าด้วย
- พัฒนาบนบทเรียนที่ได้จาก guetzli และ libjxl
- บีบอัดได้ดีกว่า WebP และ AVIF แบบเร็ว ขณะที่ยังคงสร้างไฟล์ JPEG แบบเดิม
- AVIF และ HEIC ให้ความหนาแน่นการบีบอัดดีกว่า JPEG และ WebP ได้ แต่การเข้ารหัสช้ากว่า
- JPEG XL เข้าถึงความหนาแน่นการบีบอัดใกล้เคียงกันได้ แต่เข้ารหัสเร็วกว่าอย่างมาก
- Pareto front ของระดับคุณภาพนี้จึงประกอบด้วย JPEG XL และ encoder JPEG หลายตัวในช่วงความเร็วที่สมเหตุสมผล และมี AVIF ในช่วงที่ช้ากว่า
ผลลัพธ์ในระดับคุณภาพกลางค่อนสูงและคุณภาพสูง
- ที่คุณภาพระดับกลางค่อนสูง SSIMULACRA2 70 ผลลัพธ์โดยรวมคล้ายกับระดับคุณภาพกลาง
- มีการใช้ค่าเฉลี่ย SSIMULACRA2 85 เป็นระดับคุณภาพสูงสุดที่เกี่ยวข้องกับเว็บ โดยตั้งค่าให้ภาพส่วนใหญ่ทำได้เกิน 80
- ในระดับคุณภาพสูงนี้ ความต่างจะยิ่งชัดขึ้น
- mozjpeg ไม่สามารถชนะ WebP ได้อีกต่อไป
- jpegli ยังเอาชนะ WebP ได้อยู่
- Pareto front ส่วนใหญ่ถูกครองโดย JPEG XL
- ในช่วงที่ต้องการเข้ารหัสเร็วมาก JPEG แบบดั้งเดิมก็ยังดีอยู่
- ที่ระดับคุณภาพนี้ AVIF ไม่ได้อยู่บน Pareto front
- ในค่าที่ช้าที่สุด มันทำความเร็วได้ต่ำกว่า 0.5Mpx/s แต่ให้ความหนาแน่นการบีบอัดเท่ากับการตั้งค่า libjxl ที่เร็วเป็นอันดับสอง
- การตั้งค่า libjxl นั้นทำได้ 52Mpx/s เร็วกว่าเกิน 100 เท่า
ความเร็วในการถอดรหัส
- การเปรียบเทียบจนถึงตอนนี้เน้นที่ความหนาแน่นการบีบอัดและความเร็วในการเข้ารหัส
- บนคอมพิวเตอร์สมัยใหม่ ความเร็วในการถอดรหัสไม่ใช่ปัญหาใหญ่ แต่ก็มีการนำค่าที่วัดได้มาเปรียบเทียบด้วย
- JPEG แบบ sequential แข็งแกร่งที่สุดในด้านความเร็วถอดรหัส
- Progressive JPEG ที่สร้างโดย mozjpeg และ jpegli ค่าเริ่มต้นจะช้ากว่า แต่ก็ยังเร็วพอที่จะโหลดภาพขนาดสมเหตุสมผลได้อย่างรวดเร็วมาก
- JPEG XL อยู่กึ่งกลางระหว่าง JPEG แบบ sequential และ Progressive JPEG
- ความเร็วในการถอดรหัสของ AVIF แตกต่างกันตามวิธีเข้ารหัส
- ถ้าใช้การเข้ารหัสแบบ multi-tile ที่เร็วกว่าแต่คุณภาพแย่นิดหน่อย การถอดรหัสก็เร็วขึ้นด้วย
- ส่วนการเข้ารหัสแบบ single-tile เริ่มต้นจะช้ากว่า
- แม้แต่ค่าความเร็วถอดรหัสที่ช้าที่สุดที่วัดได้ ก็ยังถือว่าเร็วพอเมื่อเทียบกับความเร็วในการเข้ารหัส
คุณภาพใกล้ไม่สูญเสียในเชิงสายตาและภาพขนาดใหญ่
- กราฟคุณภาพระดับใกล้ไม่สูญเสียในเชิงสายตาไม่ได้รวม WebP ไว้
- เพราะในโหมดสูญเสีย WebP ไปไม่ถึงระดับคุณภาพนี้
- เนื่องจาก WebP บังคับใช้ 4:2:0 chroma subsampling
- mozjpeg ก็ไม่ได้ถูกออกแบบมาสำหรับระดับคุณภาพนี้ จึงแย่กว่า libjpeg-turbo ทั้งด้านการบีบอัดและความเร็ว
- ที่การตั้งค่าความเร็วเริ่มต้น libavif ให้ไฟล์เล็กกว่า libjpeg-turbo 20% แต่ใช้เวลาเข้ารหัสนานกว่าหนึ่งหลัก
- ในระดับคุณภาพเดียวกัน libjxl ให้ไฟล์เล็กกว่า libavif 20% และเร็วกว่า 2.5 เท่า
- Pareto front ของคุณภาพระดับใกล้ไม่สูญเสียในเชิงสายตาส่วนใหญ่ถูกครองโดย JPEG XL และมี JPEG รวมอยู่ในช่วงความเร็วสูงสุดด้วย
- ต่างจากการทดสอบภาพขนาดเว็บราว 1 เมกะพิกเซล ผลสำหรับภาพขนาดใหญ่แตกต่างออกไปมาก
- ที่ระดับคุณภาพสูง WebP, mozjpeg และ AVIF แย่กว่า libjpeg-turbo
- HEIC ให้การลดขนาดได้อย่างมีนัยสำคัญเมื่อเทียบกับ libjpeg-turbo
- jpegli ก็ให้การลดขนาดได้มากพร้อมความเร็วที่ดีกว่า
- JPEG XL บีบอัดภาพให้ต่ำกว่า 1.3bpp ได้ ขณะที่ AVIF, libjpeg-turbo และ WebP ต้องใช้มากกว่า 2bpp
ตำแหน่งสุดท้ายของ libjxl 0.10
- libjxl 0.10 ลดการใช้หน่วยความจำลง ระดับหนึ่งหลัก ทั้งในการบีบอัดแบบไม่สูญเสียและแบบสูญเสีย
- ความเร็วก็ดีขึ้น โดยเฉพาะการเข้ารหัสแบบไม่สูญเสียหลายเธรดที่ค่า effort เริ่มต้นซึ่งเร็วขึ้นระดับหนึ่งหลัก
- JPEG XL ถูกสรุปได้ว่าเป็น image codec ที่แข็งแกร่งทั้งสำหรับการบีบอัดแบบไม่สูญเสียและแบบสูญเสีย โดยเฉพาะในช่วงคุณภาพสูงถึงใกล้ไม่สูญเสียในเชิงสายตา
- ในช่วงการตั้งค่าความเร็วที่กว้าง JPEG XL ยังคงเป็นตัวเลือกที่ใกล้เคียง Pareto optimal
- JPEG แบบเดิมก็ยังน่าสนใจอยู่ด้วยอานิสงส์ของ encoder รุ่นใหม่
- jpegli ปรับปรุงทั้งความเร็วและการบีบอัดเหนือกว่า mozjpeg อย่างมาก
- หากต้องการการเข้ารหัสที่เร็วสุดขีด JPEG แบบเดิมก็อาจยังเป็นตัวเลือกที่ดีที่สุด
2 ความคิดเห็น
เอนโค้ดเดอร์
jpegliกำลังยืดอายุให้ jpg ได้อีกครั้งต่อจาก mozjpeg...แม้จะถูกสร้างขึ้นโดยฝั่ง JXL แต่ก็น่าแดกดันที่มันอาจขัดขวางการแพร่หลายของ JXL เองก็ได้...
ความคิดเห็นจาก Hacker News
ควรให้ความสำคัญด้วยว่า WebP แบบไม่สูญเสียข้อมูล ดีแค่ไหน
ประเด็นนี้มักถูกกลบด้วยคำพูดที่ว่า WebP ไม่มีข้อได้เปรียบชัดเจนเมื่อเทียบกับการเข้ารหัสด้วย MozJPEG หรือแย่กว่าด้วยซ้ำ แต่ WebP แบบไม่สูญเสียข้อมูลนั้นยอดเยี่ยมจริง ๆ ทั้งด้านประสิทธิภาพและความเร็ว
ดีกว่า PNG หรือ OptiPNG มาก การรองรับออนไลน์ก็เพียงพอแล้ว และแน่นอนว่ายังเหนือกว่า AVIF แบบไม่สูญเสียข้อมูลที่แย่มากอย่างมากด้วย
สำหรับภาพ SDR ก็ใช้ได้ แต่สำหรับ HDR นี่เป็นข้อจำกัดพื้นฐานพอ ๆ กับที่ GIF ถูกจำกัดไว้ที่ 256 สี
ถ้าจะบีบอัดการ์ตูนทั้งเรื่อง PNG ยังเป็นตัวเลือกที่ถูกต้อง และในกรณีนี้ควรใช้ oxipng มากกว่า optipng ซึ่งแทบจะถูกเลิกใช้ไปแล้ว
อีกประเด็นที่ไม่ได้กล่าวถึงคือ JPEG2000 แบบไม่สูญเสียข้อมูลอาจดีและเร็วอย่างน่าประหลาดใจสำหรับคอนเทนต์ภาพถ่าย
สำหรับการใช้งานส่วนใหญ่ น่าจะเป็นตัวเลือกที่ดีกว่าแบบไม่สูญเสียจริง และมักลดขนาดลงได้ครึ่งหนึ่งโดยไม่มีความสูญเสียที่มองเห็นได้เพิ่มเติม
ในการตั้งค่าคุณภาพต่ำมาก เป็นเรื่องน่าประหลาดใจที่ JPEG แม้จะดูเละเหมือนภาพคิวบิสม์เมื่อมองใกล้ ๆ เพราะอาร์ติแฟกต์ที่เห็นชัด แต่ยังคง การประมาณรายละเอียดที่คมชัด ซึ่งรักษาคุณภาพโดยรวมของภาพได้ดีกว่า
โดยพื้นฐานแล้วมันเหมือนเปลี่ยนภาพให้เป็นศิลปะแนวนามธรรมบางแบบ ขณะที่ JXL และ AVIF แค่ทำให้ภาพเบลอ
ภาพเหล่านี้ไม่ได้เทียบกันที่อัตราบีบอัดเท่ากัน แต่พยายามให้ได้ระดับความบิดเบือนเท่ากัน และจำนวนบิตต่อพิกเซลแสดงอยู่ข้างภาพ
ในอินเทอร์เน็ตจริง ๆ การใช้คุณภาพ 65 นั้นหายาก และพบได้เฉพาะเว็บคุณภาพต่ำสุด คุณภาพ 75 คือคุณภาพต่ำที่พบได้ทั่วไป ส่วนคุณภาพ 85 ใกล้เคียงค่าเฉลี่ย
เมื่อต้องการบีบอัด จะใช้คุณภาพ 94 yuv444 ขึ้นไป
บิตเรตอยู่ในคอลัมน์ซ้าย และ JPG คุณภาพต่ำมีขนาดเท่ากับ JXL/AVIF คุณภาพระดับกลางค่อนไปต่ำที่ 0.4bpp ดังนั้นควรเทียบภาพล่างซ้ายกับภาพกลางบนและภาพขวา
อย่าหลงไปกับการเปรียบเทียบที่ผิด และถ้าให้ขนาดไฟล์กับ JXL และ AVIF เป็นสองเท่า มันก็จะดูดีขึ้นมากเช่นกัน
SSIMULACRA2 ดูเหมือนจะลงโทษอาร์ติแฟกต์แบบบล็อกอย่างหนัก แต่ไม่ค่อยใส่ใจกับความเบลอ และผมเห็นด้วยว่าถ้าได้คะแนน SSIMULACRA2 เท่ากัน เวอร์ชัน JPEG ดูดีกว่า
ไม่เข้าใจว่าทำไมบทความนี้ถึงเน้น ความเร็วในการเข้ารหัส ขนาดนั้น แต่กลับพูดถึงการถอดรหัส ซึ่งน่าจะคิดเป็น 99% ของการใช้งานในสภาพแวดล้อมการเชื่อมต่อเว็บแบบผ่าน ๆ
แค่ข้ามไปประมาณว่า “ความเร็วในการถอดรหัสไม่ใช่ปัญหาใหญ่บนคอมพิวเตอร์สมัยใหม่ แต่การดูตัวเลขแบบเร็ว ๆ ก็น่าสนใจ”
เพราะตั้งแต่จุดนั้น คอขวดไม่ใช่การถอดรหัสอีกต่อไป
อัลกอริทึมบีบอัดสมัยใหม่ส่วนใหญ่เป็นแบบอสมมาตร จึงใช้เวลาบีบอัดได้มากกว่ามากโดยแทบไม่กระทบต่อประสิทธิภาพการคลายบีบอัด ดังนั้นเมื่อได้ประสิทธิภาพพื้นฐานแล้ว มันก็สำคัญน้อยลง
ถ้าเป็นไปได้ นั่นจะเป็นเหตุผลที่แข็งแรงในการเลือกสิ่งเหล่านี้มากกว่า JPEG XL ซึ่งบนฮาร์ดแวร์ปัจจุบันต้องถอดรหัสด้วยซอฟต์แวร์ทั้งหมด
การถอดรหัส H264 มีอยู่ทุกที่ และการถอดรหัส AV1 ก็กำลังกลายเป็นฟีเจอร์มาตรฐานอย่างต่อเนื่อง
แค่ไคลเอนต์ถอดรหัสภาพไม่กี่ภาพบนหน้าเว็บได้เร็วพอจนมนุษย์ไม่รู้สึกก็เพียงพอแล้ว ในทางกลับกัน หากปรับปรุงการเข้ารหัสได้แม้เพียงไม่กี่เปอร์เซ็นต์ ก็ลดต้นทุนจริงได้
ในความเป็นจริง พวกเขาใช้เงินหลายล้านดอลลาร์กับการเข้ารหัสภาพ
เห็นมี QOI อยู่ในเบนช์มาร์กแบบไม่สูญเสียข้อมูลแล้วอดขำไม่ได้
เป็นฟอร์แมตที่ซอฟต์แวร์สำหรับผู้ใช้ทั่วไปไม่ได้รองรับในตัว และแทบไม่เกี่ยวข้อง เพราะตั้งเป้าแค่ “พอใช้” มากกว่าจะ “ดี” แต่ก็น่าสนใจที่มันได้กินพื้นที่หนึ่งตำแหน่งในชาร์ตการเข้ารหัสภาพที่ไม่ใช่ภาพถ่าย
ดังนั้น GameMaker Studio และเกมที่สร้างในช่วงราว 2 ปีล่าสุดจึงใช้ QOI ภายในจริง ๆ
ผู้บริโภคอาจไม่ได้ใช้โดยรู้ตัว แต่ก็ยากจะบอกว่าไม่เกี่ยวข้องเลย
พอมองย้อนกลับไปก็เป็นเรื่องแน่นอนอยู่แล้ว เพราะการถอดรหัส QOI โดยธรรมชาติเป็นแบบลำดับ จึงทำให้ขนานงานได้ไม่ง่าย
สงสัยว่าความยอดเยี่ยมของ JXL มาจากตัวฟอร์แมตเองหรือมาจากเอนโค้ดเดอร์
ความสามารถในการสร้างภาพขนาดเล็กแต่คุณภาพสูงได้ด้วยแค่
-d 1.0นั้นแทบจะน่าประหลาดใจ และในโคเดกอื่น ๆ หากอยากได้ผลลัพธ์ใกล้เคียงกัน ต้องตั้งค่าคุณภาพต่างกันไปตามประเภทของภาพด้วยความเร็วในการพัฒนาแบบนี้ คงไม่น่าแปลกใจถ้า libjxl จะกลายเป็น x264 ของวงการเอนโค้ดเดอร์ภาพ
ในทางกลับกัน libvpx เป็นเอนโค้ดเดอร์ที่ธรรมดามาตลอด และผมคิดว่านั่นอาจเป็นสาเหตุของประสิทธิภาพที่น่าผิดหวังของฟอร์แมต vp8/vp9 ไม่ใช่แค่ด้านความเร็ว แต่รวมถึงประสิทธิภาพโดยรวมด้วย
เรื่องนี้ย่อมส่งผลต่อประสิทธิภาพของ WebP แบบสูญเสียข้อมูลอย่างหลีกเลี่ยงไม่ได้ และ Dark Shikari ก็เคยเปรียบเทียบประสิทธิภาพภาพนิ่งของ x264 กับ vp8 ด้วย [0]
[0] https://web.archive.org/web/20150419071902/http://x264dev.mu...
ยังคงให้ความสำคัญมากกับการสูญเสียแบบแทบมองไม่ออก และไม่อยากใส่ฟีเจอร์ของฟอร์แมตที่ไม่ได้ช่วยในการตั้งค่าคุณภาพสูง แต่เพิ่มความซับซ้อนเท่านั้น
นอกจากความสามารถด้านการทำโมเดลแล้ว การทำ context modeling และประสิทธิภาพของ entropy coding ก็สำคัญมากในคุณภาพสูง
ผมมองว่า entropy coding ของ AVIF ไม่ค่อยเหมาะกับภาพถ่ายคุณภาพสูงหรือแบบไม่สูญเสียข้อมูล
-d 1.0แบบเดียวกันด้วยเป็นเรื่องที่ควรกล่าวถึงว่า จากงาน JPEG XL ยังได้ไลบรารีขนานตัวใหม่ที่ยอดเยี่ยมชื่อ Highway ออกมาด้วย
ไลบรารีนี้ถูกใช้ไม่ใช่แค่ใน JPEG XL แต่ยังใช้ในโมเดล AI Gemma รุ่นล่าสุดของ Google ด้วย
ใน [1] ก็พูดถึงเช่นกัน โดยเริ่มต้นว่า: “วันนี้เราแชร์โค้ดโอเพนซอร์สที่จัดเรียงอาร์เรย์ตัวเลขได้เร็วกว่า C++
std::sortประมาณ 10 เท่า และยังคงพกพาได้ข้ามสถาปัตยกรรม CPU สมัยใหม่ทั้งหมด ขณะเดียวกันก็เร็วกว่าวิธีเฉพาะสถาปัตยกรรมสมัยใหม่ด้วย ด้านล่างเราจะอธิบายว่าเราทำสิ่งนี้ได้อย่างไร”[0] https://github.com/google/highway
[1] https://opensource.googleblog.com/2022/06/Vectorized%20and%2..., งานวิจัยที่เกี่ยวข้องคือ https://arxiv.org/pdf/2205.05982.pdf
ดูเหมือนจะเป็นวิธีที่ดีที่สุดในการได้ SIMD แบบพกพาใน C++
ไม่ว่า JPEG XL จะโดดเด่นด้วยตัวเองแค่ไหน แค่ความสามารถทำสิ่งต่อไปนี้ได้ก็นับว่ายอดเยี่ยมแน่นอน
a.jpgมีขนาด 615504 ไบต์ และ SHA-1 คือ716744d950ecf9e5757c565041143775a810e10fเมื่อรัน
cjxl a.jpg a.jxlจะอ่าน JPEG ขนาด 615504 ไบต์ แล้วบีบอัดเหลือ 537339 ไบต์รวมคอนเทนเนอร์แต่เมื่อรัน
djxl a.jxl b.jpgจะอ่านข้อมูลบีบอัดขนาด 537339 ไบต์แล้วสร้างกลับเป็น JPEG และb.jpgก็มีขนาด 615504 ไบต์พร้อม SHA-1 ที่เหมือนกันทุกประการเมื่อนึกว่ามีไฟล์ JPEG หลายพันล้านไฟล์ในโลกที่เราอยากเก็บรักษาไว้ หากนำ JPEG เดิมไปบีบอัดซ้ำด้วยฟอร์แมตแบบสูญเสียข้อมูล คุณภาพก็จะลดลง
แต่ JPEG XL สามารถ ประหยัดพื้นที่ได้ 15~30% พร้อมทั้งกู้คืน JPG ต้นฉบับให้เหมือนเดิมระดับบิต 100% ได้หากต้องการ
เจ๋งจริง ๆ
น่าเสียดายที่ผมใช้ Debian stable 12 Bookworm อยู่ ซึ่งเป็น ImageMagick 6.9 และเท่าที่รู้ Emacs น่าจะใช้ ImageMagick เวลาแสดงภาพ
การรองรับ JPEG XL เพิ่งถูกเพิ่มใน ImageMagick 7 และผมยังไม่ได้ขุดต่อไปกว่านี้
คิดว่ามันจะช่วยรักษามรดกดิจิทัลไว้ได้ครบถ้วนโดยไม่ต้อง re-encode แบบสูญเสียข้อมูล
น่าประทับใจมากที่ libjxl เวอร์ชันใหม่ ลดการใช้หน่วยความจำลงในระดับหนึ่งหลักของขนาดเดิม ทั้งในการบีบอัดแบบสูญเสียข้อมูลและไม่สูญเสียข้อมูล และยังปรับปรุงความเร็วด้วย
โดยเฉพาะส่วนที่การตั้งค่า effort เริ่มต้นของการเข้ารหัสแบบไม่สูญเสียข้อมูลหลายเธรดตอนนี้เร็วขึ้นในระดับหนึ่งหลักของขนาดเดิม และบทความก็เขียนได้ดี
สงสัยว่ามีเว็บไซต์ที่อธิบายแต่ละขั้นตอนของฟอร์แมต JPEG XL อย่างละเอียดหรือไม่
ต่างจาก JPEG แบบดั้งเดิม ผมหาเอกสารที่อธิบายขั้นตอนที่เกี่ยวข้องอย่างชัดเจนได้ยาก ซึ่งน่าเสียดาย เพราะเห็นได้ชัดว่าฟอร์แมตนี้รวมเอานวัตกรรมที่น่าสนใจไว้มากมาย
องค์ประกอบย่อยแต่ละอย่างก็น่าจะมีประโยชน์ในตัวเองด้วย
แก่นหลักคือ DCT ขนาดแปรผัน สูงสุด 128x128, การทำนาย entropy แบบ ANS และการทำนายโครมาตามความสว่าง
https://github.com/libjxl/libjxl/blob/main/doc/encode_effort... ก็แสดงการแบ่งฟีเจอร์ตามระดับ effort ได้ดี
ในบทความไม่มี rav1e ซึ่งเข้ารหัส AV1 และดังนั้นก็คือ AVIF
rav1e เร็วกว่าการใช้งานอ้างอิงอย่าง aom มาก และเคยมีกรณีที่ aom รอ 1 นาทีแล้วยังแปลงภาพไม่เสร็จ ขณะที่ rav1e ใช้ไม่ถึง 10 วินาที
และก็สงสัยว่า rav1e ที่เร็วจะดูดีกว่า jpegli ที่ความเร็วเข้ารหัสสูงหรือไม่
ที่ความเร็วใกล้เคียงกัน ผมไม่เห็นว่าประสิทธิภาพการบีบอัดระหว่างทั้งสองต่างกันมากนัก