
JPG چگونه کار می کند
به گزارش اپست به نقل از freecodecamp ، فرمت فایل JPG یکی از پیشرفتهای چشمگیر در زمینه فشردهسازی تصویر بود که در سال ۱۹۹۲ معرفی شد. از آن زمان تاکنون، این فرمت به عنوان نیروی غالب در نمایش تصاویر با کیفیت عکس در اینترنت شناخته شده است. و برای این کار دلیل خوبی دارد. بسیاری از تکنولوژیهای پشت پرده نحوه عملکرد JPG بسیار پیچیده هستند و نیازمند درک عمیقی از نحوه تطبیق چشم انسان با ادراک رنگها و لبهها هستند.
و از آنجایی که من به این نوع چیزها علاقهمندم (و شما هم هستید، اگر این را میخوانید)، میخواستم نحوه رمزگذاری JPG را تجزیه کنم تا بهتر بتوانیم نحوه ساخت فایلهای JPG کوچکتر را درک کنیم.
خلاصه
طرح فشردهسازی JPG به چندین مرحله تقسیم میشود. تصویر زیر آنها را در سطح بالایی توصیف میکند و ما در ادامه هر مرحله را بررسی خواهیم کرد.

تبدیل فضای رنگ
یکی از اصول کلیدی فشرده سازی داده های با اتلاف کیفیت این است که حسگرهای انسانی به اندازه سیستم های محاسباتی دقیق نیستند. از نظر علمی، چشم انسان فقط توانایی فیزیکی تشخیص حدود 10 میلیون رنگ مختلف را دارد. با این حال، عوامل زیادی وجود دارد که می تواند نحوه درک رنگ توسط چشم انسان را تحت تاثیر قرار دهد؛ این موضوع به خوبی با توهمات رنگی یا همان لباس معروفی که اینترنت را شکست، نشان داده می شود. نکته اصلی این است که چشم انسان را می توان به خوبی با توجه به رنگ هایی که درک می کند، دستکاری کرد.
کوانتیزاسیون نوعی از این اثر در فشرده سازی تصویر با اتلاف کیفیت است، اما JPEG رویکرد متفاوتی در این زمینه دارد: مدل های رنگ. فضای رنگ یک سازمان خاص از رنگ ها است و مدل رنگ آن فرمول ریاضی را برای نحوه نمایش آن رنگ ها نشان می دهد (مثلاً سه تایی در RGB یا چهار تایی در CMYK).
قدرت این فرآیند در این است که می توانید از یک مدل رنگ به مدل دیگر تبدیل شوید، به این معنی که می توانید نمایش ریاضی یک رنگ معین را با مجموعه ای کاملاً متفاوت از مقادیر عددی تغییر دهید.
به عنوان مثال، در زیر یک رنگ خاص و نمایش آن در مدل های رنگ RGB و CMYK آورده شده است، آنها برای چشم انسان یک رنگ هستند، اما می توانند با مجموعه ای متفاوت از مقادیر عددی نشان داده شوند.

کاهش نمونهبرداری (Downsampling)
یکی از نتایج جالب فضای رنگ YCbCr این است که کانالهای Cb/Cr جزئیات دقیقتری ندارند؛ آنها اطلاعات کمتری نسبت به کانال Y دارند.
در نتیجه، الگوریتم JPEG اندازه کانالهای Cb و Cr را به حدود یک چهارم اندازه اصلی آنها کاهش میدهد (توجه داشته باشید که برخی از جزئیات در نحوه انجام این کار وجود دارد که در اینجا پوشش داده نشده است)، که به آن کاهش نمونهبرداری میگویند.
نکته مهم اینجاست که کاهش نمونهبرداری یک فرآیند فشردهسازی با افت کیفیت است (شما نمیتوانید رنگهای دقیق منبع را بازیابی کنید، بلکه فقط یک تقریب نزدیک به آن را بازیابی خواهید کرد)، اما تأثیر کلی آن بر اجزای بصری قشر بینایی انسان حداقل است. لومینانس (Y) جایی است که چیزهای جالب در آن قرار دارد و از آنجایی که ما فقط کانالهای CbCr را کاهش نمونهبرداری میکنیم، تأثیر آن بر سیستم بینایی کم است.

تصویر به بلوکهای ۸ در ۸ پیکسل تقسیم میشود
از این لحظه به بعد، JPG تمامی عملیات را روی بلوکهای ۸ در ۸ پیکسل انجام میدهد. دلیل این کار این است که ما انتظار داریم که در بلوکهای ۸ در ۸ تغییرات زیادی وجود نداشته باشد، حتی در عکسهای بسیار پیچیده، تمایل به وجود شباهت در مناطق محلی وجود دارد؛ این شباهت چیزی است که ما در طول فشردهسازی از آن بهره خواهیم برد.
شایان ذکر است که در این مرحله، ما یکی از اولین “آثار مصنوعی” معمول کدگذاری JPG را معرفی میکنیم. “خونریزی رنگ” جایی است که رنگها در امتداد لبههای تیز میتوانند به سمت دیگر “خونریزی” کنند. دلیل این امر این است که کانالهای کرومینانس که رنگ پیکسلها را بیان میکنند، هر بلوک ۴ پیکسل را به یک رنگ واحد میانگینگیری کردهاند و برخی از این بلوکها از لبه تیز عبور میکنند.
تبدیل کسینوسی گسسته (DCT)
تا به این نقطه، همه چیز بسیار ساده بوده است. فضاهای رنگ، نمونهبرداری پایین و بلوکبندی در دنیای فشردهسازی تصویر، کارهای سادهای هستند. اما اکنون… اکنون ریاضیات واقعی ظاهر میشود.
مولفه اصلی تبدیل DCT این است که فرض میکند هر سیگنال عددی را میتوان با استفاده از ترکیبی از توابع کسینوسی بازسازی کرد.
برای مثال، اگر نمودار زیر را داشته باشیم:

میتوانید ببینید که این در واقع مجموع cos(x) + cos(2x) + cos(4x) است.



ماتریس G نشان دهنده وزن پایه هایی است که برای بازسازی تصویر استفاده می شود (مقدار اعشاری کوچک در سمت راست پایین انیمیشن بالا). به طور خلاصه، برای هر پایه، آن را در وزن موجود در این ماتریس ضرب می کنیم، کل آنها را با هم جمع می کنیم و تصویر نهایی خود را به دست می آوریم.
در این مرحله، ما دیگر در فضاهای رنگی کار نمی کنیم، بلکه مستقیماً با ماتریس G (وزن های پایه) کار می کنیم، تمام فشرده سازی های بعدی مستقیماً روی این ماتریس انجام می شود.
اما مشکل اینجا این است که ما اکنون مقادیر صحیح بایت تراز را به اعداد حقیقی تبدیل کرده ایم. که به طور موثر اطلاعات ما را باد می کند (از 1 بایت به 1 شناور (4 بایت) حرکت می کند). برای حل این مشکل و شروع تولید فشرده سازی قابل توجه تر، به مرحله کوانتیزاسیون می رویم.
بنابراین، ما نمی خواهیم داده های نقطه شناور را فشرده کنیم. این باعث باد کردن جریان ما می شود و موثر نیست. برای این منظور، ما می خواهیم راهی برای تبدیل ماتریس وزن ها به مقادیر در فضای [0، 255] پیدا کنیم. به طور مستقیم، می توانیم این کار را با پیدا کردن حداقل/حداکثر مقدار برای ماتریس (-415.38 و 77.13، به ترتیب) و تقسیم هر عدد در این محدوده برای به دست آوردن مقداری بین [0،1] انجام دهیم که در آن ضرب می کنیم. 255 برای به دست آوردن مقدار نهایی ما.
For example : [34.12- -415.38] / [77.13 — -415.38] *255= 232
این کار میکند، اما در ازای آن دقت به میزان قابل توجهی کاهش مییابد. این مقیاسبندی توزیع نابرابری از مقادیر را ایجاد میکند که نتیجه آن از دست رفتن قابل توجه کیفیت بصری تصویر است.
در عوض، JPG رویکرد متفاوتی را اتخاذ میکند. به جای استفاده از محدوده مقادیر در ماتریس به عنوان مقدار مقیاسبندی، از یک ماتریس از پیش محاسبهشده از عوامل کمیسازی استفاده میکند. این عوامل کمیسازی (QF) نیازی به بخشی از جریان داده نیستند، بلکه میتوانند بخشی از خود کدک باشند.
این مثال یک ماتریس رایج از عوامل کمیسازی را نشان میدهد، یکی برای هر تصویر پایه.

به عنوان مثال، با استفاده از مقادیر G[0,0]=−415.37 و Q[0,0]=16:
![]()
که در نهایت ماتریس زیر حاصل میشود:

مشاهده کنید که ماتریس چقدر سادهتر شده است – اکنون حاوی تعداد زیادی ورودی کوچک یا صفر است، که فشردهسازی آن را بسیار آسانتر میکند.
به عنوان یک نکتهی سریع، این فرآیند را به طور مستقل روی کانالهای Y، CbCr اعمال میکنیم و به همین دلیل به دو ماتریس مختلف نیاز داریم: یکی برای Y و دیگری برای کانالهای C:


کوانتیزاسیون به دو روش اصلی باعث فشرده سازی تصویر می شود: اول، محدود کردن دامنه موثر وزن ها، که تعداد بیت های مورد نیاز برای نمایش آنها را کاهش می دهد. دوم، بسیاری از وزن ها یکسان یا صفر می شوند که باعث بهبود فشرده سازی در مرحله سوم، کدگذاری انتروپی، می شود.
بنابراین، کوانتیزاسیون منبع اصلی مصنوعات JPEG است. از آنجایی که تصاویر در گوشه پایین سمت راست تمایل دارند بزرگترین مقسوم علیه های کوانتیزاسیون را داشته باشند، مصنوعات JPEG تمایل دارند شبیه ترکیبی از این تصاویر باشند. ماتریس ضرایب کوانتیزاسیون را می توان با تغییر “سطح کیفیت” JPEG که مقادیر آن را بالا یا پایین می کند، مستقیماً کنترل کرد (ما این موضوع را در یک دقیقه بررسی خواهیم کرد).
فشرده سازی:
در این مرحله، ما به دنیای مقادیر صحیح بازگشته ایم و می توانیم مرحله فشرده سازی بدون از دست دادن اطلاعات را روی بلوک های خود اعمال کنیم. با این حال، هنگام نگاه کردن به داده های تبدیل شده، باید متوجه چیزی جالب شوید:

