![]() |
Farbtöne (mit Tollerenz) in einem Bild ersetzen
Hallo zusammen,
Ich suche nach einer Möglichkeit, wie ich mit GDI+ bestimmte Farbbereiche durch eine definierte Farbe (performant) ersetzen kann? Mit Scannline ist dies viel zu langsam. Mit dem Net-Framework AForge funktioniert dies mit ColorFiltering. Und auch mit OpenCV gibt es Möglichkeiten. Nur möchte ich weder einen NET- Wrapper, noch zusätzliche DLL's einsetzen. Hat jemand so etwas schon einmal gemacht und kann mir hier einen Tipp geben? |
AW: Farbtöne (mit Tollerenz) in einem Bild ersetzen
Naja auch andere Bibliotheken oder Techniken müssen früher oder später alle Pixel des Bildes durchschlaufen und sich die Farbtöne jedes Pixels anschauen (und merken) um so etwas wie "Colorfiltering" bereitstellen zu können. Und das wird wahrscheinlich auch über Scanline (Bzw. direkten Zugriff auf die Pixeldaten - was Scanline ja quasi ist) gehen.
Wie ist denn dein Code? |
AW: Farbtöne (mit Tollerenz) in einem Bild ersetzen
Scanline ist schon schnell, wenn nicht machst du was falsch.
|
AW: Farbtöne (mit Tollerenz) in einem Bild ersetzen
Wie bereits beschrieben, suche ich eine Möglichkeit mit GDI+ mit dem Ziel, dass die Operation von der GPU durchgeführt wird. Mit openCV benötige ich für die reine Operation, bei einem jpg, mit der Auflösung von 1170 * 850 und 24 Bittiefe irgend etwas um 1 ms (Mit GetTickCount nicht messbar).Da ich hier mit einer dll arbeiten muss, benötige ich mit dem zusätzlichen Ladeaufwand des jpg insgesamt ca 47 ms! Mit Scanline bin ich noch nicht einmal im Ansatz in diesen Bereich gekommen. Zumal ich auch noch unnötig die CPU belaste, die ich für andere Dinge benötige. Nur möchte ich ungern zusätzliche dll's verwenden.
Daher die Suche nach einer Möglichkeit über GDI+. Wer hat da eine Idee? |
AW: Farbtöne (mit Tollerenz) in einem Bild ersetzen
Zitat:
Hast du dir denn schon mal GDI+ angeschaut ob es da auf den ersten Blick was gibt, was nützlich aussieht? |
AW: Farbtöne (mit Tollerenz) in einem Bild ersetzen
erstelle eine Colormatrix
![]() ![]()
Delphi-Quellcode:
übergebe die Farbwerte.. r, g, b
ColorMatrixFlags = (
ColorMatrixFlagsDefault, ColorMatrixFlagsSkipGrays, ColorMatrixFlagsAltGray ); TColorMatrixFlags = ColorMatrixFlags; ColorMatrix = packed array[0..4, 0..4] of Single; TColorMatrix = ColorMatrix; PColorMatrix = ^TColorMatrix; Sample.
Delphi-Quellcode:
Du benötigst zum setzen der Farb Attributeif (nRed <> 0) or (nGreen <> 0) or (nBlue <> 0) then begin if (nRed <> 0) then sR := (nRed / 128.0) else sR := 1.0; if (nGreen <> 0) then sG := (nGreen / 128.0) else sG := 1.0; if (nBlue <> 0) then sB := (nBlue / 128.0) else sB := 1.0; sN := 0.0001; // Farb Matrix füllen // Red Green Blue Alpha W c2[0][0] := sR; c2[1][0] := 0.0; c2[2][0] := 0.0; c2[3][0] := 0.0; c2[4][0] := 0.0; // Red c2[0][1] := 0.0; c2[1][1] := sG; c2[2][1] := 0.0; c2[3][1] := 0.0; c2[4][1] := 0.0; // Green c2[0][2] := 0.0; c2[1][2] := 0.0; c2[2][2] := sB; c2[3][2] := 0.0; c2[4][2] := 0.0; // Blue c2[0][3] := 0.0; c2[1][3] := 0.0; c2[2][3] := 0.0; c2[3][3] := 1.0; c2[4][3] := 0.0; // Alpha c2[0][4] := sN; c2[1][4] := sN; c2[2][4] := sN; c2[3][4] := 0.0; c2[4][4] := 1.0; // W if cMdone then begin MoveMemory(@c1, @cM, 100); cM := MatMultiply(c1, c2); end else begin MoveMemory(@cM, @c2, 100); cMdone := true; end; end; if cMdone then begin GdipCreateImageAttributes(imgAttr); GdipSetImageAttributesColorMatrix(imgAttr, ColorAdjustTypeDefault, true, @cM, @gM, ColorMatrixFlagsDefault); end; GdipSetInterpolationMode(graphics, ObjItem.quality); GdipDrawImageRectRectI(graphics, img, PosX, PosY, wD, hD, xS, yS, wS, hS, 2, imgAttr, ImgAbort, nil); API's GdipCreateImageAttributes GdipSetImageAttributesColorMatrix GdipDisposeImageAttributes zum zeichnen Ein Image vom Bitmap-Source über GdipCreateBitmapFromScan0 erstellen das du in der Farbe verändern willst. API's GdipCreateBitmapFromScan0 GdipCreateFromHDC GdipSetInterpolationMode GdipDrawImageRectRectI GdipDeleteGraphics GdipDisposeImage Willst du nun noch den Alpha Wert verändern dann musst du auch hier das jeweilige Byte im Array ändern. Siehe..
Delphi-Quellcode:
if (Alpha < 255) then begin sT := (min(254, Alpha) / 255.0); // Farb Matrix füllen // Siehe Transparenz! in row 4, column 4 c2[0][0] := 1.0; c2[1][0] := 0.0; c2[2][0] := 0.0; c2[3][0] := 0.0; c2[4][0] := 0.0; c2[0][1] := 0.0; c2[1][1] := 1.0; c2[2][1] := 0.0; c2[3][1] := 0.0; c2[4][1] := 0.0; c2[0][2] := 0.0; c2[1][2] := 0.0; c2[2][2] := 1.0; c2[3][2] := 0.0; c2[4][2] := 0.0; c2[0][3] := 0.0; c2[1][3] := 0.0; c2[2][3] := 0.0; c2[3][3] := sT; c2[4][3] := 0.0; c2[0][4] := 0.0; c2[1][4] := 0.0; c2[2][4] := 0.0; c2[3][4] := 0.0; c2[4][4] := 1.0; if cMdone then begin MoveMemory(@c1, @cM, 100); cM := MatMultiply(c1, c2); end else begin MoveMemory(@cM, @c2, 100); cMdone := true; end; end; Zitat:
gruss |
AW: Farbtöne (mit Tollerenz) in einem Bild ersetzen
Zitat:
![]() (Die gehen da quasi per Scanline durch das Bild und vergleichen die Pixelwerte) |
AW: Farbtöne (mit Tollerenz) in einem Bild ersetzen
Zitat:
Wenn es rein um die Manipulation von Pixeln geht, gut, da gibt's mehrere Möglichkeiten. Ich behaupte das eine direkte Bit Manipulation schneller ist als Scanline. OK bin raus da es ihm ums Hardware Rendern geht also über die GPU und das ist mit GDI+ nicht machbar. gruss |
AW: Farbtöne (mit Tollerenz) in einem Bild ersetzen
Zitat:
Zitat:
Von welcher Größenordnung reden wir denn? Wieviele JPEGs sind das denn so? Wie oft machst du das? Passiert das auf einen Server oder normalen PC? Welche GPU hat der? |
AW: Farbtöne (mit Tollerenz) in einem Bild ersetzen
Super EWeiss, danke. Die Info's hatten mir gefehlt. Kann es aber erst in ein paar Tagen testen. SOweit ich weiss nutzt GDI+ doch auch die Hardwarebeschleunigung. In dem Fall etwa nicht?
@TiGü: Klar stehen hinter GDI+ auch Dll's. Die sind jedoch bereits mit Windows auf dem System. Mit TStopWatch bekomme ich dann tatsächlich 14ms heraus (bei Verwendung von Opencv). Ich habe für jedes jpg max. 800ms zeit. In dieser Zeit muss eine Farbmaske drüber laufen und als Output dann je ein Farb- Grau und Schwarzweiss Bild. Sind quasi "normale" PC's mit Xeon- CPU und durchschnittliche NVidea. Sollte es mit GDI+ länger dauern, werde ich es eben doch mit opencv machen. Die Performance ist für mich sehr zufrieden stellend und ist sehr weit weg von AForge oder "Scanline". |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:38 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