Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Skrypt który rozpoznaje kolor
Forum PHP.pl > Forum > PHP
renevaggio
Witam

Mam problem. Piszę serwis który pomaga użytkownikowi w tworzeniu szablonu do allegro. Uzytkownik przechodzi krok po kroku przez etapy wyboru opcji i na koniec generuje mu się gotowy kod.

Wszystko mam już gotowe ale pojawił się jeden poważny problem. W pewnym momencie użytkownik ma możliwość wyboru tła szablonu. I tutaj jest problem ponieważ system musi dobrać do tego tła odpowiedni kolor czcionki. Załóżmy że użytkownik wpisze jakiś kolor w formacie HEX i teraz skąd serwis ma wiedzieć czy ten kolor jest jasny czy ciemny. A to jest istotna informacja żeby dać czcionkę albo białą, albo czarną.

Szukałem w internecie, ale nie znalazłem kompletnie nic na ten temat, a nie zamierzam robić listy wszystkich ( lol ) kolorów i przypisywać im czy są jasne czy ciemne biggrin.gif:D

Proszę pomóżcie.

Pozdrawiam serdecznie

P.S.

kod hex dzieli się na 3 części

# RR GG BB

RR - od 00 - FF ( 0 - 255 ) W czym 0 to najciemniejszy a 255 najjaśniejszy lub po prostu czysty kolor czerwony
GG - od 00 - FF ( 0 - 255 ) W czym 0 to najciemniejszy a 255 najjaśniejszy lub po prostu czysty kolor zielony
BB - od 00 - FF ( 0 - 255 ) W czym 0 to najciemniejszy a 255 najjaśniejszy lub po prostu czysty kolor niebieski

Gdyby tak rozdzielić dany kolor na 3 partie. Następnie sprawdzić w każdej partii czy kolor jest od 0 - 125 czy od 125 - 255 i na tej podstawie określić czy jest jasny czy ciemny

Potem obliczyć średnią z 3 partii. I wtedy wyszło by czy jest jasny czy ciemny, ale nie wiem czy rozumuje prawidłowo. Tak tylko głośno myslę.
Pawel_W
hex to zapis szesnastkowy

pierwsze 2 znaki oznaczają wartość koloru czerwonego, kolejne 2 zielonego, kolejne 2 niebieskiego

najprościej będzie jeżeli rozbijesz sobie ten ciąg na takie grupy po 2, następnie użyjesz hexdec

potem sprawdzasz przedziały w jakich znajdują się te wartości i w ten sposób otrzymujesz kolor
Mikz
Kolor zapisywany w formacie szesnastkowym jest jako #xxxxxx
gdzie:
pierwsze XX oznacza ilość koloru czerwonego
drugie XX oznacza ilość koloru zielonego
trzecie XX oznacza ilość koloru niebieskiego

Każde XX to w formacie szesnastkowym od 0 do 255, gdzie 0 0 0 to czarny a 255 255 255 to biały. Biorąc pewne proste założenie, możemy stwierdzić że jeżeli średnia trzech kolorów daje nam więcej niż np. 100 to mamy tło jasne, inaczej mamy ciemne. Jednak jest to dosyć karkołomne, ponieważ są takie kolory tła na których dana czcionka wygląda źle mimo że według powyższego wzoru teoretycznie by pasowała.
Nie lepiej dać użytkownikowi możliwość wyboru koloru czcionki skoro może wybrać kolor tła?
renevaggio
Cytat(Mikz @ 1.07.2010, 14:26:44 ) *
Kolor zapisywany w formacie szesnastkowym jest jako #xxxxxx
gdzie:
pierwsze XX oznacza ilość koloru czerwonego
drugie XX oznacza ilość koloru zielonego
trzecie XX oznacza ilość koloru niebieskiego

Każde XX to w formacie szesnastkowym od 0 do 255, gdzie 0 0 0 to czarny a 255 255 255 to biały. Biorąc pewne proste założenie, możemy stwierdzić że jeżeli średnia trzech kolorów daje nam więcej niż np. 100 to mamy tło jasne, inaczej mamy ciemne. Jednak jest to dosyć karkołomne, ponieważ są takie kolory tła na których dana czcionka wygląda źle mimo że według powyższego wzoru teoretycznie by pasowała.
Nie lepiej dać użytkownikowi możliwość wyboru koloru czcionki skoro może wybrać kolor tła?



Też tak właśnie rozumuję. Użytkownik oczywiście ma też możliwość wyboru koloru czcionki, ale wiadomo jak to jest. Zaznaczy sobie źle, albo nie pomyśli, lub po prostu trafi blondynka i potem będą pisać do mnie z pretensjami że serwis ma błędy. Po prostu chcę zrobić takie "idioto-odporne" zabezpieczenie. Że jak ktoś da tło ciemne i da przez głupotę ciemną czcionkę to serwis to jeszcze ostatecznie zweryfikuje i poprawi.

Druga kwestia to taka że użytkownik może po prostu pominąć kwestię wyboru koloru czcionki i wtedy system będzie musiał sam podjąć decyzję.
yevaud
najlatwiej jest zanegowac bity w kolorze i juz masz czcionke kontrastowa - czasem tylko jest brzydka smile.gif
mozesz zrobic tak: zanegowac bity ~$kolor, a pozniej znalezc ten kolor z Twojej gotowej tablicy ladnych kolorkow, ktory jest najblizszy temu kontrastowemu
renevaggio
Cytat(yevaud @ 1.07.2010, 15:48:37 ) *
najlatwiej jest zanegowac bity w kolorze i juz masz czcionke kontrastowa - czasem tylko jest brzydka smile.gif
mozesz zrobic tak: zanegowac bity ~$kolor, a pozniej znalezc ten kolor z Twojej gotowej tablicy ladnych kolorkow, ktory jest najblizszy temu kontrastowemu



Można też tak zrobić, ale to jest rozwiązanie dość zaawansowane: zamiana hex na binarny, potem negacja, potem spowrotem na hex, potem szukanie najbliższego koloru ( nie wiem jak to zrealizować ). Dużo roboty po prostu.

Zresztą potestowałem przed chwilą negację kodu koloru na papierze ręcznie i powiem szczerze że nie wychodzi wcale kontrastowy. Po prostu tworzy się inny zupełnie kolor. Jak by "z minusowymi współrzędnymi" danego koloru w przestrzeni barw RGB.

---------------------------

Sposób opisany przez "Mikz" jest chyba najlepszy. Cały problem w tym że kod koloru jest złożony z 3 elementów. Gdyby było tak że kolory zapisane są od 1 do x i w tym 1 to najaśniejszy, a x najciemniejszy ( czyli kolory ułożone w linii jak kredki, a nie w przestrzeni x,y,z ) to wtedy wszystko było by git.

Napiszę taki skrypt, przetestuję i w razie czego podeślę na forum, gdyby ktoś miał jeszcze taki problem.
yevaud
jesli chcesz przeliczac kolory na jasnosc, to moim zdaniem lepiej niz zwykla srednia sprawdza sie odpowiednia srednia wazona, wylicz ja sobie z wzoru
Luma (Y’) = 0.299 R’ + 0.587 G’ + 0.114 B’
http://en.wikipedia.org/wiki/Luma_%28video%29
flashdev
Cytat(yevaud @ 1.07.2010, 15:48:37 ) *
najlatwiej jest zanegowac bity w kolorze i juz masz czcionke kontrastowa - czasem tylko jest brzydka smile.gif
[...]


Rzeczywiście, w szczególności gdy mamy do czynienia z kolorami: #7f7f7f - #808080 ph34r.gif


Najprostszy skuteczny sposób to zsumowanie składowych kolorów
Kod
sum = R + G + B;


A następnie wyświetlenie odpowiedniego koloru:
Kod
kolor = sum > 128*3 ? '#000' : '#fff';



Edit:
Inny sposób (być może lepszy) to wyliczenie średniej geometrycznej.

Kod
// obliczanie sredniej
aver = ( R^2 + G^2 + B^2 ) ^ (.5);

// normalizacja
norm = aver / (256^2 * 3)^(.5);

// warunek
if( round(norm) ){
// uzyj koloru ciemnego
}else{
// uzyj koloru jasnego
}
yevaud
Cytat(flashdev @ 2.07.2010, 01:07:31 ) *
Rzeczywiście, w szczególności gdy mamy do czynienia z kolorami: #7f7f7f - #808080 ph34r.gif

etam czepiasz sie winksmiley.jpg

w sumie to mysle ze jedyny dobry sposob to zrobienie tablicy mapujacej kolory
szukasz koloru o kodzie takim ze srednia odchylen skladowych RGB od koloru z mapy jest najmniejsza i rzutujesz na wybrany kolor
dodasz ze 20 kolorow do mapy i juz jest niezle, masz ladne kolorki, kontrastowe i nawet flashdev nie marudzi winksmiley.jpg
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.