همانطور که از گوشه بالا سمت چپ به گوشه پایین سمت راست حرکت میکنید، فرکانس صفرها افزایش مییابد. این به نظر میرسد یک گزینه اصلی برای رمزگذاری طول اجرا (Run Length Encoding) باشد. اما ترتیب سطر-اولویت و ستون-اولویت در اینجا ایدهآل نیستند، زیرا این کار باعث درهمآمیزی این رشتههای صفر میشود، در عوض آنها را همه با هم بستهبندی میکند.
در عوض، ما از گوشه بالا سمت چپ شروع میکنیم و به صورت زیگزاگ در یک الگوی مورب در سراسر ماتریس حرکت میکنیم، تا زمانی که به گوشه پایین سمت راست برسیم، به عقب و جلو میرویم.

نتیجه ماتریس لومای ما، به ترتیب زیر میشود:
−26,−3,0,−3,−2,−6,2,−4,1,−3,1,1,5,1,2,−1,1,−1,2,0,0,0,0,0,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
پس از آنکه دادهها به این فرمت تبدیل شدند، مراحل بعدی ساده است: اجرای RLE بر روی دنباله و سپس اعمال یک کدگذار آماری (مانند هافمن، حسابشناسی یا ANS) بر روی نتایج.
بلاک شما حالا با کدک JPG رمزگذاری شده است.
درک پارامتر کیفیت
حالا که فهمیدید فایلهای JPG چطور ساخته میشوند، ارزشش را دارد که مفهوم پارامتر کیفیت را دوباره بررسی کنید که معمولا موقع خروجی گرفتن تصاویر JPG از فتوشاپ (یا هر نرمافزار دیگری) میبینید.
این پارامتر که ما آن را q می نامیم، یک عدد صحیح بین 1 تا 100 است. شما باید q را به عنوان معیاری برای کیفیت تصویر در نظر بگیرید: مقادیر بالاتر q مربوط به تصاویر با کیفیت بالاتر و اندازه فایل بزرگتر است.
این مقدار کیفیت در طول فاز کوانتیزاسیون استفاده می شود تا عوامل کوانتیزاسیون را به طور مناسب مقیاس بندی کند. به طوری که به ازای هر وزن پایه، گام کوانتیزاسیون اکنون شبیه به round(Gi,k / alpha*Qi,k) است.
که نماد آلفا در نتیجه پارامتر کیفیت ایجاد می شود.
![]()
هنگامی که مقدار آلفا یا Q[x,y] افزایش یابد (به یاد داشته باشید که مقادیر بزرگ آلفا با مقادیر کوچک پارامتر کیفیت q مطابقت دارد)، اطلاعات بیشتری از دست میرود و اندازه فایل کاهش مییابد.
به همین ترتیب، اگر میخواهید فایل کوچکتری داشته باشید، با هزینهٔ ایجاد مصنوعات بصری بیشتر، میتوانید در مرحلهٔ خروجی، مقدار کیفیت پایینتری را تنظیم کنید.

همانطور که در تصویر با کمترین کیفیت مشاهده میکنید، نشانههای واضحی از مراحل بلوکبندی و کوانتیزاسیون دیده میشود.
احتمالاً مهمترین نکته این است که پارامتر کیفیت بسته به تصویر متفاوت است. از آنجایی که هر تصویر منحصر به فرد است و انواع مختلفی از مصنوعات بصری را ارائه میدهد، مقدار Q نیز منحصر به فرد خواهد بود.
نتیجهگیری
هنگامی که نحوه عملکرد الگوریتم JPG را درک میکنید، چند نکته آشکار میشود:
- تنظیم درست مقدار کیفیت برای هر تصویر، برای پیدا کردن تعادل بین کیفیت بصری و اندازه فایل مهم است.
- از آنجایی که این فرایند مبتنی بر بلوک است، مصنوعات تمایل دارند در بلوکی شدن یا “زنگ زدن” ظاهر شوند.
- از آنجایی که بلوکهای پردازش شده با یکدیگر در هم نمیآمیزند، JPG معمولاً فرصت فشردهسازی بخشهای بزرگ از بلوکهای مشابه را نادیده میگیرد. فرمت WebP در رفع این مشکل بسیار خوب عمل میکند.
و اگر میخواهی خودت با این همه بازی کنی، همه اینها را میتوان به یک فایل حدوداً هزار خطی خلاصه کرد.








