Delphi-PRAXiS
Seite 2 von 2     12   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Farbwert zu Dezimal (https://www.delphipraxis.net/200198-farbwert-zu-dezimal.html)

EWeiss 29. Mär 2019 11:09

AW: Farbwert zu Dezimal
 
Im Original VB source nicht.

gruss

Klaus01 29. Mär 2019 11:18

AW: Farbwert zu Dezimal
 
.. wenn es da funktioniert, dann kann imgSpectrumData nicht nur mit Nullen gefüllt sein.

Grüße
Klaus

EWeiss 29. Mär 2019 11:34

AW: Farbwert zu Dezimal
 
Zitat:

Zitat von Klaus01 (Beitrag 1429102)
.. wenn es da funktioniert, dann kann imgSpectrumData nicht nur mit Nullen gefüllt sein.

Grüße
Klaus

Doch ist es
Code:
GdipCreateBitmapFromScan0(w, frmMain.ScaleHeight, w * 4, PixelFormat32bppARGB, imgSpectrumData(0, 0), imgSpectrum)
Delphi-Quellcode:
GDIP_CreateBitmapFromScan0(w, rc.Bottom, w * 4, PixelFormat32bppARGB, PByte(SpectrumData1D[0]), imgSpectrum)


erstellt ein leeres Bitmap im angegebenen Format

@Michael II Funktion liefert auch immer 0 zurück.
Delphi-Quellcode:
  case FEffect of
    0:
      begin
        d := round(Fade * 255);

        for Y := 0 to h do
        begin
          for X := 0 to w do
          begin
            a := SpectrumData2D[x, y] shr 24;
            if a >= d then
              a := a - d
            else
              a := 0;

            c := SpectrumData2D[x,y] and $00FFFFFF;

            SpectrumData2D[x,y] := (a shl 24) or c;
          end;
        end;
      end;
Die VB6 Funktion konvertiert das Byte (255) zu LONG
Code:
a = (((imgSpectrumData(x, y) And &HFF000000) \ &H1000000) And &HFF&)
Kann mir aber nicht vorstellen das es daran liegen könnte.

gruss

Klaus01 29. Mär 2019 11:54

AW: Farbwert zu Dezimal
 
.. mach aus Deinem alpha: Integer mal ein alpha: Byte


Delphi-Quellcode:
     0: begin
           d := fade * 255;
           // nur für Tests
           //d := round((random(10) /10)) *255;
           for y:= 0 to h do
             for x := 0 to w do
               begin

                 alpha := ((imgSpectrum[x,y] and $FF000000) shr 24) and $FF;
                 alpha := alpha - d;
                // Byte kann nicht < 0 sein
                // if alpha < 0 then
                //   alpha := 0;
                 c := imgSpectrum[x,y] and $FFFFFF;
                 if alpha > 127 then
                   imgSpectrum[x,y] := c or ((alpha -256) shl 24)
                 else
                   imgSpectrum[x,y] := c or (alpha shl 24);
               end;
rot, grün und blau können auch vom Type Byte sein.

Grüße
Klaus

EWeiss 29. Mär 2019 12:11

AW: Farbwert zu Dezimal
 
Zitat:

Zitat von Klaus01 (Beitrag 1429106)
.. mach aus Deinem alpha: Integer mal ein alpha: Byte


Delphi-Quellcode:
     0: begin
           d := fade * 255;
           // nur für Tests
           //d := round((random(10) /10)) *255;
           for y:= 0 to h do
             for x := 0 to w do
               begin

                 alpha := ((imgSpectrum[x,y] and $FF000000) shr 24) and $FF;
                 alpha := alpha - d;
                // Byte kann nicht < 0 sein
                // if alpha < 0 then
                //   alpha := 0;
                 c := imgSpectrum[x,y] and $FFFFFF;
                 if alpha > 127 then
                   imgSpectrum[x,y] := c or ((alpha -256) shl 24)
                 else
                   imgSpectrum[x,y] := c or (alpha shl 24);
               end;
rot, grün und blau können auch vom Type Byte sein.

Grüße
Klaus

Ja das funktioniert..
Aber was ist nun mit
Delphi-Quellcode:
imgSpectrum[x,y] := c or (alpha shl 24);


Denn wenn du Byte nimmst und Fade ist unter 0.5 dann wird diese nicht mehr aufgerufen muss sie aber.
Das sind die Probleme mit denen ich mich rumschlage.

Aber es scheint ja Profis zu geben die das angeblich können nur gesehen habe ich davon noch nichts.
Können einen nur niedermachen. Grrr..

EDIT:
Hab noch nen Shot angehängt.
Du siehst VB ruft auch diese auf.. bei Fade 0,25 bei dir jedoch nie.

gruss

Klaus01 29. Mär 2019 12:22

AW: Farbwert zu Dezimal
 
.. wenn für fade 0.4 nehme (geht das erstmal nicht dem Integer zuzuweisen)
Wenn ich da ein round drumpacke dann wird das auf 0 gerundet.

Damit hängt es dann vom alpha Wert von imgSpectrm[x,y] ab wie groß
der alpha - d Wert wird.

d pendelt eigentlich immer zwischen 0 und 1.
Soll das so sein?

Mit den Zufallswerten in imgSpectrum und d wird auch ab und an der else Zweig aufgerufen.
Also muss alpha (aus imgSpectrum) einen Wert von 127 und d von 1 haben um in den else Zweig zu gelangen.
Oder alpha ist generell kleiner als 127.

Grüße
Klaus

EWeiss 29. Mär 2019 12:26

AW: Farbwert zu Dezimal
 
Zitat:

d pendelt eigentlich immer zwischen 0 und 1.
d pendelt nicht es ist ein festeingestellter wert.
Verstehe nicht wie sich der wert verändern kann.

d := fade = 0.36 * 255 bleibt konstant 92 da tut sich nichts.

gruss

Klaus01 29. Mär 2019 12:32

AW: Farbwert zu Dezimal
 
.. der verändert sich nicht, in der Routine,

Hatte das round falsch angewendet. round(0.4) -> 0
Nun mit round(0.25 * 255) ist d dann 64

und ja, auch mit diesen Werten wird der else Zweig aufgerufen.
Wenn alpha und d entsprechende Werte haben.

Grüße
Klaus

EWeiss 29. Mär 2019 12:42

AW: Farbwert zu Dezimal
 
Habe mal VB angepasst so das ich genaue werte liefern kann.

Code:
            For x = 0 To w
                a = (((imgSpectrumData(x, y) And &HFF000000) \ &H1000000) And &HFF&)
               
                f = a - d

                If f < 0 Then
                  a = 0
                Else
                  a = f
                End If
               
                c = imgSpectrumData(x, y) And &HFFFFFF

                If a > 127 Then
                    imgSpectrumData(x, y) = c Or ((a - 256) * &H1000000)
                Else
                    imgSpectrumData(x, y) = c Or (a * &H1000000)
                End If
a bekommt den wert 0

f = a - d = -92

damit ist die Bedingung erfüllt das ich in die zweite Funktion(Bedingung) springe.
Da du aber Byte verwendest wird -92 niemals bei dir auftreten..

Deshalb springt er zwischen > 127 und < 0 denn 0.36 * 255 = 92 und a -d = -92

Also Byte ist definitive in dem fall dann nicht korrekt.
Hab jetzt alles durch das wird nix.
Danke trotzdem.

gruss

Klaus01 29. Mär 2019 13:03

AW: Farbwert zu Dezimal
 
.. das mit der Hilfsvariablen ist eine gute Idee:

Delphi-Quellcode:
           for y:= 0 to h do
             for x := 0 to w do
               begin

                 alpha := ((imgSpectrum[x,y] and $FF000000) shr 24) and $FF;
                 _alpha := alpha - d;
                // if alpha < 0 then
                //   alpha := 0;
                 c := imgSpectrum[x,y] and $FFFFFF;
                 if _alpha > 127 then
                   imgSpectrum[x,y] := c or ((alpha -256) shl 24)
                 else
                   imgSpectrum[x,y] := c or (alpha shl 24);
               end;
Wobei _alpha vom type smallInt ist, alpha ist weiterhin ein Byte.

Grüße
Klaus

EWeiss 29. Mär 2019 13:09

AW: Farbwert zu Dezimal
 
kommst du denn jetzt in beide else zweige?

gruss

Klaus01 29. Mär 2019 13:17

AW: Farbwert zu Dezimal
 
Ja, aber mit dem Fadingwert von 0.32 häufiger in den else Zweig.

EWeiss 29. Mär 2019 13:19

AW: Farbwert zu Dezimal
 
Zitat:

Zitat von Klaus01 (Beitrag 1429122)
Ja, aber mit dem Fadingwert von 0.32 häufiger in den else Zweig.

Ok das funktioniert nicht bei mir.

Das Array als Integer definiert.
a als Byte
_a als SmallInt

komme nie über 127
weder mit fade über 0.5 noch mit drunter.
Ich versteh es nicht.

gruss

Klaus01 29. Mär 2019 13:29

AW: Farbwert zu Dezimal
 
Je näher fading zur 1 rückt desto häufiger geht es in den else Zweig.
Bei d = 153 (f=0.6) kann _alpha nicht mehr größer als 127 werden.

alpha max = 255 und _alpha = alpha - d

Wenn man mit der Hilfsvariablen arbeitet muss alpah noch in der Berechnung angepasst werden.

Delphi-Quellcode:
                 if _alpha > 127 then
                   imgSpectrum[x,y] := c or (((alpha - d) -256) shl 24)
                 else
                   imgSpectrum[x,y] := c or ((alpha - d) shl 24);
Grüße
Klaus

Michael II 29. Mär 2019 13:37

AW: Farbwert zu Dezimal
 
Hallo EWeiss

in welcher Procedure befindet sich der hier diskutierte Code? In procedure TSpectrum.Release;? Falls Ja: Früher hast du dort SpectrumData2D[] verwendet und jetzt imgSpectrum[]?

Oder ist es eine andere Procedure - und wenn Ja, wo findet man diese in deinem Code?

Wenn es TSpectrum.Release; ist: SpectrumData2D bzw. jetzt imgSpectrum muss natürlich am Eingang zu deiner Procedure mit Daten gefüllt sein, sonst machen die Rechnereien ja gar keinen Sinn.

Zum Testen: Wie früher erwähnt: Du könntest sämtliche VB6 Prozeduren, welche etwas rechen mit dem gleichen Input abfüllen wie deine jeweils entsprechende Delphi Prozedur und dann prüfen was am Ausgang rauskommt. Nur wenn beide Versionen die gleichen Werte liefern, bist du am sicher, dass dein Programm das tut, was das Original schön längst macht ;-).

