2012-05-16 18 views
5

Ich habe mit dem Change HUE/Saturation Beispiel auf der EFG Website experimentieren: http://www.efg2.com/Lab/Library/Delphi/Graphics/Color.htmHUE einer Bitmap ändern, aber Hintergrundfarbe beibehalten?

enter image description here

Ich möchte die Techniken in diesem Beispiel gefunden verwenden, um die Farbwerte von einigen Bitmaps zu ändern (zu auf ein verwendet werden TBild). Es gibt ein Problem, dem ich gegenüberstehe, und zwar bei TImages mit transparenten Bitmaps. Ich möchte nicht, dass die Hintergrundfarbe ihren HUE ändert, sondern nur die eigentlichen Bilddaten.

dieses Beispielbild Nehmen wir können (kann verwendet werden, obwohl jedes Bild mit Transparenz) arbeiten:

enter image description here

  • die Change HUE/Saturation Demo an der Spitze aus dem Link zum Download.
  • Jetzt laden Sie die Schaltfläche Bild oben in das BildOriginal.
  • Stellen Sie die Delta-Sättigung auf 1 ein.
  • Führen Sie das Projekt aus.

Einige Ausgabeergebnisse:

enter image description hereenter image description here

Was ich hier passieren möchte, ist die ursprüngliche Hintergrundfarbe halten (von unten definiert am weitesten links stehende Pixel) und nur den Farbton für den Rest anpassen des Bildes. So würden die Ausgabeergebnisse tatsächlich aussehen wie diese (herausgegeben in Paint.NET):

enter image description hereenter image description here

Erlauben Sie mir ein anderes Beispielbild zu verwenden, um zu testen mit, dass mehr Bilddaten enthält:

enter image description here

nach wie vor mit dem ersten Bild Probe, könnten die Ergebnisse so etwas wie:

enter image description hereenter image description here

Wenn die Ergebnisse Ich mag so sein wollen:

enter image description hereenter image description here

Eine Idee, die ich nach der Farbtonänderung war hatte, ersetzen Sie den Boden am weitesten links stehende Farbe mit der Farbe aus dem Original, aber ich bin nicht sicher, ob dies der richtige Ansatz ist oder nicht, und selbst wenn es so ist, bin ich mir nicht sicher, wie ich die Farbe X für eine andere Farbe ersetzen soll. (Grafik und Mathematik ist mir nicht).

Zum Beispiel, wenn ich zwei blaue Farbe Kreise auf Mickey Ohr zog (die blaue die ursprüngliche transparente Farbe von unten gewesen meisten Pixel links) und auch seine Augen gefärbt:

enter image description here

die HUE wieder ändern kann wie folgt aussehen:

enter image description here

wenn in der Tat sollte es dieses mag:

enter image description here

Einfach gesagt möchte ich die HUE eines Bildes ändern, ob es durch die Methoden aus der EFG-Demo oder eine andere Lösung verwendet wird. Die transparente Farbe, wie sie vom untersten linken Pixel definiert wird, sollte nicht geändert werden, wenn der HUE geändert wird. Dies sollte derselbe bleiben wie in den Beispielbildern gezeigt.

Wie kann ich den HUE-Wert einer Bitmap ändern, während die Hintergrundfarbe beibehalten wird?

Antwort

5

Der Code, auf den Sie verweisen, durchläuft alle Pixel im Bild, um den Farbton/die Sättigung zu ändern. Sie können den Code ändern, damit es nicht stört, wenn ein Pixel eine bestimmte Farbe hat:

PROCEDURE TFormChangeHS.UpdateBitmap; 
    .. 
    S    : TReal; 
    V    : TReal; 

    FixColor: TRGBTriple;       // New variable 
BEGIN 
    DeltaSaturation := SpinEditDeltaSaturation.Value; 
    NewHue := TrackBarHue.Position; 

    Bitmap := TBitmap.Create; 
    TRY 
    Bitmap.Width := ImageOriginal.Width; 
    Bitmap.Height := ImageOriginal.Height; 
    Bitmap.PixelFormat := ImageOriginal.Picture.Bitmap.PixelFormat; 
    ASSERT(Bitmap.PixelFormat = pf24bit); 

    // save bottom left color 
    FixColor := PRGBTripleArray(
        ImageOriginal.Picture.Bitmap.ScanLine[Bitmap.Height - 1])^[0]; 
    //-- 

    FOR j := 0 TO Bitmap.Height-1 DO 
    BEGIN 
     RowIn := ImageOriginal.Picture.Bitmap.Scanline[j]; 
     RowOut := Bitmap.Scanline[j]; 
     FOR i := 0 TO Bitmap.Width-1 DO 
     BEGIN 
     WITH RowIn[i] DO 
     BEGIN 

      // copy the color to target and continue with next iteration 
      if (RowIn[i].rgbtBlue = FixColor.rgbtBlue) and 
       (RowIn[i].rgbtGreen = FixColor.rgbtGreen) and 
       (RowIn[i].rgbtRed = FixColor.rgbtRed) then begin 
      RowOut[i] := FixColor; 
      Continue; 
      end; 
      //-- 

      // convert pixel coordinates to HSV 
      RGBtoHSV(rgbtRed, rgbtGreen, rgbtBlue, H, S, V); 
     END; 
     .. 
     .. 


Ausgang:

enter code here

+0

Ausgezeichnete Sertac, das funktioniert, wie ich gehofft hatte. Könnten Sie bitte diese Zeile erklären: 'FixColor: = PRGBTripleArray ( ImageOriginal.Picture.Bitmap.ScanLine [Bitmap.Height - 1])^[0];' Ist das äquivalent zur Verwendung von Pixels [], aber es ist schneller? Ich bin mir nicht sicher, was das^[0] Bit tut. –

+1

@Blobby - Sie können tatsächlich das '^' löschen, es wird nicht benötigt (was der PRGBTripleArray zeigt, aber der Compiler kann es ohne das '^' auflösen), der linke Teil ist ein TRGBTripleArray, daher ist [0] das erstes Element des Arrays. Die Geschwindigkeit ist nicht wichtig, da wir nur ein Pixel lesen, Sie können stattdessen Pixel verwenden. –

+0

Vielen Dank für das Aufräumen. Ich glaube, ich verstehe den anderen Code auch - "if (RowIn [i] .rgbtBlue = FixColor.rgbtBlue) und" .. ist dies überprüft die Farbe jedes Pixels im RGB-Kanal, und wenn jede der RGB-Komponente zu FixColor entspricht Sie konvertieren es in die FixColor? –

2

Theoretisch können Sie zum Beispiel:

Zuerst müssen Sie bestimmen, was der Hintergrund ist ... (wahrscheinlich die Farbe eines bestimmten Pixels Kommissionierung wie delphi tut ...)

Dann mit dieser Hintergrundfarbe können Sie eine Maske auf der Grundlage dieser Farbe erstellen ...

Sie das Bild kopieren ... anwenden, den Farbton ...

Sie fusionieren Ihre 2 Bitmaps unter Verwendung der Maske ...

+0

wie eine gute Idee klingt, ich habe noch nie mit Masken gearbeitet, bevor jedoch. –

+1

überprüfen Sie sie .. sie können sehr nützlich sein, o) der schwierigste Teil ist vielleicht, ** effizient ** die Maske mit ** komprimierten ** JPEG – Whiler

+0

Wie es Sertac ist die Antwort funktioniert perfekt, aber dank Ihrer Antwort ich denke, ich kann weiter in Masken schauen, ich habe eine Idee, was sie sind, aber ich werde definitiv einige Informationen über sie bekommen :) –

Verwandte Themen