5

Change HUE/Saturation私はEFGのWebサイトにある例を試しています: http ://www.efg2.com/Lab/Library/Delphi/Graphics/Color.htm

ここに画像の説明を入力してください

その例にある手法を使用して、一部のビットマップ(TImageで使用される)の色の値を変更したいと思います。私が直面している問題が1つあります。それは、透明なビットマップを持つTImagesにあります。背景色で色相を変更するのではなく、実際の画像データだけを変更したいと思います。

使用できるこのサンプル画像を取得します(ただし、透明度のある任意の画像を使用できます)。

ここに画像の説明を入力してください

  • Change HUE/Saturation上部のリンクからデモをダウンロードします。
  • 次に、上のボタン画像をImageOriginalにロードします。
  • DeltaSaturationを1に設定します。
  • プロジェクトを実行します。

いくつかの出力結果:

ここに画像の説明を入力してください ここに画像の説明を入力してください

ここで実行したいのは、元の背景色(左下の一番下のピクセルで定義)を維持し、画像の残りの部分の色相のみを調整することです。したがって、出力結果は実際には次のようになります(Paint.NETで編集)。

ここに画像の説明を入力してください ここに画像の説明を入力してください

より多くの画像データを含む別のサンプル画像を使用してテストすることを許可します。

ここに画像の説明を入力してください

最初の画像サンプルの場合と同様に、結果は次のようになります。

ここに画像の説明を入力してください ここに画像の説明を入力してください

私が望む結果が次のようになるとき:

ここに画像の説明を入力してください ここに画像の説明を入力してください

色相を変更した後、左下の一番下の色を元の色に置き換えるというアイデアがありましたが、これが正しいアプローチであるかどうかはわかりません。また、色を置き換える方法がわかりません。別の色のX。(グラフィックスと数学は私を超えています)。

たとえば、ミッキーの耳に2つの青い色の円を描き(青は左下のピクセルからの元の透明な色でした)、彼の目を着色した場合:

ここに画像の説明を入力してください

HUEを再度変更すると、次のようになります。

ここに画像の説明を入力してください

実際には次のようになります。

ここに画像の説明を入力してください

簡単に言えば、EFGデモで使用された方法によるものか、別のソリューションによるものかを問わず、画像の色相を変更したいと思います。HUEを変更しても、左下のピクセルで定義されている透明色は変更しないでください。これは、サンプル画像に示されているものと同じままである必要があります。

背景色を保持したまま、ビットマップの色相を変更するにはどうすればよいですか?

4

2 に答える 2

5

参照するコードは、画像上のすべてのピクセルをウォークして、色相/彩度を変更します。ピクセルに特定の色がある場合に干渉しないようにコードを変更できます。

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;
        ..
        ..


出力:  

ここにコードを入力してください

于 2012-05-16T16:54:30.790 に答える
2

理論的には、たとえば次のことができます。

まず、背景が何であるかを判断する必要があります...(おそらく、デルファイのように特定のピクセルの色を選択します...)

次に、この背景色を使用して、この色に基づいてマスクを作成できます...

画像を複製します...色相を適用します...

マスクを使用して 2 つのビットマップをマージします...

于 2012-05-16T16:40:47.250 に答える