Alles wird gut.

V.a. wichtig ist, dass du Datentypen nicht mischst. Sonst meckert Delphi (zurecht) noch lange rum.

Mindestens in deiner zuerst veröffentlichten Version sind in TSpectrum.Release; sämtliche Werte im Array SpectrumData2D immer 0 (Null).
Trotzdem malt dein Programm Dinge auf den Schirm. Da stimmt also etwas beim Ablauf nicht.

Ob in deiner Version auch alle Elemente 0 sind kannst du ja leicht testen, indem du
Delphi-Quellcode:
assert( SpectrumData2D[x, y] = 0, 'Oh, nicht Null ;-)' );
einfügst.

Michael II 29. Mär 2019 13:40

AW: Farbwert zu Dezimal
 
Und noch ein mal und zum letzten Mal ;-): Die Unterscheidung a > 127 ist im Delphi Code nicht notwendig, da wir im Gegensatz zum VB Code ohne Vorzeichen arbeiten.

EWeiss 29. Mär 2019 13:41

AW: Farbwert zu Dezimal
 
Zitat:

Bei d = 153 (f=0.6) kann _alpha nicht mehr größer als 127 werden.
So sieht es besser aus ;)
Muss das nochmal genau gegen prüfen.

Dann muss die Vorgehensweise bei den anderen auch im etwa so sein.
Danke dir für die Geduld.

