AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Farbwert zu Dezimal

Ein Thema von EWeiss · begonnen am 28. Mär 2019 · letzter Beitrag vom 3. Apr 2019
Antwort Antwort
EWeiss
(Gast)

n/a Beiträge
 
#1

AW: Farbwert zu Dezimal

  Alt 29. Mär 2019, 17:38
Zitat:
hast du den Code offensichtlich inzwischen geändert und die Effekte werden wie du es erwartest gezeichnet. Ich gratuliere dir zum fertigen Programm .
Nein werden sie nicht.

Ich finde den punkt leider nicht wo ich es ändern soll.
Habe ich dir doch per PN mitgeteilt

Ich meinte damit Draw was funktioniert.
Das in VB Daten vorhanden sind siehe Shot.

In Delphi nicht.
Bei deiner Case 0 Berechnung kommt immer 0 raus.
Keine Ahnung warum.

Beim Klaus seiner Version kommen werte..
Zitat:
Debug Output: < 127 -1711276032 Process TrickSpectrum.exe (15616)
Debug Output: < 127 -1711276032 Process TrickSpectrum.exe (15616)
Debug Output: < 127 -1711276032 Process TrickSpectrum.exe (15616)
Debug Output: < 127 -1711276032 Process TrickSpectrum.exe (15616)
Zitat:
Debug Output: > 127 -2147483648 Process TrickSpectrum.exe (2400)
Debug Output: > 127 -2147483648 Process TrickSpectrum.exe (2400)
Debug Output: > 127 -2147483648 Process TrickSpectrum.exe (2400)
Debug Output: > 127 -2147483648 Process TrickSpectrum.exe (2400)
und immer der gleiche wert.

aber nicht wie in VB 255, 254 usw..
Der Code von VB lässt sich definitiv auf Delphi umlegen und das ganz ohne Tricks.
Wo ist der Spezialist der das anscheinend kann? Sorry konnte ich mir nicht verkneifen.

7 Seiten und kein Erfolg vielleicht sollten wir es besser doch lassen.
Will einfach nicht.

gruss

