Gamut Mapping: Her Renk Her Ekranda Gösterilemez
sRGB ve Display P3 gamut sınırları, out-of-gamut renkler ve Helmlab'ın ton koruyarak kroma azaltan gamut mapping yaklaşımı.
Bir tasarim aracinda harika bir turkuaz seciyorsunuz. Hex kodunu alip CSS'e yapistiriyorsunuz. Ama ekranda gordugumuz renk, sectiginizden farkli gorunuyor — daha soluk, belki biraz farkli bir ton. Bu bir bug degil. Bu bir gamut siniri.
Her ekranin gosterebilecegi bir renk kumesi vardir ve bu kume sonlu. Teorik renk uzaylarinda var olan renklerin hepsi ekranlarda gosterilemez. Bu yazida, gamut kavramini, neden bazi renklerin kayboldigini ve Helmlab'in bu sorunu nasil cozdugunu anlatiyoruz.
Gamut Nedir?
Gamut, bir cihazin uretebilecegi veya gosterebilecegi renklerin toplamini ifade eder. Bunu bir boya kutusu gibi dusunun: kutunuzda 12 boya varsa, bu 12 boyayi karisterarak elde edebileceginiz tum renkler gamutunuzdur. Ama kutunuzda olmayan bir tonu — mesela floresan yesili — ne kadar karisteirseniz karistirin elde edemezsiniz.
Bilgisayar ekranlari da boyledir. Her monitorde uc temel isik kaynagi vardir: kirmizi, yesil ve mavi (RGB). Bu uc isigi farkli yogunluklarda karisterarak ekraninizdaki her pikselin rengini olusturur. Ama bu uc kaynagin spektral ozellikleri, ekranin gosterebilecegi renkleri sinirlar.
sRGB, Display P3 ve Teorik Lab
Renk dunyasinda uc temel gamut seviyesi vardir:
sRGB: Standart Gamut
1996 yilinda HP ve Microsoft tarafindan tanimlanan sRGB, internetteki baskil standarttir. Cogu monitior, tarayici ve isletim sistemi renkleri sRGB olarak yorumlar. Hex kodlari (#FF5733), CSS'teki rgb() fonksiyonu, JPEG fotograflar — hepsi varsayilan olarak sRGB'dir.
Ama sRGB, insan gozunun gorebilecegi renklerin sadece yaklasik ucte birini kapsar. Ozellikle doygun cyan, koyu turkuaz ve parlak yesil tonlarda sRGB ciddi sekilde sinirlidir.
Display P3: Genis Gamut
Apple'in 2016'dan bu yana tum cihazlarinda kullandigi Display P3, sRGB'den yaklasik %25 daha genis bir gamut sunar. Ozellikle kirmizi ve yesil bolgelerinde belirgin bir genisleme saglar. iPhone, iPad, MacBook Pro ekranlari ve bircokmmodern Android cihaz bu gamutun tamamini veya buyuk bolumunu gosteebilir.
CSS'te Display P3 renkleri su sekilde tanimlanir:
/* sRGB: standart */
color: rgb(255, 87, 51);
/* Display P3: daha genis gamut */
color: color(display-p3 1.0 0.34 0.20);CIE Lab / Helmlab Lab: Teorik Uzay
CIE Lab ve Helmlab Lab gibi algisal renk uzaylari, herhangi bir cihazla sinirli degildir. Bu uzaylar insan gorusunun tamamini modeller — goz gorebilen her rengi koordinatlarla ifade edebilir. Ancak bu koordinatlarin cogu, hicbir ekranda gosterilemez.
Yukaridaki sema ozetliyor: Lab uzayindaki renklerin bir bolumu sRGB'nin icinde, bir bolumu sadece Display P3 ile gosterilebilir ve bir bolumu de hicbir guncel ekranda gosterilemez.
Gamut Disi Ne Zaman Olur?
Gunluk calismada gamut disina cikmak dusuneceginizden daha yaygindir:
- Palet uretimi — Lab uzayinda esit aralikli bir renk olcegi olusturdugunuzda, bazi adimlar sRGB sinirlari disina cikabilir. Ozellikle doygun tonlarin acik ve koyu uclari gamut disina duser.
- Renk interpolasyonu — Iki sRGB rengi arasinda Lab'da gecis yaptiginizda, ara renklerden bazilari sRGB disinda olabilir. Ozellikle mavi-yesil geeisleri bu soruna aciktir.
- Genis gamut fotograflar — iPhone'la cekilmis bir DCI-P3 fotograf, sRGB monitorde gosteeildiginde doygunluk kaybeder. Bu kayip nasil yonetilir, gamut mapping stratejisine baglidir.
- Tasarim araclari — Figma'da Display P3 modunda calistirip, sonra CSS'e sRGB olarak aktardiginizda, bazi renkler degisir.
Naif RGB Clamping: En Kolay ve En Yanlis Yontem
Gamut disinda bir renginiz var. En basit cozum: her RGB kanalini 0-1 araligina kesmek (clamping). Ama bu yaklasim ciddi bir sorun yaratir: ton kaymasi (hue shift).
Neden? Cunku RGB kanallari birbirinden bagimsiz kesildiginde, kanallarin orani degisir. Ve renk tonu, tam olarak bu orana baglidir.
Bir ornek: Lab uzayinda doygun bir cyan renginiz var. sRGB'ye cevirdiginizde mavi kanali 1.0'i asiyor. Naive clamp bunu 1.0'a keser, ama kirmizi ve yesil kanallara dokunmaz. Sonuc: mavi azaldi, ama kirmizi ve yesil ayni — renk artik cyan degil, yesile kaydi. Gozle acikca fark edilir.
Bu sorun ozellikle palette uretiminde yikicidir. 11 adimli bir renk olceginde 3-4 adim gamut disina cikarsa ve her biri farkli yonde kayarsa, olceginiz artik perceptually uniform degildir.
Helmlab'in Yaklasimi: Chroma Azaltma ile Gamut Mapping
Helmlab, gamut mapping icin tamamen farkli bir strateji kullanir: binary search ile chroma azaltma. Prensip basittir:
- Rengi Lab koordinatlarina ayir: L (parlakilk), C (doygunluk), H (ton)
- L ve H sabit tut — bunlar rengin "kimligi"
- C'yi kademeli olarak azalt (binary search ile) — renk gamut sinirinin icine girene kadar
- Sonuc: ayni ton, ayni parlaklik, sadece daha az doygun
Bu yaklasimin kilit avantaji: ton asla degismez. Bir turkuaz, gamut mapping'den sonra da turkuaz kalir — sadece biraz daha soluk. Bir kirmizi, hala kirmizi. Rengin kimligi korunur.
Binary Search Nasil Calisiyor?
Helmlab, chroma icin optimum degeri bulmak uzere binary search kullanir. Algoritma soyleydir:
- Baslangic: C_min = 0 (kesinlikle gamut icinde), C_max = mevcut chroma (gamut disi)
- Orta noktayi test et: C_mid = (C_min + C_max) / 2
- Eger C_mid gamut icindeyse: C_min = C_mid (daha yuksek chroma dene)
- Eger C_mid gamut disindaysa: C_max = C_mid (daha dusuk chroma dene)
- 50 iterasyona kadar veya hassasiyet 0.0001'e ulasana kadar tekrarla
50 iterasyon, chroma degerini 2^50 bolunurluge kadar hassaslastirir — bu, pratikte mutlak hassasiyettir. Ve her iterasyonda sadece bir Lab → XYZ → lineer RGB donusumu yapilir, bu da son derece hizlidir.
Helmlab'da Gamut Mapping: toSRGB() ve toHex()
Helmlab npm paketinde gamut mapping otomatiktir. toSRGB() veya toHex() cagirdiginizda, eger renk sRGB gamutunun disindaysa, chroma azaltma otomatik olarak uygulanir:
import { Helmlab } from 'helmlab';
const hl = new Helmlab();
// Lab'da doygun bir renk tanimlayalim
// (bu renk sRGB gamutunun disinda olabilir)
const lab = hl.fromSRGB(0.0, 0.85, 1.0);
console.log('Lab:', lab);
// toHex() otomatik gamut mapping yapar
const hex = hl.toHex(lab);
console.log('Hex:', hex);
// Gamut icinde mi kontrol et
console.log('sRGB icinde mi?', hl.isInSRGB(lab));
console.log('P3 icinde mi?', hl.isInP3(lab));Gamut kontrolunu manuel de yapabilirsiniz:
import { Helmlab } from 'helmlab';
const hl = new Helmlab();
// Herhangi bir hex kodundan basla
const lab = hl.fromHex('#00d9ff');
console.log('sRGB gamutunda:', hl.isInSRGB(lab));
console.log('Display P3 gamutunda:', hl.isInP3(lab));
// toSRGB gamut mapping uygular
const [r, g, b] = hl.toSRGB(lab);
console.log('sRGB:', r.toFixed(3), g.toFixed(3), b.toFixed(3));
// toDisplayP3 daha genis gamutta map eder
const [r3, g3, b3] = hl.toDisplayP3(lab);
console.log('P3:', r3.toFixed(3), g3.toFixed(3), b3.toFixed(3));Palet Uretiminde Gamut Mapping
Gamut mapping en cok palet uretiminde onem kazanir. Helmlab'in semanticScale() fonksiyonu, her adimda gamut mapping uygular:
import { Helmlab } from 'helmlab';
const hl = new Helmlab();
// Doygun bir cyan icin palet olustur
const palette = hl.semanticScale('#00BCD4');
// Her adim otomatik olarak gamut-mapped
// Koyu adimlar (50-200): buyuk olasilikla gamut icinde
// Acik adimlar (800-950): gamut sinirinda, chroma azaltilmis
// Sonuc: ton hep ayni, sadece doygunluk ayarlaniyor
console.log(palette);
// { 50: '#f0fdfd', 100: '#ccf5f6', ... 900: '#003d44', 950: '#001f22' }Bu neden onemli? Cunku gamut mapping olmadan, acik tonlardaki adimlar naive clamp yuzunden farkli tonlara kayar ve palette tutarsizlik olusur. Helmlab bunu otomatik olarak cozuyor.
Display P3 ile Calisma
Eger hedefiniz Display P3 destekleyen cihazlarsa, Helmlab ayni yaklasimi daha genis gamut icin de sunar:
import { Helmlab } from 'helmlab';
const hl = new Helmlab();
const lab = hl.fromHex('#00BCD4');
// sRGB ile P3 arasindaki farki gorun
console.log('sRGB icinde:', hl.isInSRGB(lab));
console.log('P3 icinde:', hl.isInP3(lab));
// P3 daha genis gamut sundugu icin,
// bazi renkler sRGB'de gamut mapping gerektirirken
// P3'te dogrudan gosterilebilir
const srgb = hl.toSRGB(lab);
const p3 = hl.toDisplayP3(lab);
console.log('sRGB:', srgb.map(v => v.toFixed(3)));
console.log('P3: ', p3.map(v => v.toFixed(3)));P3 destekleyen ekranlarda, CSS'te @media (color-gamut: p3) sorgusunu kullanarak genis gamut renkleri sunabilirsiniz. Helmlab her iki gamut icin de ayni kalitede gamut mapping saglar.
Neden Sadece Chroma Azaltiliyor?
Gamut mapping icin baska stratejiler de mevcut. Bazi yaklasimlar lightness'i da degistirir, bazilari hue'yu kaydirarak daha doygun bir yaklasim arar. Helmlab neden sadece chroma'yi azaltir?
- Ton korunmasi — Hue, bir rengin en onemli tanimlayici ozelligi. Kirmizi kirmizi kalmali, mavi mavi kalmali. Hue'yu degistirmek, rengin kimligini degistirir.
- Parlaklik tutarliligi — Lightness'i degistirmek, ozellikle palette uretiminde zincirleme sorunlar yaratir. Eslestirmesindeki L adimlarini bozar.
- Algisal dogruluk — Insan gozu, doygunluk kaybiina tonve parlaklik degisiminden daha az duyarlidir. Az bir doygunluk kaybi neredeyse fark edilmezken, kucuk bir ton kaymasi hemen goze carpar.
- Terslenebilirlik — Chroma azaltma, H ve L'yi sabit tutarak tek boyutlu bir arama yapar. Bu, hesaplama olarak verimli ve sonuclari tahmin edilebilir kilar.
Sonuc
Her renk her ekranda gosterilemez. sRGB, Display P3 ve teorik Lab uzaylari farkli buyuklukte gamutlara sahiptir. Renk paleti uretirken, renk interpolasyonu yaparken veya genis gamut icerigi sRGB ekranlara tasirken, gamut disina cikmak kacunilmazdir.
Naif RGB clamping, kanallari bagimsiz keserek ton kaymasina neden olur. Helmlab bunu tamamen farkli bir sekilde cozuyor: tonu ve parlakligi sabit tutup, binary search ile sadece chroma'yi (doygunlugu) azaltir. Sonuc, rengin kimligini koruyan, tahmin edilebilir ve algisal olarak dogru bir gamut mapping.
Tum bunlar toSRGB() ve toHex() cagrilarinda otomatik olarak gerceklesir:
npm install helmlabKaynak kod: GitHub | Paket: npm
Bu yazi, Helmlab serisi 16 blog yazisinin sekizincisidir. Bir sonraki yazida: Neutral Correction — Helmlab'in akromatik ekseni nasil yapisal olarak garanti ettigini anlatiyoruz.