Zitat:

in welcher Procedure befindet sich der hier diskutierte Code? In procedure TSpectrum.Release;? Falls Ja: Früher hast du dort SpectrumData2D[] verwendet und jetzt imgSpectrum[]?
ist s immer noch SpectrumData2D wollte Klaus nur nicht vor den Kopf stoßen (habe es bei mir jedes mal geändert. kein problem.
Zitat:

Trotzdem malt dein Programm Dinge auf den Schirm. Da stimmt also etwas beim Ablauf nicht.
Was soll nicht stimmen ? Ist schon gut so.
Du musst Release von der Zeichenroutine komplett trennen.

es befindet sich dazwischen und manipuliert die Pixel mit denen die aus den Effekten errechneten werden.
So etwas wie ein Plugin innerhalb Draw!

gruss

Klaus01 29. Mär 2019 14:14

AW: Farbwert zu Dezimal
 
ein letztes update
alpha ist wieder ein Byte (ich fühl mich wohler damit)

Delphi-Quellcode:
           for y:= 0 to h do
             for x := 0 to w do
               begin

                 alpha := ((imgSpectrum[x,y] and $FF000000) shr 24) and $FF;
                 c := imgSpectrum[x,y] and $FFFFFF;

                 if d > alpha then
                   alpha := 0
                 else
                   alpha := alpha - d;

                 if alpha > 127 then
                   imgSpectrum[x,y] := c or ((alpha -256) shl 24)
                 else
                   imgSpectrum[x,y] := c or (alpha shl 24);
               end;
Grüße
Klaus

EWeiss 29. Mär 2019 16:11

AW: Farbwert zu Dezimal
 
@Klaus danke für deine Mühe und Einsatz mir zu helfen.
Habe leider noch ein anderes Problem um das zuverlässig testen zu können.

Wenn es dann mal funktioniert gibt es ein Update und die Meldung warum es nicht ging.
Vielleicht können dann andere davon etwas abschauen die ähnliche Probleme haben.

gruss

Michael II 29. Mär 2019 17:32

AW: Farbwert zu Dezimal
 
Delphi-Quellcode:
Was soll nicht stimmen ? Ist schon gut so.
Du musst Release von der Zeichenroutine komplett trennen.

es befindet sich dazwischen und manipuliert die Pixel mit denen die aus den Effekten errechneten werden.
So etwas wie ein Plugin innerhalb Draw!
Das Zeichnen der "Spektrum Daten" funktioniert.

Was in der mir vorliegenden Version nicht funktioniert
Zitat:

Was soll nicht stimmen ?
sind die Effekte. Dieser Teil macht gar nix, da der Input immer imgSpectrum=(0,...0) ist. Wenn du die Funktion Release(welcher Effekt, imgSpectrum) immer an der Stelle Release(welcher Effekt, imgSpectrum=0 ) auswertest, dann kannst du den Effekt auch weglassen.

Aufgrund von deinem
Zitat:

Was soll nicht stimmen ? Ist schon gut so.
hast du den Code offensichtlich inzwischen geändert und die Effekte werden wie du es erwartest gezeichnet. Ich gratuliere dir zum fertigen Programm :-D.

EWeiss 29. Mär 2019 17:38

AW: Farbwert zu Dezimal
 
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..
Zitat:

Zitat von Neutral General (Beitrag 1429081)
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

p80286 29. Mär 2019 20:22

AW: Farbwert zu Dezimal
 
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

EWeiss 29. Mär 2019 20:27

AW: Farbwert zu Dezimal
 
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

Amateurprofi 30. Mär 2019 04:05

AW: Farbwert zu Dezimal
 
Hallo Emil,
schau dir mal #1 genauer an.

Delphi-Quellcode:
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
Delphi-Quellcode:
//a := (((SpectrumData2D[X, Y] and $FF000000) div $1000000) and 255);
Ergibt immer a = 0
Deine fehlerhafte Umsetzung
Delphi-Quellcode:
a := ((SpectrumData2D[X, Y] shl 24) and 255);
ergibt ebenfalls immer a = 0
Die korrekte Umsetzung
Delphi-Quellcode:
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
Delphi-Quellcode:
a := a - d;
.
Da a = 0 war ist a jetzt abhängig von d im Bereich -255 .. 0

Delphi-Quellcode:
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
Delphi-Quellcode:
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.

Klaus01 30. Mär 2019 07:22

AW: Farbwert zu Dezimal
 
. ein 32bit Value and $FF maskiert den 32bit auf ein Byte.
$FFCCDD01 and $FF ($000000FF) ergibt $01
Bit Algebra :
0 and 0 = 0
0 and 1 = 0
1 and 0 = 0
1 and 1 = 1
Grüße Klaus

EWeiss 30. Mär 2019 08:12

AW: Farbwert zu Dezimal
 
Zitat:

Sei nicht böse, aber für mich ist dieser Thread Comedy pur.
Kein Problem bin ich nicht.
Ich habe früher alles gewusst.. warum auch immer ich es heute nicht mehr weis mag dahingestellt sein spielt auch keine weitere rolle.

Du hast es gut erklärt und aufgezeigt wo die Fehler liegen und warum es falsch ist so kann ich damit leben.

Die von dir benannten Probleme sind aber mittlerweile Asbach(Vergangenheit, erledigt, behoben) da Michael mich in einer PN schon darauf aufmerksam gemacht hat.
Wenigstens ziehst du nicht über mich her ohne aufzuzeigen wo die Probleme liegen.

Trotz alledem ob Comedy oder nicht keine eurer Versuche(Wissen? ??) hat irgendeine Verbesserung gebracht. Leider.
Die werte sind weiterhin falsch.

@Klaus
Zitat:

. ein 32bit Value and $FF maskiert den 32bit auf ein Byte.
$FFCCDD01 and $FF ($000000FF) ergibt $01
Es wäre nett wenn du mir sagen würdest auf was du dich beziehst.

Zitat:

//a := (((SpectrumData2D[X, Y] and $FF000000) div $1000000) and 255);
Ergibt immer a = 0
Rein Rechnerisch oder deine Annahme ;)
Denn das ist original von VB und die werte ändern sich ständig. (Weil nicht als Byte sondern als Long definiert)
Code:
Dim imgSpectrumData() As Long
Dim r As Long, g As Long, b As Long, a As Long
Code:
a = (((imgSpectrumData(x, y) And &HFF000000) \ &H1000000) And &HFF&)
Zitat:

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
Wo ist der Widerspruch? Oder das Problem

