भविष्य को आकार देने वाली तकनीक पर गहन लेख।

JPEG कम्प्रेशन असल में कैसे काम करता है

JPEG कम्प्रेशन की विज़ुअल गाइड: DCT ट्रांसफ़ॉर्म, क्वांटाइज़ेशन टेबल और कुछ इमेज दूसरों से बेहतर क्यों कम्प्रेस होती हैं, यह समझें।

एक फूल की इमेज जो पिक्सेल ब्लॉक्स में बदलती है और फिर घूमती लहर वाले पैटर्न में घुल जाती है

JPEG फ़ाइल फ़ॉर्मेट का कॉकरोच है। यह 1992 में स्टैंडर्ड बना, वेब ब्राउज़र से भी पुराना है, और इसे बदलने की हर कोशिश से बच निकला है। WebP, AVIF, HEIC — ये सब बेहतर कम्प्रेशन देते हैं, फिर भी JPEG इंटरनेट पर सबसे ज़्यादा इस्तेमाल होने वाला इमेज फ़ॉर्मेट बना हुआ है। इसका एक हिस्सा आदत (inertia) है। लेकिन इसका दूसरा हिस्सा यह है कि JPEG की कम्प्रेशन पाइपलाइन सचमुच शानदार है। यह एप्लाइड सिग्नल प्रोसेसिंग का मास्टरक्लास है, जिसे समझना उपयोगी है, भले ही आप कभी encoder न लिखें।

ज़्यादातर डेवलपर JPEG को ब्लैक बॉक्स की तरह देखते हैं: इमेज डालो, छोटी फ़ाइल निकालो, और क्वालिटी स्लाइडर तब तक घुमाते रहो जब तक वह ठीक न लगे। लेकिन बॉक्स के अंदर क्या होता है, यह समझने से आप इमेज, कम्प्रेशन और फ़ाइल साइज़ व विज़ुअल क्वालिटी के बीच के ट्रेड-ऑफ़ को अलग नज़रिए से देखने लगते हैं।

एक नज़र में पाइपलाइन

JPEG कम्प्रेशन पाँच चरणों की एक पाइपलाइन है, और हर चरण में कुछ चतुराई भरा काम होता है। खास बात यह है कि ये चरण एक-दूसरे के साथ जुड़कर काम करते हैं: हर चरण अगले चरण को और असरदार बनाने के लिए तैयार करता है।

  1. कलर स्पेस कन्वर्शन — RGB को YCbCr में बदलना (ब्राइटनेस को रंग से अलग करना)
  2. क्रोमा सबसैंपलिंग — रंग वाले चैनलों का रिज़ॉल्यूशन घटाना
  3. डिस्क्रीट कोसाइन ट्रांसफ़ॉर्म (DCT) — स्पेशियल डेटा को फ़्रीक्वेंसी डेटा में बदलना
  4. क्वांटाइज़ेशन — हाई-फ़्रीक्वेंसी डिटेल हटाना (यही लॉसी स्टेप है)
  5. एंट्रॉपी कोडिंग — क्वांटाइज़ किए गए डेटा की लॉसलेस कम्प्रेशन

पहला और दूसरा चरण इंसानी आँख के काम करने के तरीके का फ़ायदा उठाते हैं। तीसरा और चौथा चरण प्राकृतिक इमेज की खासियतों का फ़ायदा उठाते हैं। पाँचवाँ चरण स्टैंडर्ड डेटा कम्प्रेशन है। हर चरण अपने आप में सरल है। असली कमाल उनके क्रम में है।

चरण 1: कलर स्पेस कन्वर्शन

आपका कैमरा इमेज RGB में कैप्चर करता है: लाल, हरा और नीला चैनल, हर पिक्सेल पर 8 बिट्स के साथ। JPEG की पहली चाल इसे YCbCr में बदलना है: एक ल्यूमिनेंस (चमक) चैनल और दो क्रोमिनेंस (रंग) चैनल। यह अभी कम्प्रेशन नहीं है, इसमें कोई डेटा नहीं खोता। यह एक कोऑर्डिनेट ट्रांसफ़ॉर्म है, जैसे एक्सिस को घुमाना।

