次のような不透明度(アルファ透明度)機能を備えたキャンバスに描画しています。
var
Form1: TForm1;
IsDrawing: Boolean;
implementation
{$R *.dfm}
procedure DrawOpacityBrush(ACanvas: TCanvas; X, Y: Integer; AColor: TColor; ASize: Integer; Opacity: Byte);
var
Bmp: TBitmap;
I, J: Integer;
Pixels: PRGBQuad;
ColorRgb: Integer;
ColorR, ColorG, ColorB: Byte;
begin
Bmp := TBitmap.Create;
try
Bmp.PixelFormat := pf32Bit; // needed for an alpha channel
Bmp.SetSize(ASize, ASize);
with Bmp.Canvas do
begin
Brush.Color := clFuchsia; // background color to mask out
ColorRgb := ColorToRGB(Brush.Color);
FillRect(Rect(0, 0, ASize, ASize));
Pen.Color := AColor;
Pen.Style := psSolid;
Pen.Width := ASize;
MoveTo(ASize div 2, ASize div 2);
LineTo(ASize div 2, ASize div 2);
end;
ColorR := GetRValue(ColorRgb);
ColorG := GetGValue(ColorRgb);
ColorB := GetBValue(ColorRgb);
for I := 0 to Bmp.Height-1 do
begin
Pixels := PRGBQuad(Bmp.ScanLine[I]);
for J := 0 to Bmp.Width-1 do
begin
with Pixels^ do
begin
if (rgbRed = ColorR) and (rgbGreen = ColorG) and (rgbBlue = ColorB) then
rgbReserved := 0
else
rgbReserved := Opacity;
// must pre-multiply the pixel with its alpha channel before drawing
rgbRed := (rgbRed * rgbReserved) div $FF;
rgbGreen := (rgbGreen * rgbReserved) div $FF;
rgbBlue := (rgbBlue * rgbReserved) div $FF;
end;
Inc(Pixels);
end;
end;
ACanvas.Draw(X, Y, Bmp, 255);
finally
Bmp.Free;
end;
end;
procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
case Button of
mbLeft:
begin
IsDrawing := True;
DrawOpacityBrush(Form1.Canvas, X, Y, clRed, 50, 85);
end;
end;
end;
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
if (GetAsyncKeyState(VK_LBUTTON) <> 0) and
(IsDrawing) then
begin
DrawOpacityBrush(Form1.Canvas, X, Y, clRed, 50, 85);
end;
end;
procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
IsDrawing := False;
end;
描画DrawOpacityBrush()
手順は、私が最近尋ねた以前の質問に対する Remy Lebeau による更新でした: How to paint on a Canvas with Transparency and Opacity?
これは機能しますが、結果は私が現在必要としているものには満足できません。
現在、MouseMove でプロシージャが呼び出されるたびにDrawOpacityBrush()
、ブラシの楕円形が描画され続けます。キャンバス上でマウスを動かす速さによっては、出力が期待どおりにならないため、これは悪いことです。
これらのサンプル画像は、うまくいけばこれをよりよく説明するはずです:
-最初の赤いブラシ マウスをキャンバスの下から上にかなり速く動かしました。
- 2 番目の赤いブラシは、かなりゆっくり動かしました。
ご覧のとおり、不透明度は正しく描画されていますが、円も繰り返し描画され続けています。
代わりにやりたいことは次のとおりです。
(1)楕円の周りに不透明線を塗ります。
(2)楕円がまったく描画されないようにするオプションがあります。
この模擬サンプル画像は、どのように描画したいかのアイデアを与えるはずです:
3 つの紫色のブラシ ラインは、オプション (1)を示しています。
オプション (2)を実現するには、ブラシ ライン内の円が存在しないようにする必要があります。
これにより、必要な結果が得られることを期待してマウスをキャンバス上で必死に動かさずに、時間をかけて描画することができます。作成したばかりのブラシ ストロークに戻ることにした場合にのみ、その領域の不透明度が暗くなります。
このような描画効果を実現するにはどうすればよいですか?
TImage に描画できるようにしたいのですが、それは私が現在行っていることなので、TCanvas を関数またはプロシージャのパラメーターとして渡すのが理想的です。描画には、MouseDown、MouseMove、および MouseUp イベントも使用します。
これは、NGLN が提供するメソッドを使用して取得した出力です。
画像にも不透明度が適用されているようですが、ポリラインのみである必要があります。