Code:
Dim d As Long
Fade ist ein property
Code:
Public Property Let Fade(ByVal fNewValue As Single)
Public Property Get Fade() As Single
Du solltest stets dir den vergleich vorher ansehen deine Berechnung erstellen und dann belegen warum etwas falsch ist, sein soll,
wenn genau das im Original alles Funktioniert was du hier als falsch unterstellst. (OK ich habe irrtümlich Byte definiert deshalb ist der wert so wie du sagst)
Keine Ahnung was das mit Comedy zu tun hat.


Zitat:

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.
Wurde schon lange behoben.

Ich bin davon ausgegangen das wenn die Funktion GdipCreateBitmapFromScan0 als Übergabe von Scan0 einen Pointer of PByte erwartet das es letztendlich sinnvoll wäre das Array direkt als Byte zu definieren.
Die Nachfolgenden Funktionen wie Release hatte ich zu diesen Zeitpunkt noch nicht übersetzt, konnte also zu dem Zeitpunkt nicht wissen ob der der Datentyp so korrekt ist.
Wie gesagt in VB ist eh fast alles Long.

Versuch doch mal ein Projekt zu übersetzen das zu 80 Prozent aus nur 1 DatenTyp besteht. :)
Das hier war insbesondere schwierig da es hier ums eingemachte ging siehe FFT.. kennst du die Datentypen nicht fällst du auf die Nase.

