![]() |
AW: Circular spectrum visualizer
Ach ja: Das GDIP_BitmapUnlockBits solltest du erst aufrufen nachdem du mit den Änderungen am Bild fertig bist.
|
AW: Circular spectrum visualizer
Zitat:
Aber du hast recht habe es geändert so funktioniert es. So gehts.
Delphi-Quellcode:
Das mit dem Array war einfach nichts.
case FEffect of
0: begin d := round(FFade * 255); if GDIP_BitmapLockBits(imgSpectrum, nil, ImageLockModeRead or ImageLockModeWrite, PixelFormat32bppARGB, @BitmapData) = OK then begin for Row := 0 to BitmapData.Height - 1 do begin RGBQuad := Scanline(BitmapData, Row); for Col := 0 to BitmapData.Width - 1 do begin Pixel := RGBQuad^; alpha := Pixel.rgbReserved; if alpha >= d then Pixel.rgbReserved := alpha - d else Pixel.rgbReserved := 0; RGBQuad^ := Pixel; inc(RGBQuad); end; end; GDIP_BitmapUnlockBits(imgSpectrum, @BitmapData); end; end; Ich habe versucht aus einen Leeren Bitmap Alpha werte zu extrahieren die nicht vorhanden waren. Wie soll das auch gehen bei einem leeren Array. Irgendwo wurde das in VB initialisiert aber der Punkt ist nicht auszumachen. Aber ich denke es geht auch so. gruss |
AW: Circular spectrum visualizer
Wie komme ich an die X und y Position von BitmapData? bzw. RGBQuad
Muss ich ersetzen.
Delphi-Quellcode:
GDIP_BitmapGetPixel(imgSpectrum, Integer(Col) + dx, Integer(Row) + dy, Color);
Die Farbe muss ich über die Position erfragen.
Delphi-Quellcode:
Get und Set Pixel ist noch nicht ersetzt.
1:
begin d := round(FFade * 10); if GDIP_BitmapLockBits(imgSpectrum, nil, ImageLockModeRead or ImageLockModeWrite, PixelFormat32bppARGB, @BitmapData) = OK then begin for Row := 0 to BitmapData.Height - 1 do begin RGBQuad := Scanline(BitmapData, Row); for Col := 0 to BitmapData.Width - 1 do begin Pixel := RGBQuad^; if (Col > 0) and (Row > 0) and (Col < BitmapData.Width - 1) and (Row < BitmapData.Height) then begin red := 0; green := 0; blue := 0; alpha := 0; for dy := -1 to 1 do begin for dx := -1 to 1 do begin GDIP_BitmapGetPixel(imgSpectrum, Integer(Col) + dx, Integer(Row) + dy, Color); alpha := alpha + ( Color and $ff000000 ) shr 24; red := red + ( Color and $00ff0000 ) shr 16; green := green + ( Color and $0000ff00 ) shr 8; blue := blue + ( Color and $000000ff ); end; end; red := red div 9; green := green div 9; blue := blue div 9; alpha := alpha div 9; if alpha >= d then Pixel.rgbReserved := alpha - d else Pixel.rgbReserved := 0; Color := blue or (green shl 8) or (red shl 16); GDIP_BitmapSetPixel(imgSpectrum, Col, Row, Color or (alpha shl 24)); end else GDIP_BitmapSetPixel(imgSpectrum, Col, Row, 0); end; GDIP_BitmapUnlockBits(imgSpectrum, @BitmapData); end; end; end; Das RGBQuad hole ich mir hier drüber.
Delphi-Quellcode:
EDIT:
function Scanline(BitmapData : TBitmapData; Stride: integer): PRGBQuad;
begin result := BitmapData.Scan0; inc(PByte(result), Stride * bitmapData.stride); end; Argghh.. Ich sehe gerade in der GDIObject.pas, die machen das auch nicht anders wie ich. Aber genau das will ich nicht.
Delphi-Quellcode:
Welchen sinn macht das? Dann kann ich mir GDIP_BitmapLockBits sparen macht so keinen sinn.
function TGPBitmap.GetPixel(x, y: Integer; out color: TGPColor): TStatus;
begin result := SetStatus(GdipBitmapGetPixel(GpBitmap(nativeImage), x, y, color)); end; Ich hole mir alle Pixel in einem Rutsch und muss dann doch wieder die Position des Pixel mit GdipBitmapGetPixel einholen? Was für ein Blödsinn. Oder? EDIT2: Ok die Lösung ist zurück zum Array. gruss |
AW: Circular spectrum visualizer
Auch wenn es mir jetzt schon leid tut und ich die Büchse der Pandora öffne:
Warum machst du das so mit Get/SetPixel und dieser for -1 to 1 Schleife? Du hast doch die Farbe schon durch das RGBQuad. Je nachdem wie du das definiert hast oder den Typ aus der Windows-Unit nimmst, kannst du doch auf RGBQuad.rgbBlue, RGBQuad.rgbGreen, RGBQuad.rgbRed, RGBQuad.rgbReserved (für Alpha: ![]() Zum Vertiefen: ![]() ![]() ![]() |
AW: Circular spectrum visualizer
Zitat:
Um die Effekte korrekt darzustellen benötige ich die X, Y Position eines jeden Pixel. Die habe ich aber in der Funktion BitmapData nicht zur Verfügung. So die originale Funktion der GDIP in der GDIObject.pas holt sich die Daten mit
Delphi-Quellcode:
Das ist aber definitiv falsch denn dann macht GDIPBitmapLockBits keinen sinn mehr.
function TGPBitmap.GetPixel(x, y: Integer; out color: TGPColor): TStatus;
begin result := SetStatus(GdipBitmapGetPixel(GpBitmap(nativeImage), x, y, color)); end; Gerade wegen der NICHT Verwendung von GdipBitmapGetPixel kann man die Schnelligkeit wie die Pixel über BitmapData gelesen werden erst erfassen. GdipBitmapGetPixel verursacht eine Auslastung der CPU von 30% Ich habe mir jetzt eine Hilfsfunktion geschrieben die macht folgendes.
Delphi-Quellcode:
Sie füllt mein leeres Array mit Daten an den benötigten X,Y Positionen.
function TSpectrum.BitmapLockBits(Img: LONG_PTR): TBitmapData;
var X, Y : integer; RGBQuad : PRGBQuad; Pixel : TRGBQuad; BitmapData : TBitmapData; function Scanline(BitmapData : TBitmapData; Stride: integer): PRGBQuad; begin result := BitmapData.Scan0; inc(PByte(result), Stride * bitmapData.stride); end; begin if GDIP_BitmapLockBits(Img, nil, ImageLockModeRead or ImageLockModeWrite, PixelFormat32bppARGB, @BitmapData) = OK then begin for Y := 0 to BitmapData.Height - 1 do begin RGBQuad := Scanline(BitmapData, Y); for X := 0 to BitmapData.Width - 1 do begin Pixel := RGBQuad^; SpectrumData2D[X, Y] := DWord(Pixel); inc(RGBQuad); end; end; Result := BitmapData; end; end; Jetzt arbeite ich wie bisher mit dem Array und kann mir GdipBitmapGetPixel ersparen. Die fertige Funktion vom Fire Effekt sieht so aus und ja sie läuft wie sie soll. ;)
Delphi-Quellcode:
gruss
2:
begin d := round(FFade * 64); BitmapData := BitmapLockBits(imgSpectrum); Buf := SpectrumData2D; if FSymmetrical then begin o := 0; s := 239 * 2; end else begin o := 0.5; s := 239; end; for Row := 0 to BitmapData.Height - 1 do begin RGBQuad := Scanline(BitmapData, Row); for Col := 0 to BitmapData.Width - 1 do begin Pixel := RGBQuad^; cx := Col / s - o; cy := Row / (BitmapData.Height - 1) - 0.5; radius := round(Sqrt(cx * cx + cy * cy)); dx := round((cx + o + 0.01 * cx * ((radius - 1) / 0.5)) * s); dy := round((cy + 0.5 + 0.01 * cy * ((radius - 1) / 0.5)) * (BitmapData.Height - 1)); alpha := Buf[dx, dy] shr 24; if alpha >= d then Pixel.rgbReserved := alpha - d else Pixel.rgbReserved := 0; Color := Buf[dx, dy] and $00FFFFFF; SKAERO_SplitColorARGB((Pixel.rgbReserved shl 24) or Color, _a, _r, _g, _b); Pixel.rgbBlue := _b; Pixel.rgbGreen := _g; Pixel.rgbRed := _r; Pixel.rgbReserved := _a; RGBQuad^ := Pixel; inc(RGBQuad); end; GDIP_BitmapUnlockBits(imgSpectrum, @BitmapData); end; end; |
AW: Circular spectrum visualizer
Zitat:
Die X/Y Position des aktuellen Pixels steht doch dann in den Schleifenvariablen (Row, Col) :gruebel: |
AW: Circular spectrum visualizer
Zitat:
Ja und deshalb weise ich sie dem Array zu.
Delphi-Quellcode:
Ich muss das so machen weil ich nachher dem Buf das Array zuweisen muss..
for X := 0 to BitmapData.Width - 1 do
begin Pixel := RGBQuad^; SpectrumData2D[X, Y] := DWord(Pixel); inc(RGBQuad); end;
Delphi-Quellcode:
Buf := SpectrumData2D;
PS: Wie komme ich sonst an die X, Y Position ohne sie in jedem Durchlauf in der Render Funktion des jeweiligen Effekts durchzulaufen? Das mache ich einmal in BitmapLockBits(imgSpectrum); und fertig. gruss |
AW: Circular spectrum visualizer
Wie kann ich die Pixel direkt auf 0 setzen? Ohne jede Farbe einzeln zuzuweisen.
Delphi-Quellcode:
gruss
Pixel.rgbBlue := 0;
Pixel.rgbGreen := 0; Pixel.rgbRed := 0; Pixel.rgbReserved := 0; |
AW: Circular spectrum visualizer
DWORD(Pixel) := 0;
|
AW: Circular spectrum visualizer
Zitat:
Lade das Projekt gleich hoch. Danke an alle für ihre Geduld. Schwierige Geburt! :) gruss |
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:56 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 by Thomas Breitkreuz