ฉันไปข้างหน้าและทำการทดสอบซ้ำอีกครั้งเพื่อดูว่าฉันสามารถทราบได้ว่าเกิดอะไรขึ้น
ขั้นตอน
ฉันสร้างภาพ RGB ขนาด 256 x 256 พิกเซลแบบสุ่มโดยใช้ฟิลเตอร์ "Solid Noise" ใน GIMP (ตัวกรอง> Render> Clouds> Solid Noise ... ) โดยใช้การตั้งค่าเริ่มต้น (ดังที่แสดงด้านล่าง):
และผลลัพธ์:
จากนั้นฉันบันทึกภาพเป็น JPEG โดยใช้การตั้งค่าเริ่มต้น:
จากนั้นฉันถ่ายโอนรูปภาพไปยัง Windows และเปิดรูปภาพด้วย Windows Photo Viewer โดยคลิกขวาที่รูปภาพใน File Explorer และเลือกดูตัวอย่างจากเมนู จากนั้นฉันหมุนภาพโดยใช้ปุ่มที่ด้านล่างและบันทึกภาพโดยไปที่ภาพถัดไปโดยใช้ปุ่มลูกศร
สำหรับการทดสอบด้านล่างแต่ละครั้งฉันเริ่มต้นด้วยการคัดลอกภาพต้นฉบับและหมุน (คลิกที่ปุ่มหมุน) จำนวนครั้งที่สอดคล้องกันก่อนที่จะบันทึก นี่คือขนาด reslting ( ls -l -r
):
size in bytes last-modified date
VVVVV VVVVV
-rwxrwx--- 1 root vboxsf 6258 Nov 8 11:24 original.jpg
-rwxrwx--- 1 root vboxsf 23645 Nov 8 11:30 cw.jpg
-rwxrwx--- 1 root vboxsf 23636 Nov 8 11:30 cw-cw.jpg
-rwxrwx--- 1 root vboxsf 23649 Nov 8 11:30 cw-cw-cw.jpg
-rwxrwx--- 1 root vboxsf 6258 Nov 8 11:27 cw-cw-cw-cw.jpg
-rwxrwx--- 1 root vboxsf 23649 Nov 8 11:31 cw-cw-cw-cw-cw.jpg
-rwxrwx--- 1 root vboxsf 23649 Nov 8 11:29 ccw.jpg
-rwxrwx--- 1 root vboxsf 23636 Nov 8 11:29 ccw-ccw.jpg
-rwxrwx--- 1 root vboxsf 23645 Nov 8 11:29 ccw-ccw-ccw.jpg
-rwxrwx--- 1 root vboxsf 6258 Nov 8 11:27 ccw-ccw-ccw-ccw.jpg
-rwxrwx--- 1 root vboxsf 23649 Nov 8 11:30 ccw-ccw-ccw-ccw-ccw.jpg
สังเกตได้ทันที
- Windows Photo Viewer (WPV) เพิ่มขนาดอย่างรวดเร็ว จำนวนเพิ่มขึ้นประมาณสี่เท่าในการทดสอบนี้!
- รูปภาพใหม่ทั้งหมดจะเพิ่มขนาดใกล้เคียงกัน แต่ไม่เหมือนกัน
- WPV ไม่ได้เข้ารหัสซ้ำอีกครั้งหรือแม้กระทั่งบันทึกภาพอีกครั้งเมื่อมันหมุนไปหลายรอบ 360 องศา (การประทับเวลา 11:27 คือเมื่อไฟล์ถูกคัดลอกครั้งแรก)
การใช้cmp -l
ไฟล์ที่ควรมีเนื้อหาเหมือนกันทำให้เราเห็นว่าไฟล์แตกต่างกันอย่างไร
robert@unity ../jpeg-rotate-test % cmp -l cw.jpg ccw-ccw-ccw.jpg
2223 63 62
2224 60 71
2226 60 64
2227 60 66
robert@unity ../jpeg-rotate-test % cmp -l cw-cw.jpg ccw-ccw.jpg
2223 63 62
2224 60 71
2226 60 64
2227 62 64
robert@unity ..jpeg-rotate-test % cmp -l ccw.jpg cw-cw-cw.jpg
2223 62 63
2224 71 60
2226 64 60
2227 61 64
robert@unity ../jpeg-rotate-test % cmp -l cw.jpg cw-cw-cw-cw-cw.jpg
2221 60 61
2223 63 61
2224 60 66
2226 60 61
2227 60 61
robert@unity ../jpeg-rotate-test % cmp -l ccw.jpg ccw-ccw-ccw-ccw-ccw.jpg
2223 62 63
2224 71 60
2226 64 65
2227 61 64
ไฟล์เหล่านี้แตกต่างกันในสี่ไบต์เท่านั้น (จริง ๆ แล้วในการประทับเวลา), หมายความว่า WPV กำลังทำสิ่งเดียวกันทุกครั้ง; ตอนนี้เราแค่ต้องหาว่ามันคืออะไร
การสังเกตอย่างละเอียด
สำหรับเรื่องนี้ฉันใช้JPEGsnoopเพื่อดูว่าสิ่งที่อยู่ในภาพ
ตั้งแต่เอาท์พุทจะค่อนข้างนานฉันได้เชื่อมโยงกับพวกเขาเป็นส่วนสำคัญ นี่คือบทสรุปของความแตกต่าง:
GIMP ใช้เฉพาะส่วนAPP0
(JFIF) และCOM
(ความคิดเห็น) สำหรับข้อมูลเมตา WPV ออกจากAPP0
ส่วนที่ไม่ได้แตะ แต่อยากรู้อยากเห็นเพิ่มเป็นโมฆะไบต์ไปที่ความคิดเห็น (เพื่อให้มันถูกยกเลิก null)
WPV เพิ่มสองAPP1
ส่วนซึ่งเป็นข้อมูลเมตา Exif และ XMP กลุ่มเหล่านี้มี 4286 และ 12726 ไบต์ตามลำดับ พวกเขาช่วยกันคิดว่าเพิ่มขนาดไฟล์เกือบทั้งหมด
GIMP สร้าง JPEG แบบโปรเกรสซีฟในขณะที่ WPV จะสร้าง JPEG แบบพื้นฐาน (แบบไม่ก้าวหน้า) ด้วยเหตุนี้รูปภาพของ GIMP จึงมีหลายส่วนการสแกนในขณะที่รูปภาพ WPV มีเพียงส่วนเดียว จากประสบการณ์ของฉันภาพความก้าวหน้าบางครั้งก็เล็กกว่าเล็กน้อย
คนพิการใช้การสุ่มตัวอย่าง chroma 1 × 1 ในขณะที่ WPV ใช้การสุ่มตัวอย่างแบบ 2 × 2 สิ่งนี้ทำให้ฉันเชื่อว่า WPV ไม่ได้ใช้การหมุนแบบไม่สูญเสีย "ของจริง" ยกเว้นว่าจะสามารถตรวจจับได้ว่านี่เป็นภาพขาวดำ
เพื่อแก้ไขปัญหาเหล่านี้ฉันได้ทำการทดสอบครั้งที่สอง
ขั้นตอน
ฉันทำตามขั้นตอนที่คล้ายคลึงกับการทดสอบครั้งแรก ฉันสร้างภาพ RGB แบบสุ่ม 256 × 256 โดยใช้ตัวกรองสัญญาณรบกวน RGB (ตัวกรอง> จมูก> จมูก RGB ... ) ด้วยการตั้งค่าต่อไปนี้:
นี่คือผลลัพธ์:
ฉันส่งออกไฟล์เป็น JPEG โดยใช้การตั้งค่าต่อไปนี้:
Progressiveถูกปิดใช้งาน แต่Subsamplingยังคงถูกตั้งค่าเป็น 4: 4: 4 (ซึ่งเป็นอีกชื่อหนึ่งสำหรับSubsampling 1 × 1) คุณภาพเพิ่มขึ้นเป็น 98
ฉันคัดลอกรูปภาพแล้วหมุนสำเนาตามเข็มนาฬิกา; จากนั้นก็คัดลอกเวอร์ชันที่หมุนแล้วหมุนคัดลอกทวนเข็มนาฬิกาเพื่อให้เราสามารถเปรียบเทียบคุณภาพระหว่างต้นฉบับกับ WPV ที่คัดลอกมาประมวลผลได้โดยตรง
ผล
-rwxrwx--- 1 root vboxsf 159774 Nov 8 16:21 original-random.jpg
-rwxrwx--- 1 root vboxsf 222404 Nov 8 16:24 cw-random.jpg
-rwxrwx--- 1 root vboxsf 222467 Nov 8 16:24 cw-ccw-random.jpg
แม้ว่าการเพิ่มขึ้นในครั้งนี้จะน้อยกว่าในแง่ที่เกี่ยวข้อง (ประมาณ 40%) การเพิ่มขึ้นแน่นอนนั้นยิ่งใหญ่กว่า - ประมาณ 62 kB สิ่งนี้ชี้ให้เห็นว่า WMV ใช้การเข้ารหัสที่มีประสิทธิภาพน้อยกว่า
ฉันจะใช้ImageMagickเพื่อเปรียบเทียบภาพสองภาพ:
robert@unity ../jpeg-rotate-test % compare -verbose -metric AE original-random.jpg cw-ccw-random.jpg null:
original-random.jpg JPEG 256x256 256x256+0+0 8-bit sRGB 160KB 0.000u 0:00.009
cw-ccw-random.jpg JPEG 256x256 256x256+0+0 8-bit sRGB 222KB 0.010u 0:00.010
Image: original-random.jpg
Channel distortion: AE
red: 0
green: 0
blue: 0
all: 0
original-random.jpg=> JPEG 256x256 256x256+0+0 8-bit sRGB 0.050u 0:00.020
มีศูนย์พิกเซลที่แตกต่างกันระหว่างการคัดลอกต้นฉบับและหมุน ดังนั้นแม้ว่า WPV จะไม่ใช้การหมุนแบบไม่สูญเสีย "ของจริง" แต่ก็เป็นการทำงานที่ดีพอ ฉันสงสัยว่าฉันรู้ว่าเกิดอะไรขึ้นและเพื่ออธิบายว่าฉันจะหันเหความสนใจไปทางคณิตศาสตร์ที่อยู่เบื้องหลังการบีบอัด JPEG เล็กน้อย
อัลกอริธึมการบีบอัด JPEG แบ่งภาพออกเป็นบล็อกขนาด 8 × 8 พิกเซล หนึ่งในบล็อกเหล่านี้แต่ละครั้งจะถูกยัดเยียดไปแล้วโคไซน์ไม่ต่อเนื่อง Transform (DCT) สัมประสิทธิ์ DCT ที่ได้นั้นอธิบายถึงบล็อกว่าเป็นผลรวมของคลื่นความถี่ที่แตกต่างกัน อัลกอริทึม "โยน" ข้อมูลบางอย่างในคลื่นความถี่สูงที่ตรงกับเสียงรบกวนและรายละเอียดที่น้อยมาก กระบวนการถอดรหัสจะกลับ DCT เพิ่มคลื่นที่จัดเก็บไว้ด้วยกันเพื่อกลับบล็อก
เป็นไปได้ที่จะหมุน "คลื่น" DCT โดยไม่ต้องยกเลิกและทำการแปลงซ้ำ (โดยทั่วไปคุณเปลี่ยนคลื่นแนวนอนทั้งหมดเป็นคลื่นแนวตั้งและในทางกลับกัน) สิ่งที่ฉันคิดว่าเกิดขึ้นใน WPV คือภาพถูกถอดรหัสหมุนแล้วเข้ารหัสใหม่ ในระหว่างกระบวนการเข้ารหัสอีกครั้งเนื่องจากขนาดของภาพของเราเป็น 8 เท่าในทั้งสองมิติแต่ละบล็อกใหม่จะสอดคล้องกับหนึ่งในบล็อกเดิม ที่สำคัญเนื่องจากแต่ละบล็อกไม่มีส่วนประกอบที่มีความถี่สูงอัลกอริทึมจึงไม่ทิ้งข้อมูลใด ๆ และค้นหาส่วนประกอบ DCT ที่ถูกต้องที่การหมุนแบบไม่สูญเสีย "ที่แท้จริง" จะมี
สุดท้ายนี้ฉันจะดูส่วนประกอบของไฟล์ JPEG อีกครั้ง ผลลัพธ์จะถูกเชื่อมโยงอีกครั้งในฐานะส่วนสำคัญ เปรียบเทียบทั้งสอง:
อิมเมจ WPV มีขนาดพิเศษ 4286 + 2 ไบต์ของข้อมูลเมตา Exif, 1 ไบต์พิเศษในความคิดเห็นและ 12,726 + 2 ไบต์ของข้อมูลเมตา XMP นี่คือเมตาดาต้าเพิ่มเติมทั้งหมด 17,017 ไบต์ ข้อมูลทั้งหมดที่ใช้มีไว้เพื่ออะไร? ฉันอ่านไฟล์ด้วยโปรแกรมแก้ไข hex ที่เชื่อถือได้และสำเนามาตรฐานที่เกี่ยวข้อง:
Exif เมตาดาต้าที่มีโครงสร้างเช่นรูปแบบ TIFF ซึ่งมีจำนวนของแท็ก (มีวิธีอื่น ๆ อีกมากมายซับซ้อน แต่ฉันจะมองข้ามไปได้) ไบต์ส่วนใหญ่ในส่วน Exif มีอยู่ในสองแท็กเหมือนกันที่มีหมายเลขแท็กEA1C
(59,932 ทศนิยม) หมายเลขแท็กนั้นไม่ได้บันทึกไว้ทุกที่ที่ฉันพบ แท็กทั้งสองมีประเภท "ไม่ได้กำหนด" 2060 ไบต์ซึ่งเป็นไบต์ว่างทั้งหมดยกเว้นหกตัวแรก ( 1C EA 00 00 00 08
) ฉันไม่รู้ว่าแท็กเหล่านี้คืออะไรทำไมมีสองแท็กและทำไมต้องเป็น 2 kB
ข้อมูลเมตา XMP เป็นเอกสาร XML แบบฝังทั้งหมดที่มีเนมสเปซและ UUID แบบยาวซึ่งเพิ่งมีสตริงรุ่น WPV (ที่มีอยู่แล้วในข้อมูลเมตาของ Exif) อย่างไรก็ตามบัญชีนั้นมีขนาดประมาณ 400 ไบต์เท่านั้น ส่วนที่เหลือของส่วนที่เป็น122 ซ้ำ 100 เว้นวรรคตามด้วยการขึ้นบรรทัดใหม่ นั่นคือพื้นที่ว่างมากกว่า 12,000 ไบต์
เช่นเดียวกับการทดสอบก่อนหน้านี้ GIMP และ WPV ใช้ตารางการควอนตัม DCT เดียวกัน ซึ่งหมายความว่าพวกเขาควรจะคำนวณค่าสัมประสิทธิ์ DCT ที่แน่นอนเหมือนกันซึ่งเป็นสาเหตุที่ภาพเหมือนกันทุกประการ ฉันไม่แน่ใจว่า WPV เพิ่งจะใช้ตาราง quantization เดียวกันหรือถ้ามันคัดลอกตารางจากอินพุต
แตกต่างจากการทดสอบก่อนหน้าเวลานี้ WPV ใช้การสุ่มตัวอย่าง 1 × 1 ดังนั้นจึงอาจตรวจพบว่านี่เป็นภาพสี
GIMP และ WPV ใช้ตาราง Huffman ที่แตกต่างกัน (ส่วนหนึ่งของขั้นตอนการเข้ารหัสเอนโทรปี) ตารางสำหรับ WPV มีขนาดใหญ่ขึ้นโดยรวม 279 ไบต์และในกรณีหนึ่งมี 7 ครั้งเป็นรหัสจำนวนมาก
เมื่อดูสถิติของ JPEGsnoop เราจะเห็นว่าบางรหัสเหล่านี้ไม่ค่อยได้ใช้ ตัวอย่างเช่นในID: 1, Class: AC
ตารางของรหัส 119 16 บิตที่กำหนดจะใช้เพียง 23 ตัวเท่านั้น โดยรวมส่วนการสแกนจริงจะใหญ่กว่า 28.5% ในรุ่น WPV
สรุป
ข้อมูลรุ่น:
ระบบปฏิบัติการ (Linux) ( uname -a
):
Linux unity 3.16.0-4-amd64 #1 SMP Debian 3.16.36-1+deb8u1 (2016-09-03) x86_64 GNU/Linux
ระบบปฏิบัติการ (Windows):
GIMP (Linux): 2.8.14 (จากแพ็คเกจgimp
, รุ่น2.8.14-1+deb8u1
)
Window Photo Viewer (ตามข้อมูลเมตาของรูปภาพ):
Microsoft Windows Photo Viewer 10.0.10586.0