इसकी ज़रूरत क्यों? क्योंकि इंसानी आँखें रंग की तुलना में चमक के प्रति कहीं ज़्यादा संवेदनशील होती हैं। ब्लैक-एंड-व्हाइट फ़ोटो में आप बहुत बारीक डिटेल देख सकते हैं, लेकिन रंग का रिज़ॉल्यूशन पहचानने की आपकी क्षमता कहीं मोटी होती है। चमक को रंग से अलग करके JPEG दोनों के साथ अलग बर्ताव कर सकता है: चमक की डिटेल बचाते हुए रंग की डिटेल को ज़ोरदार तरीके से घटाना।

RGB to YCbCr conversion (simplified):
Y  =  0.299R + 0.587G + 0.114B    (luminance — brightness)
Cb = -0.169R - 0.331G + 0.500B    (blue chrominance)
Cr =  0.500R - 0.419G - 0.081B    (red chrominance)
Note: green dominates the luminance calculation because
human eyes have far more green-sensitive cone cells.
This isn't arbitrary — it matches the physiology.

चरण 2: क्रोमा सबसैंपलिंग

यहीं पर पहली असली डेटा कटौती होती है। चूँकि इंसान रंग को पूरे स्पेशियल रिज़ॉल्यूशन पर नहीं देख पाते, JPEG Cb और Cr चैनलों का रिज़ॉल्यूशन घटा देता है, आम तौर पर दोनों आयामों में आधा। इसे 4:2:0 सबसैंपलिंग कहते हैं। हर चार ल्यूमिनेंस पिक्सेल के लिए रंग का एक सैंपल होता है।

नतीजा: आपने कच्चे डेटा को लगभग आधा कर दिया (3 पूरे रिज़ॉल्यूशन वाले चैनलों से 1 पूरा और 2 चौथाई रिज़ॉल्यूशन वाले चैनल), और इमेज मूल जैसी ही दिखती है। खुद आज़माएँ: किसी भी फ़ोटो का कलर चैनल रिज़ॉल्यूशन 4 गुना घटाइए, फिर फ़र्क ढूँढने में मुश्किल होगी। आपका दिमाग ल्यूमिनेंस की जानकारी से रंग की डिटेल खुद भर देता है।

यह हर इमेज के लिए एक जैसा काम नहीं करता। फ़ोटो बहुत अच्छी तरह कम्प्रेस होती हैं, क्योंकि प्राकृतिक दृश्यों में रंग के ग्रेडिएंट चिकने होते हैं। लेकिन जिन इमेज में रंग की तीखी सीमाएँ होती हैं, जैसे रंगीन बैकग्राउंड पर टेक्स्ट, सफ़ेद पर लाल गोला, या पिक्सेल आर्ट, वहाँ क्रोमा सबसैंपलिंग के बाद रंग के किनारे फैलते हुए दिखते हैं। इसीलिए JPEG टेक्स्ट के लिए अच्छा नहीं है: तीखे रंग वाले किनारे धुंधले हो जाते हैं।

चरण 3: डिस्क्रीट कोसाइन ट्रांसफ़ॉर्म

यहीं JPEG दिलचस्प होता है। इमेज को 8×8 पिक्सेल ब्लॉक्स में बाँटा जाता है, और हर ब्लॉक को स्पेशियल डोमेन (पिक्सेल की चमक के मान) से फ़्रीक्वेंसी डोमेन (हर स्पेशियल फ़्रीक्वेंसी कितनी मौजूद है) में बदला जाता है।

इसे ऐसे सोचिए: 8×8 पिक्सेल ब्लॉक को 64 बेसिस पैटर्न के वेटेड जोड़ के रूप में दिखाया जा सकता है। पहला पैटर्न एक समान फ़्लैट ब्लॉक है (औसत मान)। अगले पैटर्न क्षैतिज और ऊर्ध्वाधर ग्रेडिएंट जोड़ते हैं। ऊँची संख्या वाले पैटर्न चमक में तेज़ उतार-चढ़ाव वाली बारीक डिटेल जोड़ते हैं।