Zitat:

Meine Vermutung ist, dass SpectrumData2D ein Array of Array of UInt32 sein sollte und nicht ein Array of Array of Byte
Ja Vermutung nur mit deinem Cardinal in Verbindung mit Bytes a,r,g,b stürzt die Anwendung ab.

gruss

Klaus01 30. Mär 2019 08:22

AW: Farbwert zu Dezimal
 
Zitat:

Zitat von EWeiss (Beitrag 1429154)
@Klaus
Zitat:

. ein 32bit Value and $FF maskiert den 32bit auf ein Byte.
$FFCCDD01 and $FF ($000000FF) ergibt $01
Es wäre nett wenn du mir sagen würdest auf was du dich beziehst.

Hab' mich verlesen/ es falsch verstanden.
Grüße
Klaus

EWeiss 30. Mär 2019 08:24

AW: Farbwert zu Dezimal
 
Zitat:

Zitat von Klaus01 (Beitrag 1429155)
Zitat:

Zitat von EWeiss (Beitrag 1429154)
@Klaus
Zitat:

. ein 32bit Value and $FF maskiert den 32bit auf ein Byte.
$FFCCDD01 and $FF ($000000FF) ergibt $01
Es wäre nett wenn du mir sagen würdest auf was du dich beziehst.

Hab' mich verlesen/ es falsch verstanden.
Grüße
Klaus

