9

純粋なものを使用してキャンバスの領域をカラーブレンド(指定されたアルファ値で色付け)したいWindows GDI(したがって、GDI +、DirectXなど、OpenGL、アセンブラー、またはサードパーティライブラリなし)。

次の関数を作成しました。これを行うためのより効率的または簡単な方法があるかどうかを知りたいです。

procedure ColorBlend(const ACanvas: HDC; const ARect: TRect;
  const ABlendColor: TColor; const ABlendValue: Integer);
var
  DC: HDC;
  Brush: HBRUSH;
  Bitmap: HBITMAP;
  BlendFunction: TBlendFunction;
begin
  DC := CreateCompatibleDC(ACanvas);
  Bitmap := CreateCompatibleBitmap(ACanvas, ARect.Right - ARect.Left,
    ARect.Bottom - ARect.Top);
  Brush := CreateSolidBrush(ColorToRGB(ABlendColor));
  try
    SelectObject(DC, Bitmap);
    Windows.FillRect(DC, Rect(0, 0, ARect.Right - ARect.Left,
      ARect.Bottom - ARect.Top), Brush);
    BlendFunction.BlendOp := AC_SRC_OVER;
    BlendFunction.BlendFlags := 0;
    BlendFunction.AlphaFormat := 0;
    BlendFunction.SourceConstantAlpha := ABlendValue;
    Windows.AlphaBlend(ACanvas, ARect.Left, ARect.Top,
      ARect.Right - ARect.Left, ARect.Bottom - ARect.Top, DC, 0, 0,
      ARect.Right - ARect.Left, ARect.Bottom - ARect.Top, BlendFunction);
  finally
    DeleteObject(Brush);
    DeleteObject(Bitmap);
    DeleteDC(DC);
  end;
end;

この関数が何をすべきかについては、次の(識別:-)画像を参照してください。

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

そして、this image上記のようにフォームの左上にレンダリングできるコードは次のとおりです。

uses
  PNGImage;

procedure TForm1.Button1Click(Sender: TObject);
var
  Image: TPNGImage;
begin
  Image := TPNGImage.Create;
  try
    Image.LoadFromFile('d:\6G3Eg.png');
    ColorBlend(Image.Canvas.Handle, Image.Canvas.ClipRect, $0000FF80, 175);
    Canvas.Draw(0, 0, Image);
  finally
    Image.Free;
  end;
end;

純粋なGDIまたはDelphiVCLを使用してこれを行うためのより効率的な方法はありますか?

4

1 に答える 1

4

AlphaBlend で Canvas Drawing を試しましたか?

何かのようなもの

Canvas.Draw(Arect.Left, ARect.Top, ABitmap, AAlphaBlendValue);

ブレンドカラーの FillRect と組み合わせる

更新:そして、ここにいくつかのコードがあります。インターフェイスに可能な限り近いですが、純粋な VCL です。
それほど効率的ではないかもしれませんが、はるかに単純です (そして多少移植性があります)。
レミーが言ったように、疑似永続的な方法でフォームにペイントするには、OnPaint を使用する必要があります...

procedure ColorBlend(const ACanvas: TCanvas; const ARect: TRect;
  const ABlendColor: TColor; const ABlendValue: Integer);
var
  bmp: TBitmap;
begin
  bmp := TBitmap.Create;
  try
    bmp.Canvas.Brush.Color := ABlendColor;
    bmp.Width := ARect.Right - ARect.Left;
    bmp.Height := ARect.Bottom - ARect.Top;
    bmp.Canvas.FillRect(Rect(0,0,bmp.Width, bmp.Height));
    ACanvas.Draw(ARect.Left, ARect.Top, bmp, ABlendValue);
  finally
    bmp.Free;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  Image: TPNGImage;
begin
  Image := TPNGImage.Create;
  try
    Image.LoadFromFile('d:\6G3Eg.png');
    ColorBlend(Image.Canvas, Image.Canvas.ClipRect, $0000FF80, 175);
    Canvas.Draw(0, 0, Image);
    // then for fun do it to the Form itself
    ColorBlend(Canvas, ClientRect, clYellow, 15);
  finally
    Image.Free;
  end;
end;
于 2012-05-10T20:55:48.443 に答える