smol-image-processor – ไมโครเซอร์วิสสำหรับทำให้เป็นมาตรฐานด้วย WebP หลังลบ EXIF/เมทาดาทา (Bun/Elysia)
(github.com/levish0)เมื่อแบ็กเอนด์รับการอัปโหลดรูปภาพจากผู้ใช้ มักมีปัญหาที่ติดมาด้วยแบบเงียบ ๆ
- ใน JPEG อาจมีพิกัด GPS, ชื่อรุ่นอุปกรณ์, เวลาที่ถ่าย เก็บอยู่ใน EXIF
- เมทาดาทาสีอย่าง ICC profile ก็อาจถูกเก็บและแจกจ่ายต่อไปทั้งอย่างนั้น
- ถ้ามีทั้ง JPEG, PNG, GIF, WebP ปะปนกันเข้ามา pipeline ของการจัดเก็บ/CDN/การเรนเดอร์จะซับซ้อนขึ้น
- แค่จัดการ EXIF orientation ผิด รูปก็อาจถูกบันทึกโดยหมุนไป 90°
smol-image-processor คือไมโครเซอร์วิสแบบหน้าที่เดียวที่จัดการปัญหาเหล่านี้แบบรวดเดียว
วิธีการทำงาน
เมื่ออัปโหลดรูปไปที่ POST /process ด้วย multipart/form-data จะได้ผลลัพธ์กลับมาเป็น WebP เสมอ
ใช้คุณสมบัติของพฤติกรรมการส่งออกเริ่มต้นของ Sharp ที่ทิ้งเมทาดาทาอย่าง source EXIF และ ICC profile ไปโดยตรง แต่สำหรับ EXIF orientation จะใช้ .rotate() กับพิกเซลก่อนลบเมทาดาทา เพื่อคงทิศทางของภาพไว้
ชั้นการป้องกันมีสองอย่าง
- จำกัดจำนวนพิกเซล (MAX_PIXELS): แม้ขนาดไฟล์จะเล็ก แต่ถ้าถอดรหัสแล้วขยายเป็นภาพระดับหลายร้อยล้านพิกเซล ก็จะถูกบล็อกด้วย
limitInputPixelsของ Sharp เพื่อป้องกันภาพแบบ decompression bomb - จำกัดจำนวนเฟรม (MAX_PAGES): ป้องกัน DoS ที่ทำให้หน่วยความจำและ CPU หมดจาก GIF/WebP แบบแอนิเมชันที่มีหลายร้อยถึงหลายพันเฟรม
GIF/WebP แบบแอนิเมชันจะถูกแปลงเป็น animated WebP โดยคงค่า frame delay และจำนวนรอบการลูปไว้
ส่วน alpha channel ของ PNG ก็ยังคงอยู่เหมือนเดิม
ใน response header จะมี width, height, size, สถานะว่าเป็น animated หรือไม่, และจำนวนหน้า ของภาพที่ประมวลผลแล้ว ทำให้สามารถบันทึกลง DB ได้ทันทีโดยไม่ต้องมีขั้นตอนดึงเมทาดาทาแยกต่างหาก
สแตก
- Runtime: Bun, HTTP framework: Elysia
- การประมวลผลภาพ: Sharp (wrapper ของ libvips)
- มี Docker image ให้ใช้งาน (GHCR)
เริ่มต้นอย่างรวดเร็ว
docker run --rm -p 6701:6701 ghcr.io/levish0/smol-image-processor
curl -F file=@photo.jpg http://localhost:6701/process -o clean.webp
ยังไม่มีความคิดเห็น