Ach so ok Danke ;)

gruss

Amateurprofi 30. Mär 2019 16:26

AW: Farbwert zu Dezimal
 
Zitat:

Zitat von EWeiss (Beitrag 1429154)
Zitat:

.
Zitat:

//a := (((SpectrumData2D[X, Y] and $FF000000) div $1000000) and 255);
Ergibt immer a = 0
Rein Rechnerisch oder deine Annahme ;)
Denn das ist original von VB und die werte ändern sich ständig. (Weil nicht als Byte sondern als Long definiert)
Code:
Dim imgSpectrumData() As Long
Dim r As Long, g As Long, b As Long, a As Long
Code:
a = (((imgSpectrumData(x, y) And &HFF000000) \ &H1000000) And &HFF&)


Rechnerisch!
Natürlich unter der Voraussetzung dass SpectrumData2D[X, Y] ein Byte ist (wie von Dir angegeben und wie auch in Deinem Projekt deklariert)
Beispiel:
SpectrumData2D[X, Y] = $37
Code:
               $00000037
and           $FF000000
=             $00000000
div           $1000000 
=             $00000000
and           $000000FF
=             $00000000

Zitat:

Zitat:

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
Wo ist der Widerspruch? Oder das Problem
Nirgends ist da ein Widerspruch oder Problem.
Ich hab das nur ausgeführt um aufzuzeigen warum das spätere
Delphi-Quellcode:
a := a - d
zu einem Wert im Bereich -255 .. 0 führt-

Zitat:

Code:
Dim d As Long
Fade ist ein property
Code:
Public Property Let Fade(ByVal fNewValue As Single)
Public Property Get Fade() As Single
Du solltest stets dir den vergleich vorher ansehen deine Berechnung erstellen und dann belegen warum etwas falsch ist, sein soll,
wenn genau das im Original alles Funktioniert was du hier als falsch unterstellst. (OK ich habe irrtümlich Byte definiert deshalb ist der wert so wie du sagst)
Keine Ahnung was das mit Comedy zu tun hat.
Genau das habe ich getan.
Ich habe mir das genau angesehen und aufgezeigt, warum (im Falle FEffect=0) SpectrumData2D stets unverändert bleibt, was sicher nicht der Sinn der vielen Berechnungen ist.

Zitat:

Zitat:

Meine Vermutung ist, dass SpectrumData2D ein Array of Array of UInt32 sein sollte und nicht ein Array of Array of Byte
Ja Vermutung nur mit deinem Cardinal in Verbindung mit Bytes a,r,g,b stürzt die Anwendung ab.
Du erstellst (in uSpectrum.TSpectrum.CreateSpectrumBitmap) mit der Funktion Gdip_CreateBitmapFromScan0 eine Bitmap und übergibst der Funktion als Pixelformat "PixelFormat32bppARGB" und als Pointer auf die Farbinformationen "PByte(SpectrumData1D[0])", wobei
SpectrumData1D die gleichen Daten enthält wie SpectrumData2D.

PixelFormat32bppARGB sagt, dass die Farbinformationen 32 Bits je Pixel enthalten, je 8 Bits für Alpha, Rot, Grün, Blau.
SpectrumData1D enthält aber nur 1 Byte je Pixel.
Und das kommt Dir nicht komisch vor?

Du sagst auch, dass im Original VB-Code imgSpectrumData() As Long definiert ist.
Ungeachtet dessen definierst Du SpectrumData2D als Array of Array of Byte. (Weil der Parameter Scan0 als PByte definiert ist).
Und auch das kommt Dir nicht komisch vor?

Zu
Zitat:

Ja Vermutung nur mit deinem Cardinal in Verbindung mit Bytes a,r,g,b stürzt die Anwendung ab.
Na ja, einfach nur die Definition von SpectrumData2D von Byte auf Cardinal ändern, reicht natürlich nicht.
Selbstverständlich musst Du dann überall dort, wo Du auf SpectrumData2D zugreifst, Änderungen vornehmen.

Zitat:

Ich bin davon ausgegangen das wenn die Funktion GdipCreateBitmapFromScan0 als Übergabe von Scan0 einen Pointer of PByte erwartet das es letztendlich sinnvoll wäre das Array direkt als Byte zu definieren.
Die Nachfolgenden Funktionen wie Release hatte ich zu diesen Zeitpunkt noch nicht übersetzt, konnte also zu dem Zeitpunkt nicht wissen ob der der Datentyp so korrekt ist.
Wie gesagt in VB ist eh fast alles Long.
Es spricht ja auch nichts dagegen, SpectrumData2D auf Basis Bytes zu definieren, allerdings nicht nur 1 Byte je Pixel sondern 4 Bytes (= 1 UInt32).

EWeiss 30. Mär 2019 16:49

AW: Farbwert zu Dezimal
 
Zitat:

PixelFormat32bppARGB sagt, dass die Farbinformationen 32 Bits je Pixel enthalten, je 8 Bits für Alpha, Rot, Grün, Blau.
SpectrumData1D enthält aber nur 1 Byte je Pixel.
Und das kommt Dir nicht komisch vor?
Klar kommt mir das komisch vor wollte ja auch das 2 Dimensionale Array direkt an Gdip_CreateBitmapFromScan0 übergeben nur Gdip_CreateBitmapFromScan0
erwartet ein zusammenhängendes Array wie soll ich das sonst machen als wie von Neutral General vorgeschlagen.

Das 2 Dimensionale zu einen eindimensionales konvertieren..
Das anschließend das 2 Dimensionale nicht mehr das widergibt was es eigentlich sollte ist mir auch klar.
Nur bitte schön wie ändern wenn es nicht erlaubt ist.

Danke für deine Ausführung.

Zitat:

Nirgends ist da ein Widerspruch oder Problem.
JO habe ich im nachhinein auch so verstanden du bist ja von Byte ausgegangen.

Zitat:

Ungeachtet dessen definierst Du SpectrumData2D als Array of Array of Byte. (Weil der Parameter Scan0 als PByte definiert ist).
Und auch das kommt Dir nicht komisch vor?
Nein kam mir nicht komisch vor aus dem Grund weil ich nicht immer hin und her konvertieren will wenn es nicht nötig ist.
Daher schien mir das als beste Lösung.

Zitat:

Es spricht ja auch nichts dagegen, SpectrumData2D auf Basis Bytes zu definieren, allerdings nicht nur 1 Byte je Pixel sondern 4 Bytes (= 1 UInt32).
Habe es als LongWord definiert und es kommen nun auch Daten.. ist also nicht mehr 0
Den Fehler warum es abgestürzt ist habe ich ebenfalls gefunden.

Trotz alledem will es nicht so wie es soll.

Zitat:

Selbstverständlich musst Du dann überall dort, wo Du auf SpectrumData2D zugreifst, Änderungen vornehmen.
Nun mit der Originalen Version von VB bekomme ich das nicht gebacken.
Range error, Überlauf Fehler usw..

Es stimmt definitiv noch nicht.
Die anderen hier die ich getestet habe führen zu keinen Werten trotz des neuen DatenTyp LongWord.
Habe das jetzt erstmal auf Seite gelegt. Source ist ja oben, wenn es jemand integrieren will muss er es selbst bewerkstelligen.
Ich für meinen Teil bekomme das nicht gebacken.

Es macht auch nur sinn wenn man das Projekt herunter lädt und es direkt damit testet
imaginär etwas in den Raum stellen bringt nicht viel weil es in dem fall nur Vermutungen sind und nicht wirklich weiterhelfen.. auch wenn es gut gemeint ist.

Mitunter ist die Praxis etwas anderes als die Theorie.

gruss

Amateurprofi 1. Apr 2019 23:16

AW: Farbwert zu Dezimal
 
Liste der Anhänge anzeigen (Anzahl: 1)
@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.

EWeiss 2. Apr 2019 05:42

AW: Farbwert zu Dezimal
 
@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
Delphi-Quellcode:
GetObject(hDIB, sizeof(bm), @bm);


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


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


redimensionier mein Array of TBytes.
Delphi-Quellcode:
    SetLength(bmpBits, BitmapLength);


hole die bits und kopiere sie in mein 1D Array vom Type TBytes
Delphi-Quellcode:
    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

TiGü 2. Apr 2019 09:31

AW: Farbwert zu Dezimal
 
Zitat:

Zitat von EWeiss (Beitrag 1429296)
@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.

Zitat:

Zitat von EWeiss (Beitrag 1429296)
Leider sind hier einige Leute sehr überheblich einen Unfähigkeit vorwerfen und am ende selbst nichts auf die reihe kriegen.

:roll:

EWeiss 2. Apr 2019 12:02

AW: Farbwert zu Dezimal
 
Zitat:

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.
Wurde erledigt neue aktuelle Version ist oben.

Zitat:

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.
Es macht keine sinn da dieser darauf ausgelegt ist die Visualisierung wiederzugeben die man auch als "sehe was du hörst" (what you hear) bezeichnet.
Dazu wird waveInOpen mit entsprechender Callback verwendet.
Ich will nicht vom Stream sondern von der Soundkarte visualisieren. Unabhängig davon welcher Datei Typ abgespielt wird.

Was man installieren bzw. ins System integriert haben muss um es zu testen siehe Shot.
Zitat:

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.
Die GUI(Oberfläche) hat nichts mit dem eigentlichen Problem zu tun.
Ich stelle etwas zur Verfügung aus dem man für sich entsprechende Funktionen entnehmen kann oder auch nicht.
Hilfe ist willkommen aber kein muss und erwarten tue ich diese auch nicht.

Für den einen ist das Spielerei für den anderen eine willkommene Hilfe wenn es auch nur um diverse Dinge innerhalb des Quellcodes geht.
Was er daraus entnimmt ist seine Sache.
Es gibt keine gewähr das alles seine Richtigkeit hat.. Man kennt das ja! Aber ich hätte das alles anders gemacht. :)

gruss

Amateurprofi 2. Apr 2019 13:11

AW: Farbwert zu Dezimal
 
Zitat:

Zitat von EWeiss (Beitrag 1429296)
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;

EWeiss 2. Apr 2019 13:14

AW: Farbwert zu Dezimal
 
Zitat:

Ich bin mir vollkommen sicher dass die Funktion Array2DTo1D korrekt funktioniert
Du hast meinen Beitrag gelesen bzg. meiner Art das 1Dimensional Array zu erstellen? Das ist meines Erachtens der korrekte weg.
Danke wenn sie schneller ist werde ich sie in der neuen Version übernehmen.

gruss

Neutral General 2. Apr 2019 13:17

AW: Farbwert zu Dezimal
 
Nur als Hinweis: Ich hatte in dem alten Thread auch schon eine schnellere Version nachgereicht:

https://www.delphipraxis.net/1428640-post39.html

Wobei das von Byte-Arrays ausgeht. Da sollte wie bei Amateurprofi wahrscheinlich
Delphi-Quellcode:
rowLen * SizeOf(AArray[y][0])
als Länge für das Move übergeben werden.

EWeiss 3. Apr 2019 05:58

AW: Farbwert zu Dezimal
 
Es ist definitiv auf der Basis wie es in VB mit den Arrays gemacht wird nicht möglich.
Ich habe das Array rausgeschmissen und mache es jetzt auf meiner weise und siehe da es funktioniert.
Fade und Blur laufen..

Der Rest im anderen Thread
Trotzdem nochmals Danke an alle für den Versuch zu helfen.

Der ganze Mist mit Arrays, Datentypen, HEX, Dezimal brauch ich alles nicht es geht auch ohne.
Mein Problem war ich habe mich da fest gefressen.. ;)

gruss


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:24 Uhr.
Seite 2 von 2     12   

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz