Seite 1 von 1
Farbverlauf
Verfasst: Dienstag 16. Januar 2007, 15:36
von jmurauer
Hallo,
ich weiß zwar nicht, ob ich hier dafür richtig bin, aber vielleicht funktioniert es ja.
Ich muss einen Farbverlauf bauen. D.h. in einem canvas erzeuge ich Rechtecke und gehen denen eine Farbe mit fill = "#aabbcc" oder so weiter.
Mein Problem: ich möchte diese Farben den natürlichen, physikalschen Farben, so wie die von der Sonne kommen (ganz schwarz bis ganz weiß und dazwischen alle möglichen anderen Farben) nachbilden. D.h. so etwas wie das Auge die Wellenlänge "sieht".
Wenn ich annehme, meine Farbenzahle gehen von 0 bis 100, also von schwarz bis weiß, mit welchem Algo ordne ich sie dann dem fill-Wert zu?
Danke
Verfasst: Dienstag 16. Januar 2007, 17:56
von Arthur
ich würds in etwa so machen:
Code: Alles auswählen
for x in range[0, 265]:
root=Tk()
canvas=Canvas(root, width=100, height=256)
canvas.grid()
for x in range(0, 256):
y=list(hex(x))
y[:2]='' #pyhton hängt immer ein 0x for die hexadezimlae zahl, das muss weg
if len(y)==1:
y=['0']+y
a=''
for z in y: #Rückumwandelung in einen String
a=a+z
y=a
canvas.create_line(0, x, 100, x, fill='#'+y+y+y)
für andere farbmischungen musste am besten einen wert konstan lassen oder so
[/code]
So leider nicht
Verfasst: Dienstag 16. Januar 2007, 18:48
von jmurauer
Danke für die rasche Antwort, aber das war nicht das Problem - ich habe leider meine Frage sehr ungenau formuliert.
Es geht um so etwas wie die Farbtemperatur: Als Input habe ich eine Zahl (Farbtemperatur) und ich möchte den dazugehörigen Farbwert der Form #aabbcc ermitteln. Dann kann ich das Ding auch zeichnen.
In der Wikipedia findet man hier näheres
http://de.wikipedia.org/wiki/Farbtemperatur
Siehe dazu den färbigen Balken. Mein Input ist also z.B. 4000 (oder eine andere Zahl, die ich dann auf 4000 umrechnen) und ich möchte #aabbcc so, dass es eben dieses hellgelb ergibt.
Verfasst: Dienstag 16. Januar 2007, 19:53
von schlangenbeschwörer
Hi jmurauer,
gibt es da nur rot, gelb, weiß und blau?
Dann würde ich irgendwie die vier Farben Farbe definieren, zu jeder Farbe den Zahlenbereich in dem sie vorkommt(bei rot also 1800-4000), und dann gucken, in welchem Bereich der Wert liegt: Ist er z.B. 3000, musst du halt ne mischung zwischen dem gelb- und dem rot-wert berechnen. Falls du noch ein bisschen mit den Werten spielen möchtest, nimm doch einfach tkColorChooser, da kann man Werte oder Farbe einstellen, und erhält das andere.
Gruß, jj
ps:
jmurauer hat geschrieben:Siehe dazu den färbigen Balken. Mein Input ist also z.B. 4000 (oder eine andere Zahl, die ich dann auf 4000 umrechne[n]) und ich möchte #aabbcc so, dass es eben dieses hellgelb ergibt
--> oder willst du immer gelb rauskriegen?

Verfasst: Mittwoch 17. Januar 2007, 15:26
von HWK
Ich glaube, das könnte Dir helfen:
http://www.fourmilab.ch/documents/specrend/specrend.c. Ist zwar in C und sieht sehr komplex aus, es dürfte aber einfach sein, einen Python-Wrapper zu schreiben, der die RGB-Werte aus der Temperatur berechnet. Als Anleitung könnte die main()-Routine des Programms dienen.
MfG
HWK
Verfasst: Donnerstag 18. Januar 2007, 09:24
von jmurauer
Danke,
dass ist ein Volltreffer!!!
Verfasst: Donnerstag 18. Januar 2007, 17:48
von HWK
Das freut mich. Wenn Du den Code für den Farbverlauf fertig hast, wäre es schön, wenn Du ihn ins Forum stellen würdest. Mich interessiert das jedenfalls.
MfG
HWK
Verfasst: Freitag 19. Januar 2007, 22:12
von HWK
Ich hab's mal selbst probiert:
Die main()-Funktion von 'specrend.c' habe ich folgendermaßen ersetzt:
Code: Alles auswählen
int PASCAL __export colspec(int temp)
{
int t;
double x, y, z, r, g, b;
struct colourSystem *cs = &SMPTEsystem;
bbTemp = temp;
spectrum_to_xyz(bb_spectrum, &x, &y, &z);
xyz_to_rgb(cs, x, y, z, &r, &g, &b);
constrain_rgb(&r, &g, &b);
norm_rgb(&r, &g, &b);
t = (unsigned char)(255 * r);
t <<= 8;
t += (unsigned char)(255 * g);
t <<= 8;
t += (unsigned char)(255 * b);
return t;
}
Danach habe ich mit Watcom 'colspec.dll' erzeugt. Das Python-Script zum Testen sieht so aus:
Code: Alles auswählen
import ctypes
from Tkinter import *
class ShowColSpec:
def __init__(self, parent):
colspec = ctypes.WinDLL('colspec')
temp1 = 1000
temp2 = 10000
width = 1000
height = 100
canvas = Canvas(parent, width=width, height=height, bg='white')
canvas.pack(expand=YES, fill=BOTH)
for i in range(width + 1):
temp = i * (temp2 - temp1) / width + temp1
rgb = colspec.colspec(temp)
canvas.create_line(i, 0, i, height, fill='#%06X' % rgb)
if __name__ == '__main__':
root = Tk()
root.title('Farbspektrum')
ShowColSpec(root)
root.mainloop()
Die Ausgabe entspricht aber nicht wirklich den bekannten Farbspektren.
Schade eigentlich
HWK
Verfasst: Freitag 19. Januar 2007, 23:08
von HWK
Das sieht schon besser aus:
Ich habe zusätzlich folgende Funktionen eingefügt:
Code: Alles auswählen
void lambda_to_xyz(int lambda, double *x, double *y, double *z)
{
int i, j;
i = (lambda - 380) / 5;
j = (lambda - 380) % 5;
*x = (cie_colour_match[i + 1][0] * j + cie_colour_match[i][0] * (5 - j)) / 5;
*y = (cie_colour_match[i + 1][1] * j + cie_colour_match[i][1] * (5 - j)) / 5;
*z = (cie_colour_match[i + 1][2] * j + cie_colour_match[i][2] * (5 - j)) / 5;
}
int PASCAL __export colspec2(int lambda)
{
int t;
double x, y, z, r, g, b;
struct colourSystem *cs = &SMPTEsystem;
lambda_to_xyz(lambda, &x, &y, &z);
xyz_to_rgb(cs, x, y, z, &r, &g, &b);
constrain_rgb(&r, &g, &b);
norm_rgb(&r, &g, &b);
t = (unsigned char)(255 * r);
t <<= 8;
t += (unsigned char)(255 * g);
t <<= 8;
t += (unsigned char)(255 * b);
return t;
}
'colspec' wurde in 'colspec1' umbenannt.
Das Test-Script sieht dann so aus:
Code: Alles auswählen
import ctypes
from Tkinter import *
class ShowColSpec:
def __init__(self, parent):
colspec = ctypes.WinDLL('colspec')
lambda1 = 380
lambda2 = 779
temp1 = 1000
temp2 = 10000
width = 1000
height = 100
canvas = Canvas(parent, width=width, height=height, bg='white')
canvas.pack(expand=YES, fill=BOTH)
for i in range(width + 1):
temp = i * (temp2 - temp1) / width + temp1
rgb = colspec.colspec1(temp)
canvas.create_line(i, 0, i, height / 2, fill='#%06X' % rgb)
for i in range(width + 1):
lambda_ = i * (lambda2 - lambda1) / width + lambda1
rgb = colspec.colspec2(lambda_)
canvas.create_line(i, height / 2 + 1, i, height, fill='#%06X' % rgb)
if __name__ == '__main__':
root = Tk()
root.title('Farbspektrum')
ShowColSpec(root)
root.mainloop()
MfG
HWK
Verfasst: Samstag 20. Januar 2007, 01:26
von HWK
Und so geht es ganz einfach:
Code: Alles auswählen
#!/usr/bin/python
# File: colspec.py
# Script zur Darstellung eines Farbspektrums
from Tkinter import *
class ShowColSpec:
def __init__(self, parent):
height = 50
width = 6 * 256
canvas = Canvas(parent, width=width, height=height, bg='white')
canvas.pack(expand=YES, fill=BOTH)
for i in range(256):
canvas.create_line(i, 0, i, height, fill='#%02X00FF' % (255 - i))
for i in range(256):
canvas.create_line(i + 256, 0, i + 256, height,
fill='#00%02XFF' % i)
for i in range(256):
canvas.create_line(i + 512, 0, i + 512, height,
fill='#00FF%02X' % (255 - i))
for i in range(256):
canvas.create_line(i + 768, 0, i + 768, height,
fill='#%02XFF00' % i)
for i in range(256):
canvas.create_line(i + 1024, 0, i + 1024, height,
fill='#FF%02X00' % (255 - i))
for i in range(256):
canvas.create_line(i + 1280, 0, i + 1280, height,
fill='#FF00%02X' % i)
if __name__ == '__main__':
root = Tk()
root.title('Farbspektrum')
ShowColSpec(root)
root.mainloop()
MfG
HWK
Verfasst: Samstag 20. Januar 2007, 12:53
von HWK
Bei den letzten Varianten habe ich mich leider ganz auf die Ausgabe eines kompletten Spektrums konzentriert. Deshalb jetzt noch eine Variante, die für einen Indexwert die Farbe als RGB zurückliefert. Der Index liegt hier zwischen 0 und 1535, kann aber natürlich beliebig angepasst werden.
Code: Alles auswählen
#!/usr/bin/python
# File: ind2col.py
# Script zur Darstellung eines Farbspektrums
def ind2col(ind):
ind %= 6 * 256
i, j = divmod(ind, 256)
a = 0x10000 >> (8 * (i % 3))
if i & 1:
b = j
else:
b = 255 -j
c = 0xFF << (8 * (i / 2))
return a * b + c
if __name__ == '__main__':
from Tkinter import *
root = Tk()
root.title('Farbspektrum')
height = 50
width = 6 * 256 / 2
canvas = Canvas(root, width=width, height=height, bg='white')
canvas.pack(expand=YES, fill=BOTH)
for i in range(width):
canvas.create_line(i, 0, i, height, fill='#%06X' % ind2col(2 * i))
root.mainloop()
MfG
HWK