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?

3 Antworten

Vom Beitragsersteller als hilfreich ausgezeichnet

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.


verreisterNutzer  28.12.2020, 17:24

Warte... Aber eine Gute Idee ...

0
max32168  28.12.2020, 17:31
@verreisterNutzer

Das ganze wäre dann ein Einzeiler:

def argb2scalar(a,r,g,b):
  return ( (a<<24) | (r<<16) | (a<<8) | b ) / (2**32-1)
0
max32168  28.12.2020, 17:47
@verreisterNutzer

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))
0
verreisterNutzer  28.12.2020, 18:05
@max32168
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...

0
max32168  28.12.2020, 18:14
@verreisterNutzer

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.

0
verreisterNutzer  28.12.2020, 18:17
@max32168

Ok.. könntest du so nett sein und mir vielleicht die ganze Funktion dann schicken? Danke! xD Achso ok ne hab es danke!

0
max32168  28.12.2020, 18:20
@verreisterNutzer

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))
0
Willibergi  28.12.2020, 17:50
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.

0

Teile einfach den Wert von jedem der 4 Variablen durch 255?


verreisterNutzer  28.12.2020, 17:09

Aber ich will einen Gesamtwert 1 nicht 4...

0
xxxcyberxxx  28.12.2020, 17:10
@verreisterNutzer
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?

0
verreisterNutzer  28.12.2020, 17:14
@xxxcyberxxx

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...

0
xxxcyberxxx  28.12.2020, 17:16
@verreisterNutzer
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)

0
verreisterNutzer  28.12.2020, 17:22
@xxxcyberxxx

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...

0
xxxcyberxxx  28.12.2020, 17:24
@verreisterNutzer

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 ...

0
verreisterNutzer  28.12.2020, 17:27
@xxxcyberxxx

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!

0
xxxcyberxxx  28.12.2020, 18:59
@verreisterNutzer
  1. ich meinte nicht 4 / SUMME, sondern SUMME / 4.
  2. 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 ...
0
xxxcyberxxx  28.12.2020, 19:02
@verreisterNutzer

joa, ist ein Weg. Wobei es, wie von ihm gesagt, nicht eindeutig ist, wenn du es auf 1 herunterrechnest

0

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.

Woher ich das weiß:Studium / Ausbildung – Studium und Promotion in Angewandter Mathematik

verreisterNutzer  28.12.2020, 17:23

Ja... aber argb soll zu 1 Wert übersetzt werden

0
ShimaG  28.12.2020, 17:41
@verreisterNutzer

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?

0
ShimaG  28.12.2020, 17:45
@verreisterNutzer

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!

0