An 8x8 DCT block conceptually:
DC ──► Low frequency ──────────────► High frequency
┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┐
│ AVG │  →  │  →  │  →  │  →  │  →  │  →  │  →  │ Low freq
│     │     │     │     │     │     │     │     │   ↓
│  ↓  │  ↘  │     │     │     │     │     │     │
│     │     │  ↘  │     │     │     │     │     │
│     │     │     │  ↘  │     │     │     │     │
│     │     │     │     │  ↘  │     │     │     │
│     │     │     │     │     │  ↘  │     │     │
│     │     │     │     │     │     │  ↘  │     │
│     │     │     │     │     │     │     │ FINE │ High freq
└─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘
Top-left = low frequency (smooth gradients)
Bottom-right = high frequency (sharp edges, fine detail)
Natural images: most energy concentrated in top-left
Text/line art: significant energy in bottom-right

DCT खुद लॉसलेस है: 64 DCT कोएफ़िशिएंट्स से मूल 8×8 ब्लॉक को पूरी तरह से दोबारा बनाया जा सकता है। लेकिन असली खासियत यह है: प्राकृतिक इमेज (फ़ोटो, ग्रेडिएंट, ऑर्गेनिक टेक्सचर) के लिए ज़्यादातर एनर्जी लो-फ़्रीक्वेंसी कोएफ़िशिएंट्स में केंद्रित होती है। हाई-फ़्रीक्वेंसी कोएफ़िशिएंट्स, जो बारीक डिटेल दर्शाते हैं, आम तौर पर छोटे होते हैं। अगला चरण इसी पर टिका है।

8×8 ही क्यों? यह एक समझौता है। बड़े ब्लॉक (16×16, 32×32) एनर्जी को और बेहतर केंद्रित करते, लेकिन उनकी गणना महँगी होती है और कम क्वालिटी पर साफ़ दिखने वाले 'ब्लॉकिंग' आर्टिफ़ैक्ट पैदा करते हैं। छोटे ब्लॉक (4×4) ब्लॉकिंग कम करते, लेकिन एनर्जी को उतना अच्छा केंद्रित नहीं कर पाते। 8×8 एक मीठा बिंदु निकला, जो 30 साल से ज़्यादा समय से टिका हुआ है।

चरण 4: क्वांटाइज़ेशन, जहाँ डेटा मरता है

यही लॉसी स्टेप है। हर DCT कोएफ़िशिएंट को क्वांटाइज़ेशन टेबल की संबंधित वैल्यू से भाग दिया जाता है, फिर निकटतम पूर्णांक में राउंड किया जाता है। बड़े डिवाइज़र (हाई-फ़्रीक्वेंसी कोएफ़िशिएंट्स के लिए) छोटी वैल्यूज़ को शून्य बना देते हैं। वे शून्य हमेशा के लिए खो जाते हैं, यहीं जानकारी स्थायी रूप से हटाई जाती है।

Example quantization (quality ~50):
DCT coefficient: 42.7    Quantization divisor: 16    Result: round(42.7/16) = 3
DCT coefficient: 8.3     Quantization divisor: 40    Result: round(8.3/40)  = 0
DCT coefficient: -2.1    Quantization divisor: 99    Result: round(-2.1/99) = 0
The quality slider in your image editor controls the quantization table.
Quality 100: divisors close to 1 (almost no rounding, huge file)
Quality 75:  moderate divisors (good balance, typical web use)
Quality 50:  large divisors (noticeable artifacts, small file)
Quality 10:  very large divisors (blocky mess, tiny file)

क्वांटाइज़ेशन टेबल JPEG की क्वालिटी का सबसे अहम कारक है। JPEG स्टैंडर्ड एक डिफ़ॉल्ट टेबल देता है, पर encoder अपनी मर्ज़ी की कोई भी टेबल इस्तेमाल कर सकते हैं। MozJPEG जैसे आधुनिक encoder ऑप्टिमाइज़्ड टेबल इस्तेमाल करते हैं, जो डिवाइज़र को इंसानी धारणा की संवेदनशीलता के हिसाब से ट्यून करते हैं: जिन फ़्रीक्वेंसी के प्रति इंसान कम संवेदनशील हैं, उन पर ज़्यादा आक्रामक होकर। इससे छोटी फ़ाइलों में भी बेहतर क्वालिटी मिलती है।

क्वांटाइज़ेशन के बाद, मध्यम क्वालिटी पर एक सामान्य 8×8 ब्लॉक में 64 में से शायद 6-10 ही नॉन-ज़ीरो कोएफ़िशिएंट्स बचते हैं। बाकी सब शून्य होते हैं। नॉन-ज़ीरो वैल्यूज़ में यह भारी कमी ही अंतिम कम्प्रेशन स्टेप को असरदार बनाती है।

चरण 5: एंट्रॉपी कोडिंग

आखिरी स्टेप क्वांटाइज़ किए गए कोएफ़िशिएंट्स की लॉसलेस कम्प्रेशन है। JPEG run-length encoding (RLE) और Huffman coding का मेल इस्तेमाल करता है। कोएफ़िशिएंट्स 8×8 ब्लॉक से ज़िगज़ैग पैटर्न में पढ़े जाते हैं: DC (ऊपर-बाएँ) कोएफ़िशिएंट से शुरू करके बढ़ती फ़्रीक्वेंसी की ओर ज़िगज़ैग करते हुए। इससे सारे ट्रेलिंग ज़ीरो एक साथ आ जाते हैं, जिन्हें RLE कुशलता से संभालता है: '0, 0, 0, 0, ..., 0' स्टोर करने के बजाय वह बस 'सैंतालीस ज़ीरो' स्टोर करता है।

फिर Huffman coding ज़्यादा आम वैल्यूज़ को छोटे बिट-सीक्वेंस और दुर्लभ वैल्यूज़ को लंबे सीक्वेंस देता है। चूँकि ज़्यादातर नॉन-ज़ीरो कोएफ़िशिएंट्स छोटे पूर्णांक (1, -1, 2, -2) होते हैं, उन्हें बहुत छोटे कोड मिलते हैं। नतीजा: 64 वैल्यूज़ से शुरू हुआ क्वांटाइज़ किया गया 8×8 ब्लॉक आम तौर पर 20-40 बाइट्स में कम्प्रेस हो जाता है, जो इमेज की सामग्री और क्वालिटी सेटिंग पर निर्भर है।

कुछ इमेज दूसरों से बेहतर कम्प्रेस क्यों होती हैं

पाइपलाइन समझने से वह कम्प्रेशन व्यवहार समझ आता है जो वरना रहस्यमय लगता है।

  • फ़ोटो अच्छी तरह कम्प्रेस होती हैं क्योंकि उनमें चिकने रंग ग्रेडिएंट होते हैं (क्रोमा सबसैंपलिंग यहाँ बढ़िया काम करती है) और ज़्यादातर एनर्जी लो-फ़्रीक्वेंसी DCT कोएफ़िशिएंट्स में होती है (क्वांटाइज़ेशन बिना दिखे असर के कई कोएफ़िशिएंट्स को शून्य कर देता है)।
  • टेक्स्ट और लाइन आर्ट खराब कम्प्रेस होते हैं क्योंकि तीखे किनारे बड़े हाई-फ़्रीक्वेंसी DCT कोएफ़िशिएंट्स बनाते हैं, जिन्हें साफ़ दिखने वाले आर्टिफ़ैक्ट के बिना शून्य नहीं किया जा सकता। 8×8 ब्लॉक की सीमाएँ टेक्स्ट के किनारों के आसपास रिंगिंग के रूप में दिखने लगती हैं।
  • नॉइज़ कम्प्रेशन को बिगाड़ देता है क्योंकि सेंसर नॉइज़ हाई-फ़्रीक्वेंसी रैंडम डेटा है। हर नॉइज़ी पिक्सेल नॉन-ज़ीरो हाई-फ़्रीक्वेंसी कोएफ़िशिएंट्स जोड़ता है, जो क्वांटाइज़ेशन का विरोध करते हैं। क्वालिटी 80 पर एक नॉइज़ी फ़ोटो, उसी दृश्य की साफ़ फ़ोटो से उसी क्वालिटी पर 3-5 गुना बड़ी हो सकती है।
  • ग्रेडिएंट लगभग मुफ़्त होते हैं क्योंकि 8×8 ब्लॉक में एक चिकना ग्रेडिएंट केवल 2-3 DCT कोएफ़िशिएंट्स से दर्शाया जाता है। बाकी क्वांटाइज़ेशन के बिना भी शून्य होते हैं।
  • दोबारा सेव करने से क्वालिटी घटती है क्योंकि हर सेव साइकल में फिर से क्वांटाइज़ेशन होता है और राउंडिंग एरर जमा होते जाते हैं। क्वालिटी 75 पर JPEG को 10 बार सेव करना, एक बार क्वालिटी 75 पर सेव करने से साफ़ तौर पर बदतर है। इसलिए हमेशा मूल सोर्स फ़ाइल से ही एडिट करें।

क्वालिटी स्लाइडर लीनियर नहीं है

ज़्यादातर डेवलपर JPEG क्वालिटी स्लाइडर को लीनियर ट्रेड-ऑफ़ मान लेते हैं: क्वालिटी 50 मतलब क्वालिटी 100 की आधी क्वालिटी और आधा फ़ाइल साइज़। दोनों में से कोई भी बात सच नहीं।

क्वालिटी 100 'लॉसलेस' नहीं है। इसमें भी क्वांटाइज़ेशन होता है, बस डिवाइज़र छोटे होते हैं। फ़ाइल बहुत बड़ी होती है (अक्सर PNG से भी बड़ी) और दिखने में क्वालिटी 95 से अलग नहीं लगती। फ़ोटो के लिए क्वालिटी 95 और 90 में विज़ुअली कोई फ़र्क नहीं दिखता। क्वालिटी 85 और 75 के बीच का धारणात्मक फ़र्क, 100 और 85 के बीच के फ़र्क से बड़ा है। क्वालिटी 50 के नीचे आर्टिफ़ैक्ट गंभीर हो जाते हैं और फ़ाइल साइज़ में कमी धीमी पड़ जाती है।

वेब इमेज के लिए मीठा बिंदु आम तौर पर क्वालिटी 75-85 होता है। 75 से नीचे, सामान्य व्यूइंग साइज़ पर आर्टिफ़ैक्ट दिखने लगते हैं। 85 से ऊपर, फ़ाइल साइज़ काफ़ी बढ़ जाता है जबकि विज़ुअल सुधार नगण्य होता है। MozJPEG का डिफ़ॉल्ट 75 अच्छा चुना गया है: ज़्यादातर फ़ोटो के लिए यह क्वालिटी-बनाम-साइज़ कर्व के घुटने वाले बिंदु पर बैठता है।

आधुनिक JPEG Encoders आपकी सोच से ज़्यादा स्मार्ट हैं

JPEG स्टैंडर्ड डिकोड फ़ॉर्मेट को परिभाषित करता है, encoder को नहीं। इसका मतलब है कि encoder इम्प्लीमेंटेशन कम्प्रेशन दक्षता में बहुत अलग हो सकते हैं, फिर भी स्पेसिफ़िकेशन-कंप्लायंट फ़ाइलें बना सकते हैं। Mozilla द्वारा विकसित MozJPEG कई तकनीकों के ज़रिए उसी विज़ुअल क्वालिटी पर libjpeg से 5-15% छोटी फ़ाइलें बनाता है।

  • ट्रेलिस क्वांटाइज़ेशन — हर DCT कोएफ़िशिएंट को अलग-अलग राउंड करने के बजाय, ट्रेलिस क्वांटाइज़ेशन देखता है कि राउंडिंग के फ़ैसले एंट्रॉपी कोडिंग स्टेज पर कैसे असर डालते हैं, और समग्र रूप से बेहतर चुनाव करता है।
  • ऑप्टिमाइज़्ड Huffman टेबल — JPEG की डिफ़ॉल्ट Huffman टेबल सामान्य होती हैं। MozJPEG हर इमेज में असल कोएफ़िशिएंट वितरण के हिसाब से कस्टम टेबल बनाता है।
  • प्रोग्रेसिव एन्कोडिंग — प्रोग्रेसिव JPEG कोएफ़िशिएंट्स को कई पासों में स्टोर करते हैं (पहले मोटा, फिर रिफ़ाइनमेंट)। यह अक्सर सीक्वेंशियल एन्कोडिंग से बेहतर कम्प्रेस होता है, क्योंकि मोटे पास में कोएफ़िशिएंट वितरण ज़्यादा अनुमानित होता है।
  • एडैप्टिव क्वांटाइज़ेशन टेबल — पूरी इमेज के लिए एक ही क्वांटाइज़ेशन टेबल के बजाय, एडैप्टिव encoder हर क्षेत्र के हिसाब से टेबल ट्यून करते हैं: व्यस्त इलाकों में ज़्यादा आक्रामक (जहाँ आर्टिफ़ैक्ट कम दिखते हैं) और चिकने इलाकों में ज़्यादा सावधान।

