Chciałbym zasięgnąć Waszych rad i opinii na temat konwersji barw z zdefiniowanych w ramach palety RGB na 256 ukochanych kolorów Atari.

Osobiście zastanawiam się nad następującym rozwiązaniem:

Proporcje wagowe bitów R G B dają następujące barwy:

RGB
111 - szary    (odpowiednik koloru $0x Atari)
100 - czerwony (odpowiednik koloru $3x Atari)
110 - zółty (odpowiednik koloru $Fx Atari)
101 - fioletowy (odpowiednik koloru $6x Atari)
011 - turkusowy (odpowiednik koloru $Ax Atari)
010 - zieleń (odpowiednik koloru $Cx Atari)
001 - niebieski (odpowiednik $9x Atari)

I teraz mając barwę zdefiniowaną w ramach RGB na odstawie proporcji składowych dobieram kolor Atari.

Dobór jasności przeliczam liniowo: $FFFFFF - to jasność $F, $000000 - to $0

I tu moje pytanie do osób, które zajmowały się tym tematem - czy macie jakieś wskazówki/uwagi dla tego algorytmu, ew. inne pomysły ?

2

function rgbRead(cl: Tcolor):byte;
var l, d, c, ma, mi, r2, g2, b2: integer;
    h, lu1, lu2, lu3: real;
    r, g, b: byte;
begin

ma:=0; mi:=0; h:=0; c:=0;

R:=GetRValue(cl) shr 4;
G:=GetGValue(cl) shr 4;
B:=GetBValue(cl) shr 4;

if (r=g) and (g=b) then begin rgbRead:=r; exit; end;
if (r>=g) and (r>=b) then ma:=r;
if (r<=g) and (r<=b) then mi:=r;
if (g>=r) and (g>=b) then ma:=g;
if (g<=r) and (g<=b) then mi:=g;
if (b>=g) and (b>=r) then ma:=b;
if (b<=g) and (b<=r) then mi:=b;

d:=ma-mi;
if d=1 then begin rgbRead:=mi; exit; end;

r2:=r*100; g2:=g*100; b2:=b*100;
 if r=ma then h:=(g2-b2)/d
   else
 if g=ma then h:=200+((b2-r2)/d)
   else
 if b=ma then h:=400+((r2-g2)/d);

h:=h*0.6; if h<0 then h:=h+360;

lu1:=r*0.296;
lu2:=g*0.586;
lu3:=b*0.106;

l:=trunc(lu1+lu2+lu3) and $0f;

case trunc(h) of
 21..31: c:=15;
 32..43: c:=14;
 44..63: c:=13;
 64..84: c:=12;
 85..147: c:=11;
 148..171: c:=10;
 172..191: c:=9;
 192..209: c:=8;
 210..261: c:=7;
 262..276: c:=6;
 277..297: c:=5;
 298..318: c:=4;
 319..334: c:=3;
 335..360: c:=2;
 0..14: c:=2;
 15..20: c:=1;
end;

rgbRead:=c shl 4+l;
end;
*- TeBe/Madteam
3x Atari 130XE, SDX, CPU 65816, 2x VBXE, 2x IDE Plus rev. C

3 Ostatnio edytowany przez epi (2008-12-25 16:23:58)

Problem można uogólnić do konwersji RGB na dowolną paletę. Opisujesz wszystkie kolory dostępne na Atari przez składowe R, G, B (gotowych palet jest już co najmniej kilka).

Teraz dla danego dowolnego koloru zdefiniowanego przez R, G, B wyszukujesz najbliższy mu kolor w palecie. Kryterium "najbliższości" można sobie wybrać dowolnie, najprościej np. tak: najbliższy kolor to taki, dla którego suma kwadratów różnic (R_koloru - R_palety)^2 + (B_koloru - B_palety)^2 + (G_koloru - G_palety)^2. Oczywiście można skomplikować i uzależnić konwersję (przypisać różne wagi dla poszczególnych składowych) od właściwości sygnału koloru z Atari, statystyki widzenia ludzkich oczu, profili barwnych monitorów, prędkości i przyspieszenia elektronów w kineskopie, stężenia etanolu we krwi oglądającego, stężenia dymu w powietrzu na sali, gdzie odbywają się kompoty, zależności temperatury par ołowiu od ciśnienia, funkcji falowych kwantowego oscylatora harmonicznego i czego dusza zapragnie, ale bez tego też działa dobrze (vide TipConv).
Przydaje się tylko podciągnięcie nasycenia barw konwertowanego obrazka (albo zdefiniowanie mniej nasyconej palety Atari, jak kto woli).

Hitler, Stalin, totalniak, SSman, NKWDzista, kaczor dyktator, za długo byłem w ChRL, wypowiadam się afektywnie.

4 Ostatnio edytowany przez Marek Konopka (2008-12-26 13:58:33)

1) Bez kolorymetru się nie obędzie, ewentualnie danych o koordynatach barw Atari w jakimś fizycznym modelu barw, np. takim jakim jest CIE XYZ/CIE xyY (a przynajmniej jego rzucie - CIE XY). Najpierw należałoby skalibrować sprzętowo jakiś monitor do wyświetlania barw w zgodzie ze standardami PAL/NTSC. Ostatecznie wystarczy poprawnie dostrojony telewizor. W przypadku monitora przydałby się jego jakiś rozbudowany model z poszerzoną paletą barw składowych (10'cio, 12'sto bitową), tak aby móc pomierzyć barwy Atarki z maksymalną możliwą dokładnością. Potrzebny będzie również tuner TV.
2) Należy pomierzyć kolory maluszka na skalibrowanym sprzęcie (bodajże do modelu sRGB) i zanotować je we wsp. modelu CIE XYZ, ew. sRGB
3) Zadanie jest o tyle złożone, że wyniki są zależne od pokrętła barw znajdującego się na spodzie komputera. Sugerowanym rozwiązaniem jest dokonanie pomiarów dla kilku ustawień - dwóch skrajnych i jakiegoś pośredniego. Ew. jeśli char. zmian parametrów jest liniowa (lub jakaś inna znana), można to adekwatnie uwzględnić podczas dopasowywania barw w oparciu o pomiary oraz tę charakterystykę. Nie pamiętam już, który parametr opisujący kolor zmienia to pokrętło - nasycenie barw czy odcienie.
4) Dla prostego policzenia barw wystarczy f. minimum odległości między dopasowywaną barwą w modelu CIE XYZ/RGB a kolorami maluszka. W ostateczności, wszystkich kalkulacji możemy dokonać w modelu RGB, ale wtedy tracimy na uniwersalności rozwiązania i jesteśmy uzależnieni od charakterystyk konkretnych wyświetlaczy, które mogą mieć przeróżne odchyłki, nawet po kalibracji.

Aktualizacja:
Zapewne jakiś układ atarynki (nie wiem który) zawiera zaszytą w sobie tablicę barw przeliczającą indeksy atarowskiego koloru do poziomów sygnałów wyjściowych luminancji oraz chromy. Teoretycznie można pomierzyć te sygnały dla wszystkich barw maluszka, dokonać przeliczenia do modelu YUV/YIQ (NTSC) a stąd do RGB. Tutaj jednak należałoby znać również sposób miksowania barw uwzględniający pokrętło kolorów.

Aktualizacja:
Tutaj odnalazłem częstotliwości dla modulacji sygnału TV w standardzie SECAM http://ftp.pigwa.net/stuff/collections/ … /FGTIA.PDF - tabela FGTIA Color Line to Color Output Frequency Conversions - strona 21. Być może w oparciu o tą i podobne tabele można dokonać dalszych ustaleń.

5

epi napisał/a:

najbliższy kolor to taki, dla którego suma kwadratów różnic (R_koloru - R_palety)^2 + (B_koloru - B_palety)^2 + (G_koloru - G_palety)^2.

Zjadłeś "jest najmniejsza".

Z innej beczki - może to na grzyba poza tym dawne czasy ale a nóż może się ktoś z tym problemem zetknie i mu się przyda...

[OT MODE ON]
Robiłem kiedyś trochę gierek w 13h na grzybie. Czasami dla uzyskania lepszego wrażenia wizualnego trzeba było wprowadzić półprzezroczystość (animacje wybuchów na przykład - patrz Tyrian).
Zachodziłem w głowę jak to zrobić, żeby dzialało szybko na tyle aby na 1 ramce zamalować cały ekran tłem+na tło półprzezroczysty plan.
Gdy mamy tryb rgb - nie ma problemu, jednak w trybie paletowym odszukiwanie koloru w palecie przy pomocy algorytmu wspomnianego przez Epiego jest conajmniej powolne (dla każdego pixela liczyć kwadraty składowych i kolorów palety...). Zrobiłem inaczej: paleta 256x256 przeliczona na początku programu gdzie założyłem, że kolor z tab[a,b] to kolor półprzezroczystego fg o kolorze b na tle o kolorze a. Pobieranie wartości z tej tablicy przy rysowaniu sprajtów tylko trochę spowolniło wyświetlanie. Po jakimś czasie jeszcze udoskonaliłem algorytm: łatwo zauwazyć, że tab[a,b] to to samo co tab[b,a] - więc marnowały się dane. W takim razie zmieniłem tablicę tak, że pobierając z jednej strony było powiedzmy 33% przezroczystości a z drugiej było 66%.
Ot dawne czasy.. efekty tych procek widać w grach na stronie kumpla:
http://gad.art.pl szukać Sadist II oraz Celis (inspirowane zybexem!)
[OT MODE OFF]