![]() |
pf8Bit seltsames aussehen der Palette
Ich versuche verschiedene Paletten für das Spectrogram zu definieren.
Dazu habe ich die weite verändert. Die Initialisierung des Bitmap sieht wie folgt aus.
Delphi-Quellcode:
Das habe ich von
procedure TForm1.InitBitmap;
begin PalOrder := PAL_HOT; PalNeg := False; PalRGB := PAL_RGB; BuffBMP := TBitmap.Create; BuffBMP.Width := (StreamLength div 512 div 2) div Info.chans; BuffBMP.Height := 160; BuffBMP.HandleType := bmDIB; BuffBMP.PixelFormat := pf8Bit; ChangePalette(PalOrder, BuffBMP.Width, BuffBMP.Height, PaletteFile); BuffBMP.Canvas.Brush.Color := PaletteIndex(0); BuffBMP.Canvas.FillRect(BuffBMP.Canvas.ClipRect); end;
Delphi-Quellcode:
(StreamLength div 512 div 4) //pf24Bit
nach
Delphi-Quellcode:
(StreamLength div 512 div 2) //pf8Bit
geändert Mein Problem die Linien sind irgendwie gestretcht (bzw.. scheint da mit Scanline was nicht zu stimmen.) Zudem wird das Spectrogram nun revers gezeichnet. Es fängt von hinten an zu zeichnen. was kann ich da machen? Habe mal die unterschiede als Anhang addiert. gruss |
AW: pf8Bit selsames aussehen der Palette
Zitat:
24-Bit sind ja bekanntlich 3 Bytes und nicht 4. Ebenfalls ist 8-Bit ja nur 1 Byte. Und unabhängig davon macht das Verhältnis von 24-Bit = 4 und 8-Bit = 2 keinen Sinn für mich. Woher die 512 kommt, sehe ich grade auch nicht, aber das mag daran liegen, dass ich mich mit der BASS Library und Audio-Formaten generell nicht wirklich auskenne. |
AW: pf8Bit selsames aussehen der Palette
Zitat:
Zitat:
gruss |
AW: pf8Bit selsames aussehen der Palette
Zitat:
|
AW: pf8Bit selsames aussehen der Palette
Zitat:
Das Problem dabei ist das meistens dann wenn es darauf ankommt keine Kommentare addiert werden. Bei nicht würdigen Funktionen wird kommentiert und bei würdigen weniger. ;) Aber ich kenne jemand der sich 100% mit der Bass Lib auskennt hab den mal angeschrieben. gruss |
AW: pf8Bit selsames aussehen der Palette
Also 4 steht für die sample länge FLOAT.
Delphi Single = 4 Byte Ein Sample hat immer eine länge von 4 Bytes wenn das Flag BASS_SAMPLE_FLOAT verwendet wird. Anschließend noch mal durch 2 also für jeden Kanal 512 enthält 256 samples für den rechten und 256 samples für den linken Kanal. Das ist dann also nicht mein Problem muss ich so belassen wie es ist. Die 4 Bytes haben also nichts mit dem PixelFormat zu tun. Hmm vielleicht funktioniert das auf diese weise auch nicht, habe keine Palette für 24Bit. Und wenn ich über HSLtoRGB die Farben hole verändert das die 8Bit Palette. gruss |
AW: pf8Bit seltsames aussehen der Palette
Wird eine vorgefertigte Palette für ein Bitmap bei ScanLine nicht berücksichtigt?
Wenn doch warum sind dann hier alle Farbwerte "0" ?
Delphi-Quellcode:
gruss
if bScanLines then
begin SetLength(ScanLines, Bitmap.Height); for i := 0 to Length(ScanLines) - 1 do ScanLines[i] := Bitmap.Scanline[i]; end; |
AW: pf8Bit seltsames aussehen der Palette
Wie verwendest du Scanline hier? Insbesondere der Typ des Pointer wäre hier interessant.
|
AW: pf8Bit seltsames aussehen der Palette
Zitat:
gruss |
AW: pf8Bit seltsames aussehen der Palette
Zitat:
Was Medium und ich schätzen ist, dass du einen Pointertyp benutzt der größer als 1 Byte ist und du somit Pixel überspringst und dadurch seltsame Ergebnisse bekommst. |
AW: pf8Bit seltsames aussehen der Palette
Zitat:
Mit ScanLine habe ich ein generelles Problem In Verbindung mit der Palette funktioniert das nicht mehr. (Ab einer bestimmten Größe einer Datei) Bei Pixel geht es allerdings werden hier die Farben falsch dargestellt in Verbindung mit HSLtoRGB. gruss |
AW: pf8Bit seltsames aussehen der Palette
Wie vermutet.
Delphi-Quellcode:
Bei pf8Bit hast du keine RGBTriples mehr, sondern nur noch 1 Byte pro Pixel (8 Bit halt). Die richtigen Typen wären also:
ScanLines: TArray<PRGBTriple>;
P: PRGBTriple;
Delphi-Quellcode:
Das hier:
ScanLines: TArray<PByte>;
P: PByte;
Delphi-Quellcode:
geht dann aber natürlich auch nicht mehr! Wenn du ein Bitmap mit Palette hast, hast du keine Farbwerte mehr in den Pixeln stehen, sondern einen Index in die Palette!! Statt also die Farben in die Pixeldaten zu schreiben, musst du dir für jeden Pixel eine Farbe aus der Palette aussuchen und deren Index in die Pixeldaten schreiben. Bitmaps mit Paletten sind da anders als die ohne.
if Assigned(P) then HSLtoRGB(H, S, L, P^.rgbtRed, P^.rgbtGreen, P^.rgbtBlue);
|
AW: pf8Bit seltsames aussehen der Palette
Zitat:
Wie schon gesagt zu wenig Erfahrung mit der Handhabung von ScanLine. Zitat:
Muss mal sehn wie ich das berechne zu mal das Bitmap jetzt auch noch umgekehrt gezeichnet wird. gruss |
AW: pf8Bit seltsames aussehen der Palette
Boahh das dauert aber viel länger als mit den RGB Farben.
Delphi-Quellcode:
Da muss ich wohl noch was Tüfteln :)
if bScanLines then
begin QueryPerformanceCounter(timeDraw0); k := BuffBMP.Height - i - 1; P := BuffBMP.ScanLine[k]; Move(P[OffsetX], P[0], (BuffBMP.Width - OffsetX)); for m := 0 to pred(OffsetX) do P[BuffBMP.Width - OffsetX + m] := Value; QueryPerformanceCounter(timeDraw1); timeDraw := timeDraw + (timeDraw1-timeDraw0); end gruss |
AW: pf8Bit seltsames aussehen der Palette
Okay war bei Scanline nicht das Problem dass du in erster Linie vertikal zeichnen musst?
Wie wärs wenn du das Bitmap um 90° gedreht zeichnest. Also statt ||||||||||||||||||||||||||||||||||||||||| so: _ _ _ _ _ _ _ Und dann kannst du das Bitmap per PlgBlt um 90° gedreht dahin zeichnen wo es auftauchen soll. ScanLine würde ich dann wieder mit pf32Bit versuchen.
Delphi-Quellcode:
// Malt das Bitmap um 90° nach rechts gedreht auf ein Canvas
procedure DrawRotated90(ABitmap: TBitmap; ACanvas: TCanvas; AX, AY: Integer); var RotatePoints: Array[0..2] of TPoint; begin RotatePoints[0] := Point(ABitmap.Height+AX, AY); RotatePoints[1] := Point(ABitmap.Height+AX, ABitmap.Width+AY); RotatePoints[2] := Point(AY, AY); PlgBlt(ACanvas.Handle, RotatePoints[0], ABitmap.Canvas.Handle, 0, 0, ABitmap.Width, ABitmap.Height, 0, 0, 0); end; procedure TForm1.Button1Click(Sender: TObject); begin DrawRotated90(Image1.Picture.Bitmap, Canvas, 10, 10); end; |
AW: pf8Bit seltsames aussehen der Palette
Zitat:
Die Farben der Palette werden also nicht geändert wenn ich pf32Bit verwende. gruss |
AW: pf8Bit seltsames aussehen der Palette
Ich rede ja davon in diesem Fall KEINE Palette mehr zu benutzen.
Die Palette benutzt du doch nur weil du hoffst dass es damit schneller geht oder? Meine neue Idee für "schneller" ist halt 32-Bit "falschrum" malen und dann drehen. Siehe meinen vorherigen Post |
AW: pf8Bit seltsames aussehen der Palette
Zitat:
Vordefinierte Farben also. ;) Vorherige Version mit der Geschwindigkeit war ausreichend nur nach der Umstellung auf Paletten muss ich diese wieder optimieren was die Geschwindigkeit angeht incl. der korrekten Farben Zuweisung. gruss |
AW: pf8Bit seltsames aussehen der Palette
Nagut dann eben 8-Bit. Sollte aber vom Prinzip genauso funktionieren.
|
AW: pf8Bit seltsames aussehen der Palette
Zitat:
Es ist umgekehrt. Zitat:
gruss |
AW: pf8Bit seltsames aussehen der Palette
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
Die Tatsache DASS du vertikal zeichnest bzw. zeichnen musst macht es ja so langsam weil du mit Scanline ja nur zeilenweise Zeichnen kannst. Wenn du jetzt aber dein Bitmap um 90° drehst kannst du horizontal malen und Scanline effektiv benutzen. (siehe Anhang) Damit es dann auf dem Bildschirm wieder richtig rum ist musst du das Bitmap da dann (z.B.) per PlgBlt zurückdrehen. |
AW: pf8Bit seltsames aussehen der Palette
Zitat:
In dem vorherigen Beispiel mache ich es auch nicht anders (falsch oder richtig das wäre dann die frage) bin mir jetzt nicht so sicher weil hier mit Scanline die RGB Farben übergeben werden. Also eine ganz andere Sache. Hier ist nochmal mein Code.. Variablen anders vergeben zum besseren Verständnis. Ok zeichne Horizontal..
Delphi-Quellcode:
....
x: PByteArray;
Value: Byte;
Delphi-Quellcode:
Das Problem das ich habe ist das mein Bitmap dann umgekehrt nicht verdreht ist.
Value := round(Sqrt(Sqrt(Buffer[i + 1]) * 3 * BuffBMP.Width));
if bScanLines then begin QueryPerformanceCounter(timeDraw0); k := BuffBMP.Height - i - 1; x := BuffBMP.ScanLine[k]; Move(x[OffsetX], x[0], (BuffBMP.Width - OffsetX)); x[BuffBMP.Width - OffsetX] := Value; QueryPerformanceCounter(timeDraw1); timeDraw := timeDraw + (timeDraw1-timeDraw0); end Also das was eigentlich vorne sein soll ist hinten.. Da nutzt auch ein drehen um 90 grad nichts. Deine Vermutung das ich nicht vertikal zeichne mag das Problem mit meiner Performance sein. Dem will ich nicht widersprechen. EDIT: Ok denke verstehe was du meinst. Ich soll das leere Bitmap vorher drehen dann mit ScanLine Horizontal zeichen und anschließend wieder zurück drehen. Das kann ich aber nicht machen weil beim Fortschritt direkt gezeichnet wird. (sichtbar) gruss |
AW: pf8Bit seltsames aussehen der Palette
Man kann alle Zeilenanfänge auch vorher einmal per Scanline besorgen und zwischenspeichern.
Mit einem eindimensionalen Array, hätte man dann eine zweidimensionale Matrix (ZeilenArray-Offset + Spalten-Offset). Alle Zeilen liegen im Speicher hintereinander, allerdings oft gerne von unten nach oben und im Speicher ausgerichtet (Alignment). Heißt, daß man im Grunde nur einen Anfang bräuchte und die Pixelposition ausgerechnet werden könnte. Oder, falls es hier geht und praktikabel ist, man dreht seine Zeichenfunktion, damit sie eben nicht Spalten, sondern Zeilenweise arbeitet. |
AW: pf8Bit seltsames aussehen der Palette
Zitat:
Ist ohne ein zusätzliches Bitmap nicht ausführbar und zudem möchte ich ja den Fortschritt der Analysierung gleichzeitig visualisieren. Zitat:
Die x Position bekomme ich ja erst durch die Value.
Delphi-Quellcode:
Value := round(Sqrt(Sqrt(Buffer[i + 1]) * 3 * BuffBMP.Width));
Danke. gruss |
AW: pf8Bit seltsames aussehen der Palette
Zitat:
Himitsu schlägt vor das Bitmap so zu lassen wie es ist, aber eben nicht Linie für Linie vertikal zu zeichnen sondern zeilenweise von oben nach unten jeweils 1 Pixel jeder Linie zu zeichnen. |
AW: pf8Bit seltsames aussehen der Palette
Zitat:
Destotrotz brauche ich die Aktuelle (x) in dem Fall dann die Y Position welche ich erst durch die Value erhalte. Oder? gruss |
AW: pf8Bit seltsames aussehen der Palette
Nee nee :zwinker:, er hat die Zeichenfläche gedreht und nach dem Zeichnen halt nochmal das fertige Bild.
Man kann aber manchmal auch das Zeichnen drehen und nicht das Blatt. Es ginge auch mitten drinnen, das Drehen ![]() allerdings nicht hier, da hier ja an Allem vorbei direkt in den Speicher gegangen wird. |
AW: pf8Bit seltsames aussehen der Palette
Hatte eigentlich gedacht es wäre schwieriger die RGB Werte zu analysieren.
So kann man sich irren. In Realzeit wo nur eine Zeile ausgelesen und dann direkt gezeichnet wird ist das kein Problem aber alles in einem Zug geht ganz schön auf die Geschwindigkeit beim einlesen. Na ja wer hatte das gedacht. ;) Bin wohl zu blöd dafür. Sollte mich erst noch etwas mehr mit der eigentlichen Materie auseinandersetzen (ScanLIne) ;) EDIT: Mit dem umgedrehten Bitmap hab ich jetzt behoben. Durch das Move jeder einzelnen Zeile dauert das aber nun ewig :) gruss |
AW: pf8Bit seltsames aussehen der Palette
Zitat:
|
AW: pf8Bit seltsames aussehen der Palette
Also intern lässt du dein Bild einfach im Hochformat.
Da kannst du auch ganz einfach verschieben, da dort ja komplette Scanlines kopiert/verschoben werden können. Beim vertikal Scrollen wird in jeder Scanline der Inhalt um ein/paar Pixel nach links kopiert. Und dann nur für die Ausgabe entweder per PlgBlt das Bild drehen und anzeigen, oder über SetWorldTransform die Anzeige (das DC/TCanvas) drehen und dein Bild da im Hochformat rein malen. Und "Anzeigen" auch immer nur den sichtbaren Bereich des internen Bildes. |
AW: pf8Bit seltsames aussehen der Palette
Zitat:
Kann machen was ich will die Paletten funktionieren einfach nicht! So sollte Scope aussehen (Realtime kein Problem) und schnell genug. Aber als Komplettansicht schlägt das fehl. ![]() gruss |
AW: pf8Bit seltsames aussehen der Palette
Ich versuche immer noch den kram zu beschleunigen.
Delphi-Quellcode:
Ich habe jetzt den Auskommentierten Teil in eine eigene Schleife gebunden.
for i := 0 to BuffBMP.Height - 1 do
begin Value := round(Sqrt(Sqrt(Buffer[i + 1]) * 4 * BuffBMP.Width)); if bScanLines then begin QueryPerformanceCounter(timeDraw0); // X := BuffBMP.ScanLine[BuffBMP.Height - i - 1]; // Move(X[OffsetX], X[0], (BuffBMP.Width - OffsetX)); for m := 0 to pred(OffsetX) do X[BuffBMP.Width - OffsetX + m] := Value; QueryPerformanceCounter(timeDraw1); timeDraw := timeDraw + (timeDraw1 - timeDraw0); end else begin QueryPerformanceCounter(timeDraw0); BuffBMP.Canvas.Pixels[ColumnCounter, BuffBMP.Height - i] := Value; //RGB(R, G, B); QueryPerformanceCounter(timeDraw1); timeDraw := timeDraw + (timeDraw1-timeDraw0); end; end; Um beim zuweisen der Farben das ganze zu beschleunigen.
Delphi-Quellcode:
Das geht relativ schnell, das Problem ist nur das bei der Übergabe der Value das Bitmap nicht gefüllt wird.
for i := 0 to BuffBMP.Height - 1 do
begin X := BuffBMP.ScanLine[BuffBMP.Height - i - 1]; Move(X[OffsetX], X[0], (BuffBMP.Width - OffsetX)); end; Eigentlich müsste es doch egal sein ob ich den Pointer vorher verschiebe anstatt in der Schleife zum ermitteln der Farben. Wo ist mein Denkfehler? In X müssten doch die richtigen Pointer liegen.
Delphi-Quellcode:
X: PByteArray;
gruss |
AW: pf8Bit seltsames aussehen der Palette
Da sind dir irgendwo auf dem Weg die gepufferten Scanlines abhanden gekommen, und statt dessen in das PByteArray verwurschtelt, dass ein ganz anderes Ziel verfolgt.
Ich hätte da jetzt eher sowas in der Art gesehen:
Delphi-Quellcode:
Woher das xOffset und die Schleife mit "m" herkommen, ist mir ehrlich gesagt etwas schleierhaft gerade. Meiner Meinung nach braucht es die nicht, oder der Codeschnipsel war nicht ausreichend um die Notwendigkeit bzw. den Nutzen zu demonstrieren.
var
x: array of PByteArray; begin ... SetLength(x, BuffBMP.Height); for i := 0 to BuffBMP.Height - 1 do x[i] := BuffBMP.Scanline[BuffBMP.Height-i-1]; for i := 0 to BuffBMP.Height - 1 do begin Value := round(Sqrt(Sqrt(Buffer[i + 1]) * 4 * BuffBMP.Width)); if bScanLines then begin QueryPerformanceCounter(timeDraw0); X[i][ColumnCounter] := Value; QueryPerformanceCounter(timeDraw1); timeDraw := timeDraw + (timeDraw1 - timeDraw0); end else begin QueryPerformanceCounter(timeDraw0); BuffBMP.Canvas.Pixels[ColumnCounter, BuffBMP.Height - i] := Value; //RGB(R, G, B); QueryPerformanceCounter(timeDraw1); timeDraw := timeDraw + (timeDraw1-timeDraw0); end; end; |
AW: pf8Bit seltsames aussehen der Palette
Zitat:
Der XOffset diente dazu Das Bitmap von verschiedenen Seiten zu zeichnen. Zitat:
Durch das vorherige füllen des PByteArray ist die Geschwindigkeit nun genauso wie gewünscht. Palette stimmt auch. War aber ein anderes Problem) ;) gruss |
AW: pf8Bit seltsames aussehen der Palette
Delphi-Quellcode:
BuffBMP.Canvas.Pixels[ColumnCounter, BuffBMP.Height - 1 - i] := Value; //RGB(R, G, B);
|
AW: pf8Bit seltsames aussehen der Palette
Zitat:
Mein Fehler! gruss |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:30 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