- Labornetzteil AliExpress         
Seite 2 von 7 ErsteErste 1234 ... LetzteLetzte
Ergebnis 11 bis 20 von 63

Thema: Farben nach R,G,B umwandeln in 4-stell. hex-code?

  1. #11
    HaWe
    Gast
    Anzeige

    Powerstation Test
    besten Dank schon im vorraus - mach dir aber keinen Stress, es ist absolut nicht eilig, es hatte mich nur stutzig gemacht!

  2. #12
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    18.03.2018
    Beiträge
    2.645
    Code:
    Das mit dem Konvertieren der Farben ist so eine Sache, das kann man machen, es kommt aber nicht unbedingt das gewünschte Ergebnis heraus. Da die Farbgewichtung auch eine Rolle spielt. Ohne das weiter kompliziert zu machen, kommt es bei der einfachen Farbanpassung per Logikoperatoren teils zu falschen Farbdarstellungen beim Ziel. Das sollte man nur mal so im Hinterkopf haben. 
    Ansonsten ist RGB-5-6-5, 5Bit für Rot, 6Bit für Grün und 5Bit für Blau. 
    Bei RGB-8-8-8, jeweils 8Bit für eine Farbe. 
    
    RGB 8-8-8: 11111111-11111111-11111111
    RGB 5-6-5: xxx11111-xx111111-xxx11111
    
    Schiebe die ersten 8 Bit nach rechts, um 3 Stellen.
    Schiebe die zweiten 8 Bit nach rechts, um 2 Stellen.
    Schiebe die dritten 8 Bit nach rechts, um 3 Stellen.
    
    int rot1 = rot/8; int gruen1 = gruen/4; int blau1 = blau/8;
    
    Das Problem dabei: Grün ist anders gewichtet, das kann sich in einem Grünstich des Bildes bemerkbar machen.
    
    Rückwärts geht es genau andersrum:
    
    Schiebe die ersten 5 Bit nach links, um 3 Stellen.
    Schiebe die zweiten 6 Bit nach links, um 2 Stellen.
    Schiebe die dritten 5 Bit nach links, um 3 Stellen.
    
    int rot = rot1*8; int gruen = gruen1*4; int blau = blau1*8;
    
    --------------------------
    
    Die einzelnen Farben aus rgb-8-8-8 nach rgb-5-6-5:
    
    r = rgb888/524288;
    g = (rgb888/1024)&63;
    b = (rgb888/8)&31;
    
    Ganze RGB-Werte umrechnen:
    
    rgb565 =  ((  ((rgb888/524288)*64) | ((rgb888/1024)&63)  )*32) | ((rgb888/8)&31);
    
    10111000 10101100 10101000 =>  ((1472 | 43) * 32) | 21 => 1011110101110101
    
    und zurück (als Probe):
    
    rgb888 = ((rgb565 & 63488) * 256) | ((rgb565 & 2016) * 32) | ((rgb565 & 31) * 8)
    
    1011110101110101 => (12058624 | 44032) | 168 => 10111000 10101100 10101000

  3. #13
    HaWe
    Gast
    danke für den Post!
    ich habe jetzt neu codiert:
    Code:
    uint16_t ColorRGB216bit(uint16_t R, uint16_t G, uint16_t B) {
    
       return  ((uint16_t)R << 11) | (((uint16_t)G << 5) & 0b0000011111100000) | ((uint16_t)B & 0b0000000000011111);
    }
    
    
    void Color16bit2colorRGB(uint16_t color16, uint16_t &R, uint16_t &G, uint16_t &B) {
    
       R = (uint8_t)(color16/524288);
       G = (uint8_t)(color16/1024);
       B = (uint8_t)((color16/8)&31);
       Serial.println("");
       Serial.println("Unterprogramm color16 zu RGB:");
       Serial.println( (String)"color16="+(String)color16);
       Serial.println( (String)"R="+(String)R);
       Serial.println( (String)"G="+(String)G);
       Serial.println( (String)"B="+(String)B); 
    }
    
    void setup() {
      // put your setup code here, to run once:
    
       uint16_t r=255, g=102, b=78, 
                col16=0;               // 0xFF66B2;  // Dark Pink (255,102,78)
    
    
       Serial.begin(115200);
       delay(3000);
       
       Serial.println("Hauptprogramm vor Aufruf:");
       Serial.println( (String)"col16="+(String)col16);
       Serial.println( (String)"r="+(String)r);
       Serial.println( (String)"g="+(String)g);
       Serial.println( (String)"b="+(String)b);
       Serial.println("");
       
       col16=ColorRGB216bit(r,g,b);
       r=g=b=0; // Rücksetzen!
    
       Serial.println("Hauptprogramm nach rgb zu col16-Berechnung (rgb gelöscht):");
       Serial.println( (String)"col16="+(String)col16);
       Serial.println( (String)"r="+(String)r);
       Serial.println( (String)"g="+(String)g);
       Serial.println( (String)"b="+(String)b);
       
       Color16bit2colorRGB(col16, r, g, b);
       Serial.println("");
       Serial.println("Hauptprogramm nach col16 zu rgb:");
       Serial.println( (String)"col16="+(String)col16);
       Serial.println( (String)"r="+(String)r);
       Serial.println( (String)"g="+(String)g);
       Serial.println( (String)"b="+(String)b);   
        
    }
    
    void loop() {
      // put your main code here, to run repeatedly:
    
    }
    und bekomme jetzt den output:
    Code:
    Hauptprogramm vor Aufruf:
    col16=0
    r=255
    g=102
    b=78
    
    Hauptprogramm nach rgb zu col16-Berechnung (rgb gelöscht):
    col16=64718
    r=0
    g=0
    b=0
    
    Unterprogramm color16 zu RGB:
    color16=64718
    R=0
    G=63
    B=25
    
    Hauptprogramm nach col16 zu rgb:
    col16=64718
    r=0
    g=63
    b=25
    hmmmm...

  4. #14
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    18.03.2018
    Beiträge
    2.645
    Code:
    G = (uint8_t)(color16/1024);
    
    muss, wenn dann so:
    
    G = (uint8_t)(color16/1024)&63;
    Allerdings schreibst Du "color16". sind das als Quelle 16Bit-Farben? RGB-8-8-8 sind 24Bit-Farben. RGB-5-6-5 sind 16Bit-Farben.

  5. #15
    HaWe
    Gast
    ja, es handelt sich immer um die 16-bit Zahlen
    r,g,b haben immer die volle range von 0-255, die dann nur anders in die 16- bzw. auch optional 24-bit oder 32-bit truecolor umkodiert werden sollen.

  6. #16
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    18.03.2018
    Beiträge
    2.645
    Ich hatte gelesen, Du schriebst, dass nicht so einfach ist, wie in HTML - Farben für Webseiten. Die sind dort 8bit-8bit-8bit (style="color:#452f63"), 45h - 2fh - 63h. Macht 24Bit.

    Von welchem Farbformat, nach welchem muss es denn?

    "r,g,b haben immer die volle range von 0-255, die dann nur anders in die 16- bzw. auch optional 24-bit oder 32-bit truecolor umkodiert werden sollen."

    Dann ist es 8-8-8 nach 5-6-5. Wo ist der Fehler?

    Code:
    sinngemäß wäre so richtig:
    
    G = (uint8_t)(color24/1024)&63;
    Allerdings kann man die 24Bit-Farbe natürlich nur in ein 32Bit-Register packen. Um in einem Stück zu rechnen.
    Dumm gelaufen, wenn der Arduino nur 16Bit-Register hat Vor Jahren noch hätte ich das jetzt einfach auf 16Bit-Operationen aufgeteilt, als ich noch in Übung war. So muss ich nochmal drüber nachdenken.

    Nachtrag:

    Vorher war der ganze 24Bit-Farbwert: rgb888

    Wenn die Farbwerte einzeln vorliegen, ist es so, wie ich Anfangs schrieb:

    int rot1 = rot/8; int gruen1 = gruen/4; int blau1 = blau/8;

    So wird aus Rot mit 8 Bit, Rot mit 5 Bit, aus Grün mit 8 Bit, wird Grün mit 6 Bit, aus Blau mit 8 Bit, wird Blau mit 5 Bit.
    Geändert von Moppi (10.09.2018 um 12:36 Uhr)

  7. #17
    HaWe
    Gast
    also noch mal von vorn:
    r,g,b-Werte sind ja als Vorgabe universell,
    weiß ist immer (255, 255,255)
    und rot immer (255,0,0 )
    und "Dark Pink" z.B. (255,102,78 ) etc.

    in html habe ich meist 24-bit, das ist einfach: color24 = (r<<16)+(g<<8 )+b

    hier geht es aber jetzt um die color16 - Kodierung (hin und zurück).

  8. #18
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    18.03.2018
    Beiträge
    2.645
    Demnach müsste es so sein, von R,G,B Einzelwerten zu 16Bit-Werten:

    Code:
    rgb =  ((rot/8)*2048) | ((grün/4)*32) | (blau/8);
    und zurück müsste dann so sein:

    Code:
    rot = (rgb/2048)*8; 
    grün = (rgb&2016)/8;
    blau = (rgb&31)*8;
    Geändert von Moppi (10.09.2018 um 13:09 Uhr)

  9. #19
    HaWe
    Gast
    hast du das mal selber getestet? Ich hatte doch den Arduino Code gepostet...
    Code:
    uint16_t ColorRGB216bit(uint16_t R, uint16_t G, uint16_t B) {
    
       return  ((R/8)*2048) | ((G/4)*32) | (B/8);
    }
    
    
    void Color16bit2colorRGB(uint16_t color16, uint16_t &R, uint16_t &G, uint16_t &B) {
    
       R = (uint8_t)(color16 / 2048)*8;
       G = (uint8_t)(color16 & 2016)/8;
       B = (uint8_t)(color16 &31)*8;
       Serial.println("");
       Serial.println("Unterprogramm color16 zu RGB:");
       Serial.println( (String)"color16="+(String)color16);
       Serial.println( (String)"R="+(String)R);
       Serial.println( (String)"G="+(String)G);
       Serial.println( (String)"B="+(String)B); 
    }
    
    void setup() {
      // put your setup code here, to run once:
    
       uint16_t r=255, g=102, b=78, 
                col16=0;               // 0xFF66B2;  // Dark Pink (255,102,78)
    
    
       Serial.begin(115200);
       delay(3000);
       
       Serial.println("Hauptprogramm vor Aufruf:");
       Serial.println( (String)"col16="+(String)col16);
       Serial.println( (String)"r="+(String)r);
       Serial.println( (String)"g="+(String)g);
       Serial.println( (String)"b="+(String)b);
       Serial.println("");
       
       col16=ColorRGB216bit(r,g,b);
       r=g=b=0; // Rücksetzen!
    
       Serial.println("Hauptprogramm nach rgb zu col16-Berechnung (rgb gelöscht):");
       Serial.println( (String)"col16="+(String)col16);
       Serial.println( (String)"r="+(String)r);
       Serial.println( (String)"g="+(String)g);
       Serial.println( (String)"b="+(String)b);
       
       Color16bit2colorRGB(col16, r, g, b);
       Serial.println("");
       Serial.println("Hauptprogramm nach col16 zu rgb:");
       Serial.println( (String)"col16="+(String)col16);
       Serial.println( (String)"r="+(String)r);
       Serial.println( (String)"g="+(String)g);
       Serial.println( (String)"b="+(String)b);   
        
    }
    
    void loop() {
      // put your main code here, to run repeatedly:
    
    }

    ergibt:
    Code:
    Hauptprogramm vor Aufruf:
    col16=0
    r=255
    g=102
    b=78
    
    Hauptprogramm nach rgb zu col16-Berechnung (rgb gelöscht):
    col16=64297
    r=0
    g=0
    b=0
    
    Unterprogramm color16 zu RGB:
    color16=64297
    R=248
    G=4
    B=72
    
    Hauptprogramm nach col16 zu rgb:
    col16=64297
    r=248
    g=4
    b=72
    Teste doch bitte mal selber, sei so nett...

  10. #20
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    18.03.2018
    Beiträge
    2.645
    Ich guck mal, ob noch ein Fehler drin ist.

    Hier mal die Hin-Rechnung:

    Code:
    r=255, g=102, b=78
    
    r=11111111, g=01100110, b=01001110
    
    muss ergeben: 11111 011001 01001 = 64297
    
    rgb =  ((rot/8)*2048) | ((grün/4)*32) | (blau/8);
    
    rgb     = 11111 000000 00000 
            | 00000 011001 00000 
            | 00000 000000 01001
            --------------------
              11111 011001 01001
    
            = 64297
    und das Ganze zurück:

    Code:
    rgb = 64297;
    
    rot = (rgb/2048)*8;     =>      11111000   => 248
    grün = (rgb&2016)/8;    =>      01100100   => 100
    blau = (rgb&31)*8;      =>      01001000   => 72
    So weit ich das sehe, ist das richtig so, wenn ich die Bitmuster vergleiche.

    Mit den Werten Rot=248, Grün=100 und Blau=72 müsste das Hin und Zurück dann stimmen.
    Auf die Originalwerte kann man nicht kommen, weil man 24Bit-Farbe auf 16Bit-Farbe komprimiert, das ist verlustbehaftet - die unteren Bits gehen hier verloren und können nicht rekonstruiert werden. 16Bit-Farben haben einen kleineren Farbraum als 24Bit-Farben.

    Allerdings benötigt man für diese Berechnungen:
    Code:
    rot = (rgb/2048)*8; ... etc.
    16 Bit. Die Berechnung muss mit 16 Bit stattfinden und dann am Ende könnte man auf 8 Bit umwandeln, weil im Ergebnis nur noch die unteren 8 Bit der Berechnung belegt sind.

    Ich denke Dein Problem liegt hier:
    Code:
    R = (uint8_t)(color16 / 2048)*8;
    sieht für mich so aus, als ob die gesamte Berechnung mit 8 Bit durchgeführt werden soll(!?).

    Eventuell so besser (ohne jede Gewähr):
    Code:
    (uint8_t) R = (color16 / 2048)*8;
    Weiß ich aber nicht, weil ich diese sprachspezifischen Sachen hier nicht gut so kenne. Aber ich denke, Du weißt, was ich meine.

    Oder mach es so:

    Code:
    int R = (color16 / 2048)*8;
    Die obersten 8 Bit sind nach erfolgter Berechnung sowieso nicht belegt. Normalerweise switcht man auch zwischen den Datentypen nicht so oft hin und her. Das dürfte Zeit kosten, wenn aus 16 Bit-Operanden 8 Bit-Operanden gemacht werden und umgekehrt. Da sind bestimmt unnütze Operationen, die der Compiler für Dich einbaut. Ich würde es bei den Datentypen für die Farben immer bei 16 Bit belassen. Vielleicht kann man das später aus Platzgründen optimieren, aber erst mal sollte man schauen, dass es funktioniert.
    Geändert von Moppi (10.09.2018 um 16:34 Uhr)

Seite 2 von 7 ErsteErste 1234 ... LetzteLetzte

Ähnliche Themen

  1. String nach Array umwandeln (?)
    Von slavezero im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 3
    Letzter Beitrag: 07.06.2012, 17:21
  2. Chips die nach Seriell umwandeln
    Von dundee12 im Forum Elektronik
    Antworten: 13
    Letzter Beitrag: 12.08.2010, 09:08
  3. word nach byte umwandeln
    Von magic33 im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 10
    Letzter Beitrag: 21.02.2007, 16:04
  4. C-Code in hex umwandeln
    Von elkokiller im Forum C - Programmierung (GCC u.a.)
    Antworten: 2
    Letzter Beitrag: 16.02.2006, 09:41
  5. PAL-Videosignal irgendwie nach seriell umwandeln?
    Von Trabukh im Forum Elektronik
    Antworten: 39
    Letzter Beitrag: 14.09.2005, 13:15

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

12V Akku bauen