Farbanteile berechnen



  • Phisherman schrieb:

    @kpeter: Das Makro hilft mir nicht weiter. Ich verfüge nicht über das Wissen dieses zu verwenden.

    Es ist aber genau das was du suchst. Schau mal ins Archiv.

    Ok, mal ein Bsp:

    DWORD farbe = 1234567;
        int r = GetRValue(farbe);
        int g = GetGValue(farbe);
        int b = GetBValue(farbe);
        TColor clRot   = (TColor) RGB(r, 0 ,0);
        TColor clGruen = (TColor) RGB(0, g ,0);
        TColor clBlau  = (TColor) RGB(0, 0 ,b);
    


  • Dass ich die Farbanteile aus dem TColor-Wert ausrechnen kann, wusste ich nicht. Das war meine Frage. Die Frage, die sich jetzt ergibt ist, wie ich das machen kann (ohne Makro). Bitoperationen scheinen mir auch nicht das Richtige zu sein. Es muss noch eine andere Möglichkeit geben. Damit meine ich keine Kompliziertere.



  • Phisherman schrieb:

    Die Frage, die sich jetzt ergibt ist, wie ich das machen kann (ohne Makro).

    s. Posting akari



  • Phisherman schrieb:

    Bitoperationen scheinen mir auch nicht das Richtige zu sein

    Der Schein trügt...



  • Es ist eine Zusatzaufgabe aus meinem Unterricht. Wir haben Bitoperatoren und Makros noch nicht behandelt. Insofern sollte es auch anders gehen.

    @kpeter: Danke für das Beispiel. Verständlich. Es funktioniert jetzt zwar, aber so richtig verstehe ich es nicht. Wieso sind diese Makros nicht in der Hilfe verzeichnet? Nun bin ich doch neugierig geworden.



  • Phisherman schrieb:

    Es ist eine Zusatzaufgabe aus meinem Unterricht. Wir haben Bitoperatoren und Makros noch nicht behandelt. Insofern sollte es auch anders gehen.

    Wie schon gesagt geht es natürlich auch anders. Anders bedeutet in dem Fall aber auch komplizierter, potentiell ineffizienter und weniger portabel. Bitoperationen sind hier der einzig sinnvolle Weg.



  • Alles klar, danke!
    Auch wenn ich meines Erachtens die Aufgabe nicht "richtig" gelöst habe. Aber dafür könnt ihr ja nichts. Naja, noch 3 Tage Ferien. Dann frage ich die Lehrkraft nach der richtigen Lösung und werde diese dann hier präsentieren.



  • Klar gehts auch ohne Bitoperationen:

    eine Bitweise verschiebung um x nach rechts z.B. ist
    gleichzusetzen einer Division durch 2^x.
    d.h. statt

    ((BYTE)(((WORD)(rgb)) >> 8))
    

    kannst du auch

    ((BYTE)(((WORD)(rgb)) / 256 ))
    

    schreiben.



  • Habt Ihr Unions schon behandelt. Damit könnte man das auch lösen 😉



  • MichelRT schrieb:

    Habt Ihr Unions schon behandelt. Damit könnte man das auch lösen 😉

    Das funktioniert zwar in den mir bekannten Fällen zu 100%, ist aber streng genommen nicht erlaubt und erzeugt undefiniertes Verhalten.

    @Phisherman:
    Der einzig vernünftige Weg sind Bitoperationen. Wenn du das nicht kannst bzw. noch nicht behandelt wurde dann probier´s einfach aus. Schreib´ eine kleine Anwendung zum rumprobieren und guck mal, was verschiedene Operationen/Verschiebungen bewirken. Obwohl die meisten online C++ Tutorials schwach sind sollte dieses Thema ausreichend erlärt werden.



  • DocShoe schrieb:

    Das funktioniert zwar in den mir bekannten Fällen zu 100%, ist aber streng genommen nicht erlaubt und erzeugt undefiniertes Verhalten.

    Wer sagt das? Was ist daran undefiniert?



  • Hallo

    Es ist undefiniert weil im Standard für unions folgende Beschränkung gilt : Es darf nur dann ein Member des Unions ausgelesen werden, wenn dieser Member auch als letztes beschrieben wurde. Du darfst zwar folgenden union definieren

    union c
    {
      __int32 a;
      __int8 b[4];
    };
    

    und du darfst laut Standard (in dieser Reihenfolge)
    1. einen Wert in a speichern
    2. einen Wert in b speichern
    3. einen Wert aus b auslesen.
    Aber der Standard definiert nicht das Verhalten, wenn du Schritt 2 ausläßt. union wurde nicht als Konvertiercheat eingeführt, sondern um Speicherverbrauch zu reduzieren. Meistens wird der Konvertiercheat funktionieren, aber du könntest eben irgendwann auf eine C/C++ Implementation treffen, wo das nicht funktioniert. Oder auf eine Betriebssystem-Plattform, wo die Reihenfolge der Bytes im 32-Integer andersrum ist (siehe Byte-Order)...

    bis bald
    akari



  • bitte helfen , weg damit !



  • Was sollte denn dagegen sprechen außer der Tatsache, daß man sowas eher mit unsigned int machen sollte? Du holst dir die drei niederwertigsten Bytes des int, in denen deine RGB-Anteile stehen. Das vierte Byte ist erstens 0 und zweitens für diesen Einsatz unwichtig.



  • also du meinst das sieht vernünftig aus `?



  • Hallo

    Ja, das ist soweit in Ordnung, solltest nur unsigned int verwenden.
    Es gibt sicher auch andere Varianten, aber das Prinzip bleibt gleich.

    bis bald
    akari



  • weg damit



  • basekatalog schrieb:

    uint r = color >> 16 ;

    könnte auch reichen, das zusätzliche AND dient nur dazu, eventuell vorhandene Daten im höchsten Byte abzuschneiden

    uint g = color >> 8 & 0xFF;

    um das zu veranschaulichen:
    * 0xFFEEFF >> 8 = 0x00FFEE
    * 0x00FFEE & 0xFF = 0xEE

    uint b = color & 0xFFFF;

    Da sind zwei F zu viel, du willst ja schließlich nur die niedrigsten 8 Bit rausholen.



  • alles klar habs jetzt genau verstanden , weil mir war das logische und nicht so geläufig! ok vielen dank!


Anmelden zum Antworten