- LiFePO4 Speicher Test         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 63

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

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    11.12.2007
    Ort
    weit weg von nahe Bonn
    Alter
    40
    Beiträge
    3.416
    im zweifelsfall mit pointer

    Code:
    void Color16bit2RGB(uint16_t color16, uint8_t* R, uint8_t* G, uint8_t* B) {
    
       *R = (uint8_t)((0b1111100000000000 & color16) >> 11);
       *G = (uint8_t)((0b0000011111100000 & color16) >> 5);
       *B = (uint8_t)((0b0000000000011111 & color16));
    }
    muss gestehen dass ich solche reference calls meide, weils mir leicht spanisch ist
    pointer sind für mich persönlich einfacher zu handhaben

    beim aufruf musst du dann natürlich dioe adressen auflösen

    Code:
    uint8_t myR,myG,myB;
    Color16bit2RGB(some16bitColor, &myR, &myG, &myB);
    printf("<font color=\"#%00h%00h%00h\">",myR,myG,myB);

    PS: ich habe die einzelnen farben mal auf 8 bit reduziert und einen expliziten cast mit eingebaut damit alles sauber aussieht
    Es gibt 10 Sorten von Menschen: Die einen können binär zählen, die anderen
    nicht.

  2. #2
    HaWe
    Gast
    danke für die Mühe!
    Ich muss allerdings auch etwas gestehen...: dass mir das mit diese Pointern mit * und dann doch wieder & im Hauptprogramm noch viel unklarer ist, mit Pointer hin und vorher und hinterher referenzieren oder dereferenzieren oder wie auch immer das heißt - wenn möglich würde ich lieber eindeutige Variablennamen im Hauptprogramm verwenden, die dann per Referenz übergeben werden und auf die man dann nach Ende der Funktion wieder als aktuaisierte Werte per Variabennamen zugreifen kann.
    Aber auch da komme ich immer ins Schleudern. Hatte gehofft, das könnte irgendwer aus dem Stegreif...

    so, nochmal getestet - das mit dem "&" klappt...
    Rest nochmal in Arbeit...



    funktioniert noch nicht ganz perfekt...

    - - - Aktualisiert - - -

    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)((0b1111100000000000 & color16) >> 11);
       G = (uint8_t)((0b0000011111100000 & color16) >> 5);
       B = (uint8_t)((0b0000000000011111 & color16));
       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;               // Dark Pink (255,102,78)
    
    
       Serial.begin(115200);
       
       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 Einzelwerte dann 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:
    
    }
    Ausgabe:

    Hauptprogramm vor Aufruf:
    col16=0
    r=255
    g=102
    b=78

    Hauptprogramm nach rgb zu col16-Berechnung (rgb Einzelwerte dann gelöscht):
    col16=64718
    r=0
    g=0
    b=0

    Unterprogramm color16 zu RGB:
    color16=64718
    R=31
    G=38
    B=14

    Hauptprogramm nach col16 zu rgb:
    col16=64718
    r=31
    g=38
    b=14
    Geändert von HaWe (10.09.2018 um 12:29 Uhr)

  3. #3
    HaWe
    Gast
    kann es sein, dass die zurück-Richtung clolor16 => r,g,b nicht richtig rechnet? Zumindest schein es so nach direkter Kontrolle der (lokalen) Rechenschritte
    R = (uint8_t)((0b1111100000000000 & color16) >> 11);
    G = (uint8_t)((0b0000011111100000 & color16) >> 5);
    B = (uint8_t)((0b0000000000011111 & color16));

    denn die geben ja andere Ergebnisse als die hinwärts-Richtung r,g,b => color16:


    die hinwärts-Richtung ermittelt ja aus den 3 rgb-Werten
    r=255
    g=102
    b=78
    die color16-Zahl 64718

    die Rückwärts-Funktion dann aber aus color16=64718
    die (abweichenden) rgb-Werte
    R=31
    G=38
    B=14

    Hatte ich etwas falsch c+p'tet ?

  4. #4
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    11.12.2007
    Ort
    weit weg von nahe Bonn
    Alter
    40
    Beiträge
    3.416
    Sorry dass ich nicht früher antworten konnte, hatte nicht viel gelegenheit überhaupt mal länger als 5 Minuten ins Forum zu schauen.

    Mir ist da ein Denkfehler passiert, bei der Rückrechnung der einzelnen Komponenten stimmt zumindest schonmal deine Formel, bei der Umrechnung von Komponenten auf RGB16 allerdings ist rigendwas schief, da komme ich auf einen anderen Wert.

    Der primäre Denkfehler liegt jedoch beim Rückrechnen von RGB16 auf R G B

    G wird hier mit 6Bit aufgelöst, also müsste man streng genommen >> 6 statt >> 5 machen ... was allerdings der größte Denkfehler von mir war ... die Werte sind doch nur 5 bzw. 6Bit groß und müssten ja nochmal auf 8Bit aufgeblasen werden (inklusive eines Verlust der Auflösung selbsttverständlich)

    Und ich glaube beim Maskieren und schieben ist auch noch ein dreher drinne ... ich habe immer die MSB ausmaskiert und da kann nur blödsinn bei rauskommen XD

    Ich versuche heute Nachmittag mal eine Korrektur, da ich jetzt noch was wegschaffen muss bevor hier alles abbrennt
    Es gibt 10 Sorten von Menschen: Die einen können binär zählen, die anderen
    nicht.

  5. #5
    HaWe
    Gast
    besten Dank schon im vorraus - mach dir aber keinen Stress, es ist absolut nicht eilig, es hatte mich nur stutzig gemacht!

  6. #6
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    18.03.2018
    Beiträge
    2.650
    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

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

  8. #8
    HaWe
    Gast
    ja, ich habe ja schon mal einen Benchmarktest für verschiedene MCUs geschrieben, könnte ich mal machen



    - - - Aktualisiert - - -

    edit: Code aktualisiert nach Ceos' Einwand (s.u.!)

    Code:
    #define TimerMS() millis()  //for  cross plattform compatib
    uint32_t time0;
    
    long test_Int_multdiv2() {
      uint32_t  x,y;
      volatile uint32_t  s;
    
      for(y=0;y<10000;y++) {
        s=11;
        for(x=1;x<=16;x++) { s*=2;}
        for(x=16; x>0;x--) { s/=2;}
        s=7;
        for(x=1;x<=8;x++) { s*=8;}
        for(x=8; x>0;x--) { s/=8;}
      }
      return s;
    }
    
    
    long test_Int_shl_shr() {
      uint32_t  x,y;
      volatile uint32_t  s;
    
      for(y=0;y<10000;y++) {
        s=11;
        for(x=1;x<=16;x++) { s=(s<<1);}
        for(x=16; x>0;x--) { s=(s>>1);}
        s=7;
        for(x=1;x<=8;x++) { s=(s<<3);}
        for(x=8; x>0;x--) { s=(s>>3);}
      }
      return s;
    }
    
    
    // *SNIP*
    
    
      time0=TimerMS();
      s=test_Int_multdiv2();
      runtime[0]=TimerMS()-time0;
      sprintf (buf, "%3d %9ld  Int_multdiv2",   0, runtime[0]); Serial.println( buf);
    
    
     time0=TimerMS();
      s=test_Int_shl_shr();
      runtime[1]=TimerMS()-time0;
      sprintf (buf, "%3d %9ld  Int_shl_shr",   1, runtime[1]); Serial.println( buf);
    Ergebnis: doch identisch, anders als vermutet (Angaben in ms):


    Plattform: AVR (Arduino Mega2560, 16 MHz)
    Code:
    start test
      0      1220  Int_multdiv2
      1      1220  Int_shl_shr


    Plattform: ARM Cortex M0 (Adafruit Itsybitsy M0, 48 MHz)
    Code:
    start test
      0        93  Int_multdiv2
      1        93  Int_shl_shr


    Plattform: ARM Cortex M3 (Arduino Due, 84MHz)
    Code:
    start test
      0        49  Int_multdiv2
      1        49  Int_shl_shr


    Pattform: ESP8266 (nodeMCU, Xtensa LX106, 80 MHz)
    Code:
    start test
    start test
      0        56  Int_multdiv2
      1        55  Int_shl_shr
    edit:
    gleiches Ergebnis auch für Zuweisung an 2. Variable:
    Code:
    long test_Int_multdiv2() {
      uint32_t  x,y;
      volatile uint32_t  s,t;
    
      for(y=0;y<10000;y++) {
        s=11;
        for(x=1;x<=16;x++) { t=s*2;}
        for(x=16; x>0;x--) { t=s/2;}
        s=7;
        for(x=1;x<=8;x++) { t=s*8;}
        for(x=8; x>0;x--) { t=s/8;}
      }
      return s;
    }
    
    
    long test_Int_shl_shr() {
      uint32_t  x,y;
      volatile uint32_t  s,t;
    
      for(y=0;y<10000;y++) {
        s=11;
        for(x=1;x<=16;x++) { t=(s<<1);}
        for(x=16; x>0;x--) { t=(s>>1);}
        s=7;
        for(x=1;x<=8;x++) { t=(s<<3);}
        for(x=8; x>0;x--) { t=(s>>3);}
      }
      return s;
    }
    Geändert von HaWe (12.09.2018 um 18:29 Uhr)

  9. #9
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    11.12.2007
    Ort
    weit weg von nahe Bonn
    Alter
    40
    Beiträge
    3.416
    hey moment mal, du schummelst doch :P

    mach mal aus (s << 1) ein s = (s << 1) bzw. 3 natürlich, du schiebst hier eine zahl aber sie wird nicht gespeichert, wenn dem so ist optimiert er den inhalt der schleife wahrscheinlich einfach weg und du hast nur eine leere schleife gemessen

    bei der multiplikation und division machst du ja auch eine zuweisung

    EDIT: by the way hab cih das mit dem barrel shifter wohl falsch verstanden, den gibt es wohl für links als auch für rechts, aber atmel benutzt beim rsr scheinbar nicht immer den barrel shifter, das warum hat sich mir aus den bisherigen topics nicht wirklich erscshlossen, aber es scheint wohl ein bekanntes phänomen zu sein (primär englische atmel foren die sich mit komplexerer verwendung beschäftigen und nciht mit so trivialen tests)
    Es gibt 10 Sorten von Menschen: Die einen können binär zählen, die anderen
    nicht.

  10. #10
    HaWe
    Gast
    hey moment mal, du schummelst doch :P
    kleiner Aufmerksamkeitstest

    ich korrigiere es sofort!

    edit:
    Korrektur, sind doch immer jeweils identisch, ist oben korrigiert!

Seite 1 von 2 12 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
  •  

fchao-Sinus-Wechselrichter AliExpress