Ich zeichne auf eine Leinwand mit Opazität (Alpha-Transparenz) Fähigkeiten wie so:Leinwandzeichnung - Wie kann ich diese Alpha-Zeichnungsroutine verbessern?
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;
Die DrawOpacityBrush()
Verfahren zeichnen ein Update von Remy Lebeau auf eine frühere Anfrage wurde ich vor kurzem gefragt: How to paint on a Canvas with Transparency and Opacity?
Während dies funktioniert, sind die Ergebnisse nicht zufrieden stellend mit dem, was ich jetzt brauche.
Derzeit jedes Mal, wenn die DrawOpacityBrush()
-Prozedur in MouseMove aufgerufen wird, wird die Pinselellipsenform gezeichnet. Das ist schlecht, denn je nachdem, wie schnell Sie die Maus über die Zeichenfläche bewegen, ist die Ausgabe nicht wie erhofft.
Diese Beispielbilder sollte dies besser hoffentlich verdeutlichen:
- Die erste rote Bürste ich die Maus bewegt ziemlich schnell aus dem Boden der Leinwand nach oben.
- Der zweite rote Pinsel bewegte ich viel langsamer.
Wie Sie sehen können, wird die Deckkraft korrekt gezeichnet, außer dass der Kreis auch weiterhin gezeichnet wird.
Was Ich mag wäre es stattdessen zu tun ist:
(1) Farbe mit einer Opazität Linie um die Ellipse.
(2) Haben Sie eine Option, um zu verhindern, dass Ellipsen überhaupt gezeichnet werden.
Diese Mock-Probe Bild soll eine Vorstellung davon, wie ich es gezeichnet werden möchte:
Die 3 lila Pinsel Linien zeigen Option (1).
Um Option (2) zu erreichen, sollten die Kreise in den Pinsellinien nicht da sein.
Dies sollte dann erlauben Sie Zeit beim Zeichnen zu nehmen, nicht verzweifelt bewegen Sie die Maus um die Leinwand in der Hoffnung, das gewünschte Ergebnis zu erhalten. Nur wenn Sie sich entscheiden, über den Pinselstrich, den Sie gerade gemacht haben, zurückzukehren, wird die Deckkraft für diesen Bereich dunkler usw.
Wie kann ich diese Art von Zeicheneffekten erzielen?
Ich möchte in der Lage sein, auf eine TImage als das, was ich gerade mache, zu zeichnen, so TCanvas als Parameter in einer Funktion oder Prozedur übergeben wäre ideal. Ich werde auch die MouseDown, MouseMove und MouseUp Ereignisse für meine Zeichnung verwenden.
Dies ist die Ausgabe ich die Methode von NGLN zur Verfügung gestellt bekommen mit:
Opazität scheint auch auf das Bild angewendet werden, es sollte nur die Poly Linien sein.
"Anforderungen klarer machen" ändert die Frage, nachdem jemand auf die vorliegende Frage geantwortet hat. Stellen Sie besser eine neue Frage und denken Sie sorgfältig über die Anforderungen nach. –
Nun, um fair zu sein, wenn das Beispiel, das ich gepostet habe, TCanvas verwendet, enthält die Antwort, die ich von NGLN erhielt, diesen Parameter nicht, sondern eine andere Methode. Vielleicht hätte ich Image1MouseDown anstelle von Form1MouseDown in meinem Beispiel verwenden sollen. Und der Titel der Frage sagt Canvas auch .. –