JPEG
ตัวที่หลุดเยอะสุดไฟล์ JPEG เก็บเมทาดาต้าไว้ในเซกเมนต์ APPn ระหว่างส่วนหัวของไฟล์กับข้อมูลภาพ นี่คือสิ่งที่อยู่ในแต่ละส่วน และสิ่งที่ PicScrub ทำกับมัน
อะไรบ้างที่ถูกลบ
- EXIF พิกัด GPS, ยี่ห้อและรุ่นกล้อง, วันเวลา, ค่าการเปิดรับแสง
- XMP ประวัติการแก้ไข, ซอฟต์แวร์ที่ใช้, การให้ดาว
- IPTC / Photoshop คำบรรยาย, เครดิต, คำสำคัญ
- คอมเมนต์และภาพขนาดย่อที่ฝังอยู่ สำเนาจิ๋วของภาพต้นฉบับที่อาจรอดจากการครอปและการแต่งรูปของคุณมาได้
อะไรบ้างที่เก็บไว้ได้
- ข้อมูลภาพ ไม่ถูกแตะเลย ไม่มีการเข้ารหัสใหม่
- โปรไฟล์สี ICC เลือกได้ เพื่อให้สียังตรงเหมือนเดิม
- การหมุนภาพ เลือกได้ เพื่อให้ภาพแนวตั้งไม่ล้ม
- ประกาศลิขสิทธิ์ เลือกได้ สำหรับช่างภาพที่อยากได้เครดิตโดยไม่ต้องแถมพิกัด
ภาพรวมโครงสร้างไฟล์
ถ้าคุณเคยเปิดไฟล์ JPEG ด้วย hex editor คุณจะเห็นว่ามันประกอบขึ้นจาก เซกเมนต์ที่คั่นด้วยมาร์กเกอร์ มาร์กเกอร์ทุกตัวขึ้นต้นด้วย 0xFF ตามด้วยไบต์ที่บอกว่าเซกเมนต์นั้นเป็นชนิดไหน การออกแบบแบบนี้ทำให้อ่าน JPEG ได้ค่อนข้างง่าย แค่ไล่หาไบต์ FF แล้วดูว่าตามหลังมาด้วยอะไร
ส่วนที่น่าสนใจในแง่ความเป็นส่วนตัวคือ เมทาดาต้าทั้งหมด (EXIF, GPS, วันเวลา) อยู่ในเซกเมนต์พวกนี้ แยกออกจากข้อมูลภาพจริงโดยสิ้นเชิง เราจึงลบเมทาดาต้าได้โดยไม่ต้องแตะพิกเซลหรือบีบอัดอะไรใหม่เลย
โครงสร้างไฟล์ JPEG
ตัวอย่างส่วนหัวของไฟล์ JPEG
| Offset | Hex | ASCII | |||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0000 | FFD8FFE000104A464946000101000048 | ......JFIF.....H | |||||||||||||||
| 0010 | 00480000FFE112344578696600000000 | .H.....4Exif.. | |||||||||||||||
โครงสร้างของมาร์กเกอร์
FF xx:มาร์กเกอร์ (xx บอกชนิด)LL LL:ความยาว (2 ไบต์ แบบ big-endian นับรวมตัวเองด้วย)Data...:ข้อมูลของเซกเมนต์ (ความยาว - 2 ไบต์)
รายการมาร์กเกอร์ JPEG ทั้งหมด
| มาร์กเกอร์ | ชื่อ | คำอธิบาย |
|---|---|---|
| FF D8 | SOI | จุดเริ่มต้นของภาพ |
| FF D9 | EOI | จุดสิ้นสุดของภาพ |
| FF C0 | SOF0 | จุดเริ่มต้นของเฟรม (Baseline DCT) |
| FF C2 | SOF2 | จุดเริ่มต้นของเฟรม (Progressive DCT) |
| FF C4 | DHT | กำหนดตาราง Huffman |
| FF DB | DQT | กำหนดตารางควอนไทซ์ |
| FF DD | DRI | กำหนดช่วง restart |
| FF DA | SOS | จุดเริ่มต้นของการสแกน (ข้อมูลภาพตามหลังมา) |
| FF FE | COM | คอมเมนต์ (เมทาดาต้า) |
| FF E0 | APP0 | มาร์กเกอร์ JFIF |
| FF E1 | APP1 | มาร์กเกอร์ EXIF / XMP |
| FF E2 | APP2 | โปรไฟล์ ICC / MPF |
| FF ED | APP13 | IPTC / Photoshop |
| FF EE | APP14 | การแปลงสีของ Adobe |
สีทอง = เมทาดาต้า (ถูกลบ), สีปกติ = โครงสร้างที่คงไว้
JFIF กับ EXIF ต่างกันอย่างไร
มีเรื่องหนึ่งที่ทำให้หลายคนสับสน คือไฟล์ JPEG มักมีมาตรฐานเมทาดาต้าสองแบบ อยู่พร้อมกัน JFIF มาก่อนและดูแลเรื่องพื้นฐานอย่างความละเอียด ต่อมากล้องเริ่มใส่ข้อมูล EXIF ที่บอกรายละเอียดการถ่ายแบบครบถ้วน JPEG ยุคใหม่ส่วนใหญ่จึงมีทั้งคู่ นั่นคือเหตุผลที่คุณจะเห็นทั้งมาร์กเกอร์ APP0 และ APP1 อยู่ใกล้ๆ ต้นไฟล์
APP0:JFIF
JPEG File Interchange Format ข้อมูลพื้นฐานของภาพ
- • หมายเลขเวอร์ชัน
- • ความหนาแน่นของพิกเซล (DPI)
- • อัตราส่วนภาพ
- • ภาพขนาดย่อ (ถ้ามี)
APP1:EXIF
Exchangeable Image File Format เมทาดาต้าจากกล้อง
- • ยี่ห้อและรุ่นกล้อง
- • พิกัด GPS
- • วันเวลา
- • ค่าการเปิดรับแสง
เจาะลึกมาร์กเกอร์ APP
สเปกของ JPEG กันมาร์กเกอร์ "แอปพลิเคชัน" ไว้ 16 ตัว (APP0 ถึง APP15) ให้ผู้ผลิตแต่ละรายเอาไปใช้ได้ตามใจ ผ่านไปหลายปี องค์กรต่างๆ ก็จับจองมาร์กเกอร์คนละตัวไว้เก็บเมทาดาต้าในรูปแบบของตัวเอง ผลลัพธ์เลยค่อนข้างยุ่งเหยิง แต่อย่างน้อยก็เป็นความยุ่งเหยิงที่มีเอกสารกำกับดี
จุดที่ยุ่งยากคือมาร์กเกอร์ตัวเดียวกันอาจหมายถึงคนละอย่างขึ้นอยู่กับเนื้อหาข้างใน อย่าง APP1 เป็นได้ทั้งข้อมูล EXIF และ XMP คุณจึงต้องดูสตริงตัวระบุที่อยู่ข้างในด้วยว่ากำลังเจอกับอะไรอยู่
APP0 (0xFFE0):JFIF
ตัวระบุ: JFIF\0 เก็บเวอร์ชัน หน่วยความหนาแน่น ความหนาแน่นแกน X/Y และภาพขนาดย่อที่ฝังไว้ (ถ้ามี) โดยทั่วไปเก็บไว้ได้อย่างปลอดภัย
APP1 (0xFFE1):EXIF
ตัวระบุ: Exif\0\0 ข้างในเป็นโครงสร้าง TIFF เต็มรูปแบบ พร้อมรายการ IFD ที่เก็บข้อมูลกล้อง ข้อมูล GPS วันเวลา ภาพขนาดย่อ และ maker notes จุดเสี่ยงหลักด้านความเป็นส่วนตัว
APP1 (0xFFE1):XMP
ตัวระบุ: http://ns.adobe.com/xap/1.0/\0 มาตรฐานเมทาดาต้า บนพื้นฐาน XML ของ Adobe เก็บได้ทั้งประวัติการแก้ไข ข้อมูลซอฟต์แวร์ และข้อมูล EXIF เพิ่มเติม
namespace ของ XMP
xmp: http://ns.adobe.com/xap/1.0/xmpMM: http://ns.adobe.com/xap/1.0/mm/dc: http://purl.org/dc/elements/1.1/photoshop: http://ns.adobe.com/photoshop/1.0/tiff: http://ns.adobe.com/tiff/1.0/exif: http://ns.adobe.com/exif/1.0/APP1 (0xFFE1):Extended XMP
ตัวระบุ: http://ns.adobe.com/xmp/extension/\0 สำหรับข้อมูล XMP ที่เกิน 65KB จะถูกแบ่งไปเก็บในหลายเซกเมนต์ APP1
APP2 (0xFFE2):MPF
ตัวระบุ: MPF\0 Multi-Picture Format สำหรับภาพสามมิติและภาพพาโนรามา
APP2 (0xFFE2):โปรไฟล์ ICC
ตัวระบุ: ICC_PROFILE\0 ข้อมูลการจัดการสี แบ่งเก็บข้ามมาร์กเกอร์ APP2 หลายตัวได้ โดยทั่วไปเก็บไว้ได้อย่างปลอดภัย
APP13 (0xFFED):IPTC/Photoshop
ตัวระบุ: Photoshop 3.0\0 เก็บข้อมูล IPTC-IIM ทั้งคำบรรยาย คำสำคัญ ลิขสิทธิ์ และข้อมูลผู้สร้าง อาจมีข้อมูลของผู้เขียนอยู่ด้วย
APP14 (0xFFEE):Adobe
ตัวระบุ: Adobe\0 เก็บแฟล็กการแปลงสี (RGB/CMYK) สำคัญต่อการแสดงสีให้ถูกต้อง
โครงสร้างของ EXIF
ตรงนี้แหละที่เริ่มน่าสนใจ (และแปลกนิดๆ) เพราะจริงๆ แล้วข้อมูล EXIF ก็คือไฟล์ TIFF จิ๋วๆ ที่ฝังอยู่ในไฟล์ JPEG ของคุณ ใช่แล้ว จริงๆ นะ มันมีส่วนหัวของตัวเอง มีลำดับไบต์ของตัวเอง และใช้โครงสร้าง IFD (Image File Directory) ของ TIFF ในการเก็บแท็ก
สิ่งแรกที่คุณจะเห็นถัดจากตัวระบุ "Exif" คือส่วนหัวของ TIFF ที่บอกว่าข้อมูลเป็นแบบ little-endian (Intel, "II") หรือ big-endian (Motorola, "MM") ถ้าอ่านผิดตรงนี้ ตัวเลขทั้งหมดจะเพี้ยนหมด มันจึงเป็นสิ่งแรกที่ตัวอ่านทุกตัวต้องเช็ก
ส่วนหัวของ TIFF (8 ไบต์)
| Offset | Hex | ASCII | |||||||
|---|---|---|---|---|---|---|---|---|---|
| 0000 | 49492A0008000000 | II*..... | |||||||
II = Intel (little-endian), MM = Motorola (big-endian)
โครงสร้างของรายการ IFD (12 ไบต์)
รายการ IFD ที่สำคัญ
0x010F:Make0x0110:Model0x0132:DateTime0x8769:ExifIFDPointer0x8825:GPSInfoIFDPointer0x927C:MakerNotePicScrub จัดการไฟล์ JPEG อย่างไร
วิธีการค่อนข้างตรงไปตรงมา เราไล่อ่านไฟล์ทีละมาร์กเกอร์ เก็บตัวที่จำเป็นต่อการแสดงภาพไว้ แล้วข้ามตัวที่เป็นเมทาดาต้าไป เพราะเราไม่เคยแตะข้อมูลภาพที่ถูกบีบอัดไว้เลย คุณภาพจึงไม่ลดลงแม้แต่นิดเดียว
กุญแจสำคัญคือโครงสร้างแบบมาร์กเกอร์ของ JPEG ทำให้เรื่องนี้ง่ายมาก เราไม่จำเป็นต้องเข้าใจค่าสัมประสิทธิ์ DCT หรือตาราง Huffman เลย แค่ต้องแยกให้ออกว่าเซกเมนต์ไหนเป็นเมทาดาต้าและเซกเมนต์ไหนไม่ใช่
ตรวจสอบส่วนหัว
ยืนยันว่ามีมาร์กเกอร์ SOI (FF D8) อยู่ต้นไฟล์
อ่านมาร์กเกอร์
ไล่อ่านมาร์กเกอร์ทีละตัวตามลำดับ ดึงชนิดและความยาวออกมา
ระบุว่าอันไหนเป็นเมทาดาต้า
ตรวจตัวระบุในเซกเมนต์ APP (EXIF, XMP, IPTC ฯลฯ)
คัดลอกเฉพาะที่ต้องการ
คัดลอกเซกเมนต์ที่ไม่ใช่เมทาดาต้าไปยังไฟล์ผลลัพธ์ แล้วข้ามเซกเมนต์เมทาดาต้า
อะไรบ้างที่เก็บไว้
- • มาร์กเกอร์ SOI/EOI (จำเป็น)
- • DQT (ตารางควอนไทซ์)
- • SOF (ส่วนหัวของเฟรม)
- • DHT (ตาราง Huffman)
- • SOS และข้อมูลสแกน (ตัวภาพจริง)
- • เลือกได้: โปรไฟล์สี ICC (ตั้งค่าได้)
อะไรบ้างที่ถูกลบ
- • APP1 EXIF (กล้อง, GPS, วันเวลา)
- • APP1 XMP (เมทาดาต้าการแก้ไข)
- • APP13 IPTC (คำบรรยาย, ผู้สร้าง)
- • มาร์กเกอร์ COM (คอมเมนต์)
- • ภาพขนาดย่อใน EXIF
รายการแท็ก EXIF
แท็ก EXIF ไม่ได้อันตรายเท่ากันหมดในแง่ความเป็นส่วนตัว บางตัวอย่างค่าการเปิดรับแสงก็ค่อนข้างไม่มีพิษภัย แต่บางตัวอย่างหมายเลขเครื่องและชื่อเจ้าของ ระบุตัวคุณหรืออุปกรณ์ของคุณได้เลย นี่คือกลุ่มที่เรามองว่าเสี่ยงสูง
| Tag ID | ชื่อ | ความเสี่ยง |
|---|---|---|
| 0x9003 | DateTimeOriginal | สูง |
| 0x9004 | DateTimeDigitized | สูง |
| 0x9010 | OffsetTime | ปานกลาง |
| 0x9286 | UserComment | สูง |
| 0x927C | MakerNote | สูง |
| 0xA420 | ImageUniqueID | สูง |
| 0xA430 | CameraOwnerName | สูง |
| 0xA431 | BodySerialNumber | สูง |
| 0xA434 | LensModel | ปานกลาง |
| 0xA435 | LensSerialNumber | สูง |
| 0xFDE8 | OwnerName | สูง |
| 0xFDE9 | SerialNumber | สูง |
ดูแท็กการตั้งค่ากล้องทั้งหมด (ไม่ระบุตัวตน)
0x829A ExposureTime0x829D FNumber0x8822 ExposureProgram0x8827 ISOSpeedRatings0x9201 ShutterSpeedValue0x9202 ApertureValue0x9203 BrightnessValue0x9204 ExposureBiasValue0x9207 MeteringMode0x9208 LightSource0x9209 Flash0x920A FocalLength0xA001 ColorSpace0xA002 PixelXDimension0xA003 PixelYDimension0xA402 ExposureMode0xA403 WhiteBalance0xA405 FocalLengthIn35mmFilm0xA406 SceneCaptureTypeรายการแท็ก GPS
ข้อมูล GPS อยู่ใน sub-IFD ของตัวเอง โดยมีแท็ก 0x8825ใน IFD หลักชี้ไปหา ถ้ามีตัวชี้นี้อยู่ ก็แปลว่ารูปของคุณมีข้อมูลตำแหน่งติดมาด้วย สมาร์ตโฟนยุคใหม่ขยันฝังข้อมูลนี้เป็นพิเศษ และมักละเอียดพอที่จะระบุได้เลยว่าคุณยืนอยู่ตรงไหน
| Tag ID | ชื่อ | คำอธิบาย |
|---|---|---|
| 0x0000 | GPSVersionID | เวอร์ชันของแท็ก GPS |
| 0x0001 | GPSLatitudeRef | N หรือ S |
| 0x0002 | GPSLatitude | องศา ลิปดา ฟิลิปดา |
| 0x0003 | GPSLongitudeRef | E หรือ W |
| 0x0004 | GPSLongitude | องศา ลิปดา ฟิลิปดา |
| 0x0005 | GPSAltitudeRef | เหนือหรือใต้ระดับน้ำทะเล |
| 0x0006 | GPSAltitude | เมตร |
| 0x0007 | GPSTimeStamp | เวลา UTC |
| 0x001D | GPSDateStamp | วันที่ UTC |
| 0x0012 | GPSMapDatum | ข้อมูลหมุดอ้างอิงทางภูมิศาสตร์ |
| 0x001B | GPSProcessingMethod | GPS/CELLID/WLAN/MANUAL |
| 0x001C | GPSAreaInformation | ชื่อสถานที่ |
รายการแท็ก IPTC
IPTC ถูกออกแบบมาให้สำนักข่าวฝังคำบรรยาย เครดิต และข้อมูลลิขสิทธิ์ลงในรูป มันถูกเก็บไว้ใน APP13 พร้อมตัวระบุ "Photoshop 3.0" (ใช่แล้ว Adobe รับมาตรฐานนี้มาใช้) ถ้าคุณเคยใส่ข้อมูลลิขสิทธิ์ หรือคำสำคัญใน Lightroom หรือ Photoshop มันก็ไปจบลงตรงนี้แหละ
0x0250 By-line (ผู้สร้าง)0x0255 By-line Title (ตำแหน่งผู้สร้าง)0x025A City (เมือง)0x025C Sub-location (สถานที่ย่อย)0x025F Province/State (จังหวัดหรือรัฐ)0x0265 Country Name (ชื่อประเทศ)0x0274 Copyright Notice (ประกาศลิขสิทธิ์)0x0276 Contact (ผู้ติดต่อ)0x0237 Date Created (วันที่สร้าง)0x023C Time Created (เวลาที่สร้าง)0x0278 Caption/Abstract (คำบรรยาย)0x0219 Keywords (คำสำคัญ)