मान लें कि आप RGB रंगों के साथ काम कर रहे हैं: प्रत्येक रंग को तीन तीव्रता या चमक के साथ दर्शाया गया है । आपको "रैखिक RGB" और "sRGB" के बीच चयन करना है। अभी के लिए, हम तीन अलग-अलग तीव्रता को अनदेखा करके चीजों को सरल करेंगे, और मान लें कि आपके पास बस एक तीव्रता है: अर्थात, आप केवल ग्रे के रंगों के साथ काम कर रहे हैं।
एक रैखिक रंग-स्थान में, आपके द्वारा संग्रहित संख्याओं और उनके द्वारा प्रदर्शित तीव्रता के बीच का संबंध रैखिक होता है। व्यावहारिक रूप से, इसका मतलब है कि यदि आप संख्या को दोगुना करते हैं, तो आप तीव्रता (ग्रे की लपट) को दोगुना करते हैं। यदि आप दो तीव्रता को एक साथ जोड़ना चाहते हैं (क्योंकि आप दो प्रकाश स्रोतों के योगदान के आधार पर तीव्रता की गणना कर रहे हैं, या क्योंकि आप एक अपारदर्शी वस्तु के ऊपर एक पारदर्शी वस्तु जोड़ रहे हैं), तो आप इसे केवल जोड़कर कर सकते हैं एक साथ दो नंबर। यदि आप किसी भी तरह के 2 डी सम्मिश्रण या 3 डी छायांकन, या लगभग किसी भी छवि प्रसंस्करण कर रहे हैं, तो आप एक रैखिक रंग-स्थान में अपनी तीव्रता चाहते हैं, इसलिए आप तीव्रता पर समान प्रभाव डालने के लिए बस जोड़, घटा, गुणा और भाग कर सकते हैं। अधिकांश रंग-प्रसंस्करण और रेंडरिंग एल्गोरिदम केवल रैखिक आरजीबी के साथ सही परिणाम देते हैं, जब तक कि आप हर चीज में अतिरिक्त भार नहीं जोड़ते हैं।
यह वास्तव में आसान लगता है, लेकिन एक समस्या है। प्रकाश के प्रति मानव की संवेदनशीलता उच्च तीव्रता की तुलना में कम तीव्रता पर महीन होती है। यह कहना है, यदि आप उन सभी तीव्रता की सूची बनाते हैं जो आप भेद कर सकते हैं, तो प्रकाश की तुलना में अधिक अंधेरे हैं। इसे दूसरे तरीके से रखने के लिए, आप ग्रे के हल्के रंगों के अलावा ग्रे के हल्के रंगों को बेहतर बता सकते हैं। विशेष रूप से, यदि आप अपनी तीव्रता का प्रतिनिधित्व करने के लिए 8 बिट्स का उपयोग कर रहे हैं, और आप इसे रैखिक रंग-स्थान में करते हैं, तो आप बहुत सारे लाइट शेड्स के साथ समाप्त होंगे, और पर्याप्त डार्क शेड्स नहीं। आप अपने अंधेरे क्षेत्रों में बैंडिंग करते हैं, जबकि आपके प्रकाश क्षेत्रों में, आप सफेद के विभिन्न रंगों पर बिट्स को बर्बाद कर रहे हैं जो उपयोगकर्ता अलग नहीं कर सकता है।
इस समस्या से बचने के लिए, और उन 8 बिट्स का सबसे अच्छा उपयोग करने के लिए, हम sRGB का उपयोग करते हैं । SRGB मानक आपको अपने रंगों को गैर-रैखिक बनाने के लिए उपयोग करने के लिए एक वक्र बताता है। नीचे की तरफ कर्व है, इसलिए आपके पास अधिक गहरे रंग के ग्रे, और सबसे ऊपर स्टिपर है, इसलिए आपके पास कम प्रकाश ग्रिड हैं। यदि आप संख्या को दोगुना करते हैं, तो आप तीव्रता को दोगुना करते हैं। इसका मतलब है कि यदि आप sRGB रंगों को एक साथ जोड़ते हैं, तो आप एक परिणाम के साथ समाप्त होते हैं जो हल्का होना चाहिए। इन दिनों, अधिकांश मॉनिटर अपने इनपुट रंगों की व्याख्या sRGB के रूप में करते हैं। इसलिए, जब आप स्क्रीन पर एक रंग डाल रहे हों, या इसे 8-बिट-प्रति-चैनल बनावट में संग्रहीत कर रहे हों , तो इसे sRGB के रूप में संग्रहीत करें , इसलिए आप उन 8 बिट्स का सबसे अच्छा उपयोग करते हैं।
आप देखेंगे कि अब हमें एक समस्या है: हम चाहते हैं कि हमारे रंग रैखिक स्थान पर संसाधित हों, लेकिन sRGB में संग्रहीत हैं। इसका मतलब है कि आप पढ़ने पर sRGB-to-रैखिक रूपांतरण कर रहे हैं, और लिखने पर रैखिक-से-sRGB रूपांतरण कर रहे हैं। जैसा कि हमने पहले ही कहा है कि रैखिक 8-बिट तीव्रता में पर्याप्त अंधेरा नहीं है, यह समस्या पैदा करेगा, इसलिए एक और व्यावहारिक नियम है: यदि आप इसे से बच सकते हैं तो 8-बिट रैखिक रंगों का उपयोग न करें । इस नियम का पालन करना पारंपरिक हो रहा है कि 8-बिट रंग हमेशा sRGB होते हैं, इसलिए आप अपनी sRGB-से-रैखिक रूपांतरण उसी समय करते हैं, जब आपकी तीव्रता 8 से 16 बिट्स तक बढ़ जाती है, या पूर्णांक से फ्लोटिंग-पॉइंट तक; इसी तरह, जब आपने अपना फ़्लोटिंग-पॉइंट प्रोसेसिंग समाप्त कर लिया है, तो आप sRGB में कनवर्ट करने के साथ-साथ 8 बिट तक संकीर्ण होते हैं। यदि आप इन नियमों का पालन करते हैं,
जब आप एक sRGB छवि पढ़ रहे हों, और आप रेखीय तीव्रता चाहते हैं, तो इस सूत्र को प्रत्येक तीव्रता पर लागू करें:
float s = read_channel();
float linear;
if (s <= 0.04045) linear = s / 12.92;
else linear = pow((s + 0.055) / 1.055, 2.4);
दूसरे रास्ते पर जाने पर, जब आप किसी छवि को sRGB के रूप में लिखना चाहते हैं, तो इस सूत्र को प्रत्येक रैखिक तीव्रता पर लागू करें:
float linear = do_processing();
float s;
if (linear <= 0.0031308) s = linear * 12.92;
else s = 1.055 * pow(linear, 1.0/2.4) - 0.055; ( Edited: The previous version is -0.55 )
दोनों ही मामलों में, फ़्लोटिंग-पॉइंट का मान 0 से 1 तक होता है, इसलिए यदि आप 8-बिट पूर्णांक पढ़ रहे हैं, जिसे आप 255 से विभाजित करना चाहते हैं, और यदि आप 8-बिट पूर्णांक लिख रहे हैं, तो आप 255 से गुणा करना चाहते हैं अंत में, उसी तरह जो आप आमतौर पर करेंगे। बस आपको sRGB के साथ काम करने की जानकारी होनी चाहिए।
अब तक, मैंने केवल एक ही तीव्रता से निपटा है, लेकिन रंगों के साथ चतुर चीजें हैं। मानव आंख अलग-अलग चिह्नों की तुलना में अलग-अलग चमक को बता सकती है (तकनीकी रूप से, इसमें क्रोमिनेंस की तुलना में बेहतर ल्यूमिनेन्स रिज़ॉल्यूशन है), इसलिए आप टिंट से अलग चमक को संग्रहीत करके अपने 24 बिट्स का और भी बेहतर उपयोग कर सकते हैं। यह वही है जो YUV, YCrCb इत्यादि का प्रतिनिधित्व करने की कोशिश करता है। वाई चैनल रंग की समग्र लपट है, और अन्य दो चैनलों की तुलना में अधिक बिट्स (या अधिक स्थानिक रिज़ॉल्यूशन) का उपयोग करता है। इस तरह, आपको (हमेशा) आरजीबी तीव्रता के साथ एक वक्र लगाने की आवश्यकता नहीं है। YUV एक रैखिक रंग-स्थान है, इसलिए यदि आप Y चैनल में संख्या को दोगुना करते हैं, तो आप रंग की चमक को दोगुना कर देते हैं, लेकिन आप YUV रंगों को एक साथ जोड़ या गुणा नहीं कर सकते हैं जैसे आप RGB रंगों के साथ कर सकते हैं, इसलिए यह '
मुझे लगता है कि आपके सवाल का जवाब है, इसलिए मैं एक त्वरित ऐतिहासिक नोट के साथ समाप्त करूंगा। SRGB से पहले, पुराने CRT में एक गैर-रैखिकता का उपयोग किया जाता था। यदि आप एक पिक्सेल के लिए वोल्टेज को दोगुना करते हैं, तो आप तीव्रता को दोगुना से अधिक करेंगे। प्रत्येक मॉनिटर के लिए कितना अधिक भिन्न था, और इस पैरामीटर को गामा कहा जाता था । यह व्यवहार उपयोगी था क्योंकि इसका मतलब था कि आप रोशनी की तुलना में अधिक अंधेरा पा सकते हैं, लेकिन इसका मतलब यह भी है कि आप यह नहीं बता सकते कि आपके रंग उपयोगकर्ता के सीआरटी पर कितने उज्ज्वल होंगे, जब तक कि आप इसे पहले कैलिब्रेट नहीं करते। गामा सुधारआप (शायद रैखिक) के साथ शुरू होने वाले रंगों को बदलने और उपयोगकर्ता के सीआरटी के गामा के लिए उन्हें बदलने का मतलब है। OpenGL इस युग से आता है, यही कारण है कि इसका sRGB व्यवहार कभी-कभी थोड़ा भ्रमित होता है। लेकिन GPU विक्रेता अब मेरे द्वारा ऊपर बताए गए अधिवेशन के साथ काम करते हैं: जब आप किसी बनावट या फ्रेम-बफ़र में 8-बिट की तीव्रता का भंडारण कर रहे होते हैं, तो यह sRGB होता है, और जब आप रंगों को संसाधित कर रहे होते हैं, तो यह रैखिक होता है। उदाहरण के लिए, एक OpenGL ES 3.0, प्रत्येक फ्रेमबफ़र और बनावट में एक "sRGB ध्वज" होता है जिसे आप पढ़ते और लिखते समय स्वचालित रूपांतरण को सक्षम कर सकते हैं। आपको स्पष्ट रूप से sRGB रूपांतरण या गामा सुधार बिल्कुल करने की आवश्यकता नहीं है।