Int r = ((p & 0xFF0000) >> 16); wie funktioniert das im Hintergrund

Hallo Leute,

wie kann man farbwerte bekommen?
angenommen wir haben Pixel mit diesem wert 11111111 01001010 01000110 00111010 und laut diese Formeln kann man farbwerte berechnen

int r = ((p & 0xFF0000) >> 16);
				int g = ((p & 0x00FF00) >> 8);
				int b = ((p & 0x0000FF));

überall ist geschrieben dass man nach rechts verschieben soll aber Hintergrund verstehe ich nicht wirklich
0xFF0000 = 00000000 00000000 00000000 11111111 wenn man logische und macht bekommt man von ben genannte Pixel diese wert

00000000 00000000 00000000 00111010

und wie Funktioniert Rest?

danke euch

ist falsch, richtig ist

0xFF0000 = 11111111 00000000 00000000

das wird über die Quelle mit den logischen Bits gelegt und ein Teil „ausgeblendet“. Danach wird das entsprechend geshifted.

allerdings kannst du beim Alpha was falsches bekommen

wenn der Alpha größer als 127 ist, wird anschließend beim Shiften von links alles mit 1 aufgefüllt (vgl. Regeln fürs Shiften).

int alpha = (p >> 24) & 0xff;

little endian und big endian ist nur direkt auf dem Prozessor interessant

[QUOTE=mogel]allerdings kannst du beim Alpha was falsches bekommen

wenn der Alpha größer als 127 ist, wird anschließend beim Shiften von links alles mit 1 aufgefüllt (vgl. Regeln fürs Shiften).

int alpha = (p >> 24) & 0xff;

[/QUOTE]

Alternativ >>> statt >> benutzen, dann wird immer mit 0 aufgefüllt.

int rgbInt = Integer.MAX_VALUE / 3;

int bits = 32;

int rInt = ((rgbInt >>> (bits=bits-8)) << 24) >>> 24;
int gInt = ((rgbInt >>> (bits=bits-8)) << 24) >>> 24;
int bInt = ((rgbInt >>> (bits=bits-8)) << 24) >>> 24;

Das Ganze nur noch in eine Schleife packen und schon hast du alle 3-4 Farbwerte, ohne lästige Biermarke/Bitmaske.

Zur Erklärung: Da werden Bits hin und her geschoben, ohne arithmetisch zu sein.

Warum immer so kompliziert und kryptisch…!?

Worauf sich die Frage nun genau bezieht, hab’ ich nicht verstanden (es geht wohl nicht draum, wann wo wie viel Strom fließt :D). Aber allgemein finde ich es auch “handlicher”, erst zu shiften und dan zu verUNDen…

int a = (p >> 24) & 0xFF;
int r = (p >> 16) & 0xFF;
int g = (p >>  8) & 0xFF;
int b = (p >>  0) & 0xFF;

Weniger Strom läuft bei >>> , marco, weil msb/lsb nicht auf 1 geprüft werden muss.

Hast du mal getestet, ob meins funktioniert, BEVOR wieder das Kritisieren anfängt?

Ich denke, hier liegt s an dem Begriff bit shift, bit mask, binary or, and, not und XOR. (Was gibt s denn da noch, was nicht arithmetisch ist, aber [unär/binär/te/ärner] bitweise ist?)

So Bier alle, ich gehe nun schlafen, gn8.

Stromverbrauch für Operationen von Code zu diskutieren der in einer VM läuft dürfte in etwa so sinnvoll sein, als würde man den Spritverbrauch von grünen und roten Autos vergleichen :wink:

Unabhängig davon ob der Code funktioniert, ist die Code von Marco13 lesbarer (und auch die gängige Version, die man normalerweise für diese Konvertierung sieht).
Zweiten Absatz hier schon gelesen? http://forum.byte-welt.net/threads/11813-Text-(nicht-sicher)-verschlüsseln-aber-für-Human-lesbar-!?p=91520&viewfull=1#post91520
Das ist genau so ein Fall, wo man eine super Möglichkeit hat den eigenen Stil aufzupeppen :slight_smile:

So, ich hab’ natürlich auch etwas ausprobiert, hier ist das richtige und lesbare Ergebnis:

        int i = rand.nextInt();
        if (Math.random() < 0.5) {
            i |= 1 << 31;
        } else {
            i &= Integer.MAX_VALUE;
        }
        System.out.printf("%32s%n", Integer.toBinaryString(i));
        for (int j = 0; j < 4; j++) {
            int k = i >>> 24 - j * 8 & 0xFF;
            // oder: int k = i >>> (24 - j*8) & 0xFF; , aber das regelt OperatorenRang
            System.out.println(String.format("%08d", Integer.parseInt(Integer.toBinaryString(k))));
        }```

Zeile 3 bis 7 wäre eigentlich gar nicht nötig (da der komplette Bereich aus 2^32 ints abgedeckt wird), aber daran kann TE/TO schnell sehen, wie man ein Bit setzt oder löscht.

i = rgbInt
j = Schleifenzähl- oder Iterationsvariable
k = aktueller Wert = ? v R v G v B v ?
alles Andere = Konstanten/Literale/Formatierungsanweisungen

Soweit i.O./in Ordnung?

Das ist überkompliziert und deshalb schlecht lesbar. Marco13s Lösung ist lesbar und erfüllt genau den gewünschten Zweck. Daran gibt es nichts mehr zu verbessern. Die „Erweiterbarkeit“ die du in deiner Lösung eingebaut hast, wird man niemals brauchen: YAGNI.

Nein, weil „funktionieren“ eine Grundvoraussetzung ist. Quasi eine Art „Standgas“. Es gibt aber noch viel mehr, was wichtig ist. Wenn man, wie bei nt rInt = ((rgbInt >>> (bits=bits-8)) << 24) >>> 24; mindestens fünf low-level instruktionen in einer Zeile unterbringt (wenn es weniger auch schon tun würde), und dort ein assignment mit reinmischt (das einen „„Seiteneffekt““ hat, und defür sorgen würde, dass der Rest nicht nicht mehr funktioniert, wenn man z.B. die Zeile für „rInt“ auskommentiert), dann rollen sich zumindest mir die Fußnägel hoch. Natürlich kann es nicht schaden, sowas mal „auszuprobieren“ oder mal fasziniert über sowas wie Bit Twiddling Hacks zu scrollen, aber „in der Praxis“ sollte man sowas nicht einsetzen, bzw. bei letzteren dazuschreiben, was es macht…

Ja, gut, es soll nicht so kompliziert sein, dass es keiner mehr versteht, aber ich habe es didaktisch aufgearbeitet, s. D. man doch etwas lernt/versteht… Bis später (Wenn Fragen da sind)

… und das ist schon ein Fehler. Der Code sollte für sich sprechen und keiner Erklärung bedürfen.

Ich wär natürlich nicht Cyborg, wenn ich nicht eine Demo dazu vorbereitet hätte (Farben-Demo, Bit umdrehen):

 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package pkg12farbendemo;

import java.awt.Color;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.WindowConstants;

/**
 * @author CB
 */
public class Main {

    private static final JFrame frame = new JFrame("12FarbenDemo");
    private static final JPanel panel = new JPanel();
    private static int rgbInt = new Random().nextInt();

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
        panel.setBackground(new Color(rgbInt));
        frame.add(panel);
        frame.setSize(800 - 50, 600 - 50);
        frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
        frame.setVisible(true);

        for (;;) {
            String str = JOptionPane.showInputDialog(
                    frame,
                      "Sie sehen die (RGB)-Farbe:
"
                    + String.format("%32s
", Integer.toBinaryString(rgbInt)).replaceAll(" ", "0")
                    + "Welches Bit (1 bis 32) soll umgedreht werden?:",
                    Integer.valueOf(32));
            int newInt;
            if (str == null || str.isEmpty() || (newInt = Integer.parseInt(str)) < 1 || newInt > 32) {
                //frame.dispose();
                return;
            }
            newInt = 32 - newInt;
            if ((rgbInt >>> newInt & 1) == 1) {
                rgbInt &= ~(1 << newInt);
            } else {
                rgbInt |= 1 << newInt;
            }
            panel.setBackground(new Color(rgbInt)); //SwingUtilities.invokeLater(...args.);
        }
    }
}```

Der User soll immer die Möglichkeit haben, ein Bit umzudrehen/umzupolen.

So schaut's aus:



Zu verbessern auf jeden Fall noch:

Integer#parseInt(str) kann eine Exception werfen,
muss generell immer alles in den EDT?,
anscheinend ist JOptionPane#showInputDialog(Component) immer modal?, das habe ich auch nicht weg bekommen bekommen,
Zeile 47 kann auch ersetzt werden durch:
`if ((rgbInt & (1 << newInt)) > 0) {`
,
Zeile 46 bis 51 ist vermutlich irgendetwas falsch.

Bis später

Sinnbefreit…

Zeile 46 bis 51 ist doch richtig, wenn man das für ein paar Bits durchspielt, ist es richtig… Der Sinn ist,
verschiedene Farben darstellen/anzeigen,
einzelne Bits manipulieren,
allgemein: Mini mini GUI,
ein umgedrehtes Bit kann je nach Position eine Farbe stark oder schwach verändern,
mehr fällt mir jetzt auch nicht ein.

anni80 könnte sich ja noch mal melden hier.