Thema: Delphi Farbwert zu Dezimal

Einzelnen Beitrag anzeigen

Amateurprofi

Registriert seit: 17. Nov 2005
Ort: Hamburg
1.077 Beiträge
 
Delphi XE2 Professional
 
#64

AW: Farbwert zu Dezimal

  Alt 30. Mär 2019, 05:05
Hallo Emil,
schau dir mal #1 genauer an.

d := round(Fade * 255); Fade, wenn ich es richtig sehe ist ein Single im Bereich 0 .. 1.
Also ist d (ein Integer) im Bereich 0 .. 255

Der auskommentierte Ausdruck
//a := (((SpectrumData2D[X, Y] and $FF000000) div $1000000) and 255); Ergibt immer a = 0
Deine fehlerhafte Umsetzung
a := ((SpectrumData2D[X, Y] shl 24) and 255); ergibt ebenfalls immer a = 0
Die korrekte Umsetzung
a := ((SpectrumData2D[X, Y] shr 24) and 255); ergibt ebenfalls immer a = 0
Warum?!
Wenn Du einen Byte-Wert um 8 oder mehr Bits shiftest, gleichgültig ob links oder rechts und das Ergebnis mit "and 255" begrenzt wird das Resultat stets 0 sein.

Danach machst du
a := a - d; .
Da a = 0 war ist a jetzt abhängig von d im Bereich -255 .. 0

c := SpectrumData2D[X, Y] and RGB(255, 255, 255); .
c ist im Bereich 0..255 (identisch mit SpectrumData2D[X, Y])

Delphi-Quellcode:
if a > 127 then
   SpectrumData2D[X, Y] := c or ((a - 256) * $1000000) // hier komm ich nicht klar wegen den $1000000
else
   SpectrumData2D[X, Y] := c or (a * $1000000); // hier komm ich nicht klar wegen den $1000000
Das wirst du inzwischen durch den von Klaus01 vorgeschlagenen Code aus #4 ersetzt haben.
Delphi-Quellcode:
if a > 127 then
   SpectrumData2D[X, Y] := c or ((a - 256) shl 24)
else
   SpectrumData2D[X, Y] := c or (a shl 24);
Hier wird (weil a = -255..0) immer der Else-Zweig ausgeführt, was aber belanglos ist, denn SpectrumData2D[X, Y] wird immer = c gesetzt.
Warum?!
In SpectrumData2D[X, Y] (ein Byte) wird immer das untere Byte des zugewiesenen Wertes gespeichert, das "or (a shl 24)" bzw. "or ((a - 256) shl 24)" verändert das untere Byte von c aber nicht.
Da c identisch ist mit SpectrumData2D[X, Y] bleibt (zumindest wenn FEffect = 0 ist) SpectrumData2D unverändert.

Komme ich mal zum Schluss.
Meine Vermutung ist, dass SpectrumData2D ein Array of Array of UInt32 sein sollte und nicht ein Array of Array of Byte, wie von dir am Anfang von #1 geschrieben und wie auch in deinem Projekt definiert.
Ich hab nicht wirklich alle Beiträge gelesen, aber alles was ich las, ließ mich vermuten, dass alle automatisch davon ausgingen dass SpectrumData2D 32Bit-Werte enthält, obwohl Du in der ersten Zeile von #1 schiebst " SpectrumData2D[X, Y] definiert als byte".
Sei nicht böse, aber für mich ist dieser Thread Comedy pur.

Ach, was mir per Zufall auffiel:
Delphi-Quellcode:
procedure TSpectrum.SetSymmetrical(const Value: BOOL);
begin
  FSymmetrical := Value;
  FillChar(SpectrumData2D[0], sizeof(SpectrumData2D), 0);
  CreateSpectrumBitmap;
  CreateMap;
end;
Mit FillChar(SpectrumData2D[0], sizeof(SpectrumData2D), 0); willst Du vermutlich alle Bytes in SpectrumData2D = 0 setzen.
Tust du aber nicht!
Deine Erwartung ist sicherlich, dass SizeOf(SpectrumData2D) die Größe des Speicherbereiches von SpectrumData2D ist.
Damit hättest Du auch Recht, wenn SpectrumData2D ein statisches Array wäre.
Da es sich aber um ein dynamisches Array handelt, ist SizeOf(SpectrumData2D) = 4.
Gruß, Klaus
Die Titanic wurde von Profis gebaut,
die Arche Noah von einem Amateur.
... Und dieser Beitrag vom Amateurprofi....
  Mit Zitat antworten Zitat