Rapier JXL: انکودر JPEG XL با جاوااسکریپت خالص
خلاصهٔ کاملتر
Rapier JXL یه انکودر برای فرمت تصویری JPEG XL هست که با جاوااسکریپت خالص نوشته شده. تو مرورگر، Web Worker، Node و Deno کار میکنه، لایسنسش MIT هست و هیچ وابستگیای نداره. نسخهٔ فشردهشدهش ۲۹ کیلوبایته، در حالی که libjxl (انکودر رسمی JPEG XL) وقتی به WebAssembly کامپایل بشه حدود ۹۶۲ کیلوبایت حجم داره.
ادعای اصلی پروژه اینه که با کیفیت دیداری یکسان، فایل کوچیکتری میسازه. کیفیت با معیار SSIMULACRA2 سنجیده شده، یعنی یه عدد که نشون میده عکس فشردهشده به چشم آدم چقدر شبیه اصلشه. روی ۲۴ عکس مجموعهٔ Kodak، خروجیها ۵ تا ۷ درصد از cjxl -e 9 کوچیکتر، ۴ تا ۲۰ درصد از AVIF، ۱۵ تا ۲۳ درصد از WebP و ۱۹ تا ۴۳ درصد از JPEG (mozjpeg) کوچیکتر بودن. تبدیل JPEG به JPEG XL هم ۱۵ درصد صرفهجویی داشته و هر ۲۴ فایل بایت به بایت قابل برگردوندن بودن.
یه قابلیت جالبش جستوجوی کیفیت هست: بهجای اینکه عدد کیفیت رو حدسی بدی، یه امتیاز هدف میدی و کتابخونه کوچیکترین فایلی رو برمیگردونه که به اون امتیاز میرسه. این جستوجو میتونه روی WebGPU اجرا بشه، و اگه GPUDevice ندی، روی CPU انجام میشه:
import {encodeToScore} from 'rapier-jxl/score';
const {bytes} = await encodeToScore(rgba, width, height, {target: {ssimulacra2: 80}, gpu: device});اگه کیفیت ثابت بخوای، encode با گزینهٔ quality هست که مقدار ۱۰۰ یعنی بدون افت (lossless). تابع encodeAsync هم همون فایل رو میسازه ولی اگه صفحه WebGPU داشته باشه از کارت گرافیک استفاده میکنه. سازنده میگه یه عکس ۱۲ مگاپیکسلی گوشی اینطوری حدود ۲.۱ ثانیه طول میکشه، در حالی که بدون GPU حدود ۶.۷ ثانیهست (میانهٔ ۲۴ عکس روی NVIDIA T4).
برای تبدیل یه فایل تو صفحهٔ وب، کافیه فایل worker رو کنار صفحه بذاری و تابع toJXL رو صدا بزنی تا یه Blob از نوع image/jxl بگیری. پکیج به چند بیلد جدا تقسیم شده تا فقط چیزی که لازم داری رو بار کنی: مثلاً هستهٔ اصلی حدود ۲۹ کیلوبایته، worker بدون انیمیشن حدود ۱۵۰ کیلوبایت و worker کامل با انیمیشن حدود ۲۱۴ کیلوبایت.
نکات کلیدی:
- انکودر JPEG XL با جاوااسکریپت خالص، لایسنس MIT و بدون وابستگی
- حجم هسته ۲۹ کیلوبایت gzip، در برابر ۹۶۲ کیلوبایت برای libjxl در WebAssembly
- با کیفیت SSIMULACRA2 یکسان، ۵ تا ۷ درصد کوچیکتر از cjxl -e 9 و ۱۵ تا ۲۳ درصد کوچیکتر از WebP
- تابع encodeToScore کوچیکترین فایلی که به امتیاز هدف برسه رو برمیگردونه و میتونه روی WebGPU اجرا بشه
- انکود عکس ۱۲ مگاپیکسلی با WebGPU حدود ۲.۱ ثانیه، بدون اون حدود ۶.۷ ثانیه
- تبدیل JPEG به JPEG XL حدود ۱۵ درصد کوچیکتر و کاملاً برگشتپذیره