अगर आप वेब पर इमेज सर्व करते हैं, तो डिफ़ॉल्ट libjpeg encoder से MozJPEG पर स्विच करना सबसे आसान परफ़ॉर्मेंस जीतों में से एक है। ज़्यादातर इमेज CDN और प्रोसेसिंग लाइब्रेरी इसे सपोर्ट करती हैं। एन्कोड धीमा होता है (पहले से प्रोसेस की गई स्टैटिक इमेज के लिए इससे फ़र्क नहीं पड़ता), और उसी क्वालिटी पर आउटपुट छोटा होता है।

JPEG बनाम नए फ़ॉर्मेट

WebP, AVIF और HEIC सभी ज़्यादा आधुनिक कम्प्रेशन तकनीकें इस्तेमाल करते हैं: बड़े ट्रांसफ़ॉर्म ब्लॉक, इन-लूप डीब्लॉकिंग फ़िल्टर, और इंट्रा-प्रेडिक्शन (मौजूदा ब्लॉक का अनुमान लगाने के लिए पड़ोसी ब्लॉकों का इस्तेमाल)। वे उसी विज़ुअल क्वालिटी पर JPEG से 20-50% बेहतर कम्प्रेस करते हैं। AVIF, जो AV1 वीडियो कोडेक पर आधारित है, खास तौर पर प्रभावशाली रूप से कुशल है।

तो JPEG आज भी हर जगह क्यों है? यूनिवर्सल सपोर्ट की वजह से। हर ब्राउज़र, हर इमेज व्यूअर, हर ऑपरेटिंग सिस्टम, हर कैमरा, हर फ़ोन और इमेज हैंडल करने वाला हर सॉफ़्टवेयर JPEG को सपोर्ट करता है। WebP ब्राउज़रों में लगभग यूनिवर्सल है, लेकिन नेटिव OS सपोर्ट में कमज़ोर है। AVIF सपोर्ट अभी भी असंगत है। HEIC मुख्य रूप से Apple के इकोसिस्टम तक सीमित है। जिस फ़ॉर्मेट को हर जगह काम करना है, उसके लिए JPEG अब भी एकमात्र सुरक्षित विकल्प है।

व्यावहारिक सलाह: अगर आपका सर्विंग इंफ़्रास्ट्रक्चर सपोर्ट करता है, तो JPEG फ़ॉलबैक के साथ AVIF या WebP इस्तेमाल करें (ज़्यादातर CDN content negotiation के ज़रिए यह करते हैं)। अगर आप केवल एक ही फ़ॉर्मेट रख सकते हैं, तो फ़ोटो के लिए क्वालिटी 80 पर MozJPEG से encode किया गया JPEG हराना मुश्किल है। स्क्रीनशॉट, डायग्राम और टेक्स्ट-भारी इमेज के लिए PNG अब भी बेहतर विकल्प है — या इमेज प्रतिनिधित्व के और रचनात्मक तरीकों को देखें।

वह 8×8 ब्लॉक जिसने दुनिया जीत ली

JPEG की कम्प्रेशन पाइपलाइन इंजीनियरिंग का एक पाठ्यपुस्तक उदाहरण है, जो इंसानी धारणा के खिलाफ नहीं बल्कि उसके साथ काम करती है। हर चरण एक खास गुण का फ़ायदा उठाता है: रंग के प्रति कम संवेदनशीलता, प्राकृतिक इमेज का फ़्रीक्वेंसी वितरण, क्वांटाइज़ेशन शोर का धारणात्मक मास्किंग। ये मिलकर ऐसी व्यवस्था बनाते हैं जो दिखने वाले असर को न्यूनतम रखते हुए फ़ाइलों को 10-20 गुना छोटा कर देती है। चौंतीस साल बाद भी, वही 8×8 DCT ब्लॉक, जो 1992 के हार्डवेयर पर चलते थे, इंटरनेट की ज़्यादातर इमेज अब भी उठाए हुए हैं। यही उस डिज़ाइन की पहचान है जिसने बुनियादी बातें सही कीं।