Hat jemand eine Idee wie ich ein ARGB Wert (A,R,G,B haben Zahl zwischen 0-255) zu einen Wert zwischen 0 und 1 übersetze, in Python?
Also ich möchte, wie oben genannt, einen ARGB Wert in einen einmaligen Wert zwischen 0-1 übersetzten. Also es soll für jeden Farbton und jeder Farbkonsistenz ein einmaliger Wert zwischen 0 und 1 geben. Habt ihr einen Idee wie ich das in Python3 anstelle?
3 Antworten
So wie ich das verstehe willst du einen Vektor (A,R,G,B) in ein Skalar s wandeln. Dabei sind A, R, G und B jeweils Integer im Bereich von 0 bis 255 und s ein Double von 0 bis 1.
Ich sehe nicht so richtig den Sinn dahinter. Vielleicht würde es helfen die konkrete Anwendung zu kennen. Das Problem ist, dass es zwischen 0 und 1 mehr Werte gibt als mögliche ARGB-Kombinationen. Somit funktioniert die eindeutige Umwandlung nur in eine Richtung.
Mein Vorschlag zur Umwandlung ist recht simpel. Du kannst den ARGB-Wert in einen Hex-Wert umrechnen. Somit wird aus (A,R,G,B) -> #aarrggbb.
Damit ergibt sich dann eine Zahl zwischen 0 und 2^32-1. Eine Umwandlung zwischen den beiden Formaten ist in beide Richtungen eindeutig. Möchtest du nun zwischen 0 und 1, dann musst du nur noch durch 2^32-1 teilen. Damit ist aber die Umwandlung rückwärst nicht mehr eindeutig.
Damit ist aber die Umwandlung rückwärst nicht mehr eindeutig.
Eindeutig schon, aber nicht jeder Wert zwischen 0 und 1 korrespondiert mit einer ARGB-Kombination. Oder in anderen Worten: Die Abbildung wäre injektiv (ein Wert wird nicht zweimal getroffen), aber nicht surjektiv (nicht jeder Wert wird getroffen) - d.h. allerdings, man könnte sie bijektiv einschränken.
Das ganze wäre dann ein Einzeiler:
def argb2scalar(a,r,g,b):
return ( (a<<24) | (r<<16) | (a<<8) | b ) / (2**32-1)
Und anders herum geht es auch. Aber ist wie gesagt nicht eindeutig.
def scalar2argb(s):
h = int( round( (2**32-1)*s, 1 ) )
return ( (h & 0xff000000)>>24, (h & 0x00ff0000)>>16, (h & 0x0000ff00)>>8, (h & 0x000000ff))
def argb2scalar(a,r,g,b):
return ( (a<<24) | (r<<16) | (a<<8) | b ) / (2**32-1)
Stop warte wo ist das g?? Heißt ja nicht AARB... g wird nicht benutzt...
copy-paste Fehler xD
(a<<8) muss natürlich (g<<8) sein.
Auch wenn du es nicht brauchst, aber beim umgekehrten muss round( (2**32-1)*s, 1 ) zu round( (2**32-1)*s, 0 ) geändert werden.
Ok.. könntest du so nett sein und mir vielleicht die ganze Funktion dann schicken? Danke! xD Achso ok ne hab es danke!
Das sind die ganzen Funktionen:
# wandelt RGBA-Farbwert in eine Zahl (Double) zwischen 0 und 1
# Eingangsvariablen sind Integer im Bereich von 0 bis 255
def argb2scalar(a,r,g,b):
return ( (a<<24) | (r<<16) | (g<<8) | b ) / (2**32-1)
# Umkehrfunktion zu argb2scalar()
# Eingangsvariable ist Double im Bereich von 0 bis 1
# Rückgabewert ist Tuple (a,r,g,b)
def scalar2argb(s):
h = int( round( (2**32-1)*s, 0 ) )
return ( (h & 0xff000000)>>24, (h & 0x00ff0000)>>16, (h & 0x0000ff00)>>8, (h & 0x000000ff))
Für meine KI brauche ich das... So kann ich Zeit und Rechenleistung sparen... :)
Teile einfach den Wert von jedem der 4 Variablen durch 255?
Aber ich will einen Gesamtwert 1 nicht 4...
Du meinst also, die Summe von A, R, G und B soll nicht 1 übersteigen?
Willst du dann einen einzigen Wert oder eben 4 verschiedene?
Nein ARGB soll zu 1 übersetztem Wert gemacht werden... Wie ist egal nur das jeder Farbton einen einzigartigen Wert zwischen 0 und 1 haben soll...
Wie ist egal nur das jeder Farbton einen einzigartigen Wert zwischen 0 und 1 haben soll...
und wie kommst du dann auf "Gesamtwert 4"?
Wenn jeder Farbton einen Wert zwischen 0 und 1 haben darf und momentan zwischen 0 und 255 sein kann, musst du diesen - wie von mir schon gesagt - einfach nur durch 255 teilen.
ARGB von (42, 0, 255, 128) wird dann eben in etwa zu (0.1647, 0.0, 1.0, 0.5020)
Jaha aber ARGB soll zu EINEM WERT ÜBERSETZT WEREN ZU 11! Das hier ist praktisch eine Liste (0.1647, 0.0, 1.0, 0.5020) aber KEIN 1 Wert. Das ganze ARGB zu 1 Wert...
Also doch irgendwas summiert. Gib doch mal die genaue Aufgabenstellung. Das ganze macht so wenig Sinn, wie du es erzählst.
Sonst: Summier dooch einfach alle vier Kanäle zusammen und teile den Wert durch 4? Egal, welchen Wert die einzelnen Kanäle haben, diese Summe ist dann nicht größer als 1 ...
Dann ist aber 4/(40+30+172+255) GENAU SO GROSS wie 4/(70+100+122+205). Nur als Beispiel, obwohl das VÖLLIG VERSCHIEDENE FARBEN SIND!
- ich meinte nicht 4 / SUMME, sondern SUMME / 4.
- natürlich. du bekommst durch reines Aufsummieren - auch wenn es gewichtet wäre - mehrere Möglichkeiten, wie dieser Wert zustandekommen könnte. Deswegen nimmt man eben nicht EINEN Wert für alle 4 Kanäle, sondern einen Wert pro Kanal ...
Guck mal nach oben zu Max... Der hat ne tolle Lösung dafür gefunden
joa, ist ein Weg. Wobei es, wie von ihm gesagt, nicht eindeutig ist, wenn du es auf 1 herunterrechnest
Mit ist zwar nicht klar, warum man das machen will, aber warum teilst du nicht den ARGB-Wert, der ja zwischen 0 und 2^32-1 liegt, nicht einfach durch 2^32-1? Dann liegt der Wert definitiv zwischen 0 und 1, Grenzen eingeschlossen.
Naja, wird er dann ja. Ein ARGB-Wert ist ein 32-Bit-Wert mit den besagten Werten.
Wenn du das nicht so berechnen willst, kannst du auch folgendermassen rechnen: Seien a, r, g, b jeweils die Kanäle deines Farbwerts mit Werten zwischen 0 und 255. Dann berechne
x = (a * 2^24 + r * 2^16 + g * 2^8 + b) / (2^32 - 1)
Das ist dein gesuchter Wert zwischen 0 und 1.
Aber wie gesagt: Den als einzelnen Wert darstellen zu wollen ist irgendwie komisch; was ist deine Anwendung dafür?
Guck mal bei Max... Er hat eine gute Lösung dafür gefunden
Er hat... die gleiche Lösung gefunden, tippt aber schneller! :-)
Du bist uns beiden aber noch die Beschreibung deiner Anwendung schuldig geblieben. Lass uns bitte nicht dumm sterben!
Warte... Aber eine Gute Idee ...