Geändert von EWeiss (11. Jul 2019 um 15:56 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#2

AW: Farbwert zu Dezimal

  Alt 29. Mär 2019, 20:22
Irgendwie finde ich das seltsam.
nehmen wir mal an c wäre hXX und a=h80,dann ware igspectrumdata[x,y]=h800000XX.
Also etwas größer als 254,255,265. Da muß noch (implizit) irgendwas anderes passieren. (ich denke da an ROR/ROL??)

Gruß
K-H
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#3

AW: Farbwert zu Dezimal

  Alt 29. Mär 2019, 20:27
Ich habe eine andere Vermutung die ich gerade am testen bin..
Wenn es das ist was ich meine melde ich mich wieder.

Kann mir nicht vorstellen das @Michaels Version falsch sein soll da ist irgendwas anderes im argen.

gruss

Geändert von EWeiss (29. Mär 2019 um 21:05 Uhr)
  Mit Zitat antworten Zitat
Amateurprofi

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

AW: Farbwert zu Dezimal

  Alt 30. Mär 2019, 04: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
Amateurprofi

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

AW: Farbwert zu Dezimal

  Alt 1. Apr 2019, 23:16
@Emil.
Kann sein ich habe da etwas gefunden, was ein Grund für Exceptions sein könnte.
Am Ende von #64 schrieb ich:

Zitat:
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.
Schon als ich das schrieb hatte ich das Gefühl dass da noch mehr ist und habe das deshalb noch mal überprüft.
Wenn du an FillChar SpectrumData2D[0] als StartAdresse übergibst, dann werden nicht die Daten in SpectrumData2D[0] gelöscht, sondern die in SpectrumData2D enthaltenen dynamischen Arrays, beginnend mit SpectrumData2D[0].
Bei Count=4 wird das Array SpectrumData2D[0] zerstört und wenn dann später darauf zugegriffen wird hagelt es Exceptions.
Außerdem wird ein Memory Leak erzeugt.

Setz mal einen Breakpoint auf die Zeile mit FillChar(SpectrumData2D[0], sizeof(SpectrumData2D), 0);
Wenn dann dort angehalten wird geh mit der Maus auf SpectrumData2D und schau dir an, wie das dargestellt wird.
Dann führe das FillChar mit F7 aus und danach gehe wieder auf SpectrumData2D.
In der anhängenden Abbildung siehst du wie es vor und nach Ausführung von SpectrumData2D ist.
Bei SpectrumData2D[0] kannst du sehen, dass nach dem FillChar keine Daten mehr da sind.
Ob das jetzt die Ursache für alle Probleme ist weiß ich nicht, aber zumindest ist das eine der Ursachen.
Angehängte Grafiken
Dateityp: jpg SpectrumData2D.jpg (233,6 KB, 9x aufgerufen)
Gruß, Klaus
Die Titanic wurde von Profis gebaut,
die Arche Noah von einem Amateur.
... Und dieser Beitrag vom Amateurprofi....

Geändert von Amateurprofi ( 1. Apr 2019 um 23:46 Uhr)
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#6

AW: Farbwert zu Dezimal

  Alt 2. Apr 2019, 05:42
@Amateurprofi
Danke daran kann es nicht liegen denn dieser Eintrag existiert nicht mehr.

Delphi-Quellcode:
{$REGION 'SetSymmetrical'}

procedure TSpectrum.SetSymmetrical(const Value: BOOL);
begin

  FSymmetrical := Value;

  CreateSpectrumBitmap;
  CreateMap;
end;
{$ENDREGION}
Es hat gekracht nach der Änderung zu LongWord weil der Pointer auf SpectrumData2D falsch übergeben worden ist
Alle hier bisher vorgestellten Lösungen geben keine Daten zurück alles ist leer ausgenommen davon die Originale HEX Funktion.
Hier bestehen jedoch mehrere Probleme: Overflow, Range check error, signed und unsigned typen werden gemischt.
Deshalb wollte ich das ganze auf Dezimal umlegen was leider nicht funktioniert wie man sieht.

Vorher
Delphi-Quellcode:
  if GDIP_CreateBitmapFromScan0(w, rc.Bottom, w * 4, PixelFormat32bppARGB, PByte
     (SpectrumData1D[0]), imgSpectrum) <> OK then
Nachher
Delphi-Quellcode:
  if GDIP_CreateBitmapFromScan0(w, rc.Bottom, w * 4, PixelFormat32bppARGB, PByte
     (@SpectrumData1D[0]), imgSpectrum) <> OK then
Das einzige was es bzg. FillChar noch gibt ist diese Zeile.
Ob es zwingend notwendig ist die vorherigen Daten zu Nullen mag dahin gestellt sein.
Ich mache es um vorher ermittelte werte im Speicher zu löschen damit beim Rendern keine Überbleibsel zurück bleiben was die Darstellung verändern könnte.
Delphi-Quellcode:
  FillChar(Spectrum[0], Length(Spectrum) * sizeof(TComplex), 0); // <<<<

  ToComplex(Wav, Spectrum);

  FFT(Spectrum);
Bin mir auch nicht sicher ob die von @Neutral General verwendete Funktion das 2D Array zu 1D Array zu konvertieren der richtige weg ist.
Man kann mit ihm leider unvoreingenommen nicht Diskutieren. Siehe
Bits vom Type Array of TBits ist Hundertfach bewährt nichts besonderes und man trifft immer wieder auf dieser oder ähnlicher Herangehensweise.

Normalerweise würde ich die länge des Arrays so übergeben wenn man davon ausgeht das es beim Start so oder so leer ist.
Ich erstelle ein HDib vom HBitmap oder DC.
Delphi-Quellcode:
  if hBmp <> 0 then
    hDIB := hBmp
  else
    hDIB := GetBitmapFromDC(DC);

Dann hole ich mir das Object über
GetObject(hDIB, sizeof(bm), @bm);

weise dem Header bmiHeader die werte zu
bi.bmiHeader.biSize := sizeof(bi.bmiHeader)

errechne die Bitmap länge anhand der vorher zugewiesenen werte
BitmapLength := bm.bmWidth * bm.bmHeight * 4;

redimensionier mein Array of TBytes.
    SetLength(bmpBits, BitmapLength);

hole die bits und kopiere sie in mein 1D Array vom Type TBytes
    GetDIBits(DC, hDIB, 0, bm.bmHeight, @bmpBits[0], bi, DIB_RGB_COLORS);

erst dann erstelle ich das Bitmap über
Delphi-Quellcode:
      if GdipCreateBitmapFromScan0(bm.bmWidth, bm.bmHeight, bm.bmWidth * 4, PixelFormat32bppARGB,
        @bmpBits[0], lpImg) = OK then
Glaube es ist besser wenn die Leute die den Effekt haben möchten es selbst implementieren anhand ihres Wissensstand.
Dann muss ich mich nicht mehr damit rumärgern.

Danke für deine Analyse..
Bei bedarf kann ich gerne die aktuelle Version mit alter Release HEX Funktion hochladen.

PS:
Aber nochmal.. Nein es ist keine Comedy auch wenn es den Anschein hat.
Warum gehen denn alle hier vorgeschlagenen Lösungen ins leere? Gute frage oder?
Keine variante die hier von Spezialisten ? erstellt, vorgestellt wurde funktioniert warum wohl? Weil es nun mal nicht so einfach ist.
Das ist kein Vorwurf (Bin über Hilfe Dankbar) aber eine Feststellung.
Leider sind hier einige Leute sehr überheblich einen Unfähigkeit vorwerfen und am ende selbst nichts auf die reihe kriegen.

gruss

Geändert von EWeiss ( 2. Apr 2019 um 14:49 Uhr)
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.079 Beiträge
 
Delphi 10.4 Sydney
 
#7

AW: Farbwert zu Dezimal

  Alt 2. Apr 2019, 09:31
@Amateurprofi
Danke daran kann es nicht liegen denn dieser Eintrag existiert nicht mehr.

Delphi-Quellcode:
{$REGION 'SetSymmetrical'}

procedure TSpectrum.SetSymmetrical(const Value: BOOL);
begin

  FSymmetrical := Value;

  CreateSpectrumBitmap;
  CreateMap;
end;
{$ENDREGION}
Es wäre natürlich praktisch für diejenigen die noch (!) helfen wollen, wenn du deine Änderungen und Anpassungen immer aktuell halten würdest, so dass man sich die doppelte Mühe sparen kann.

In dem anderen Thread - es ist übrigens für Außenstehende und neue Leute im Forum nicht ersichtlich, worauf sich dein Problem hier in diesem Thread bezieht - kann man bisher nur Version 1.0.2.0 herunterladen.
Dieser Versionsstand beinhaltet noch den von Amateurprofi gefundenen Fehler.
Für die Nachwelt:
https://www.delphipraxis.net/200135-...isualizer.html

Es wäre für andere übrigens einfacher zu helfen, wenn der Visualizer noch die Möglichkeit böte eine Wave-Datei direkt zu öffnen, abzuspielen und zu visualisieren.
Ich habe zwei, drei Minuten erfolglos mit den Windows-Aufnahmegeräten herumprobiert, aber außer leises Rauschen wurde nichts angezeigt (kurzes Flackern und blinken im Kreis).
Für mehr fehlt mir die Zeit und Motivation.

Du solltest die Eingangshürden so gering wie möglich halten, wenn du wirklich Hilfe erwartest.
Dein NonVCL-Quelltext weicht stark von dem ab, was der durchschnittliche Delphiprogrammierer gewohnt ist.
Daher wäre es vorteilhaft, wenn du den Einstieg so bequem wie möglich gestaltest.

Leider sind hier einige Leute sehr überheblich einen Unfähigkeit vorwerfen und am ende selbst nichts auf die reihe kriegen.
  Mit Zitat antworten Zitat
Amateurprofi

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

AW: Farbwert zu Dezimal

  Alt 2. Apr 2019, 13:11
Bin mir auch nicht sicher ob die von @Neutral General verwendete Funktion das 2D Array zu 1D Array zu konvertieren der richtige weg ist.
Delphi-Quellcode:
function Array2DTo1D(AArray: TArray2D): TArray1D;
var
  y, x: Integer;
  n: Integer;
begin
   SetLength(Result, Length(AArray) * Length(AArray[0]));

   n := 0;
   for y := 0 to High(AArray) do begin
     for x := 0 to High(AArray[y]) do begin
       Result[n] := AArray[y,x];
       inc(n);
     end;
   end;
end;
Ich bin mir vollkommen sicher dass die Funktion Array2DTo1D korrekt funktioniert, allerdings unter der Bedingung dass alle in SpectrumData2D enthaltenen Arrays die gleiche Länge haben. Das scheint in Deinem Projekt der Fall zu sein.

Die nachstehende Version liefert die gleichen Ergebnisse aber deutlich schneller (Laufzeit ca. 1/3 der obigen Version).
Auch hier gilt die Bedingung dass alle in SpectrumData2D enthaltenen Arrays die gleiche Länge haben.

Delphi-Quellcode:
FUNCTION xArray2DTo1D(AArray: TArray2D): TArray1D;
var I,Len,Size:Integer;
begin
   Len:=Length(AArray[0]);
   SetLength(Result, Length(AArray)*Len);
   Size:=Len*SizeOf(Result[0]);
   for I:=0 to High(AArray) do
      Move(AArray[I,0],Result[I*Len],Size);
end;
Gruß, Klaus
Die Titanic wurde von Profis gebaut,
die Arche Noah von einem Amateur.
... Und dieser Beitrag vom Amateurprofi....
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:23 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz