AW: Pfeil auf einem Image platzieren
Zitat:
Hier der Code für den Pfeil:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin CancelDraw := not CancelDraw; end; procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single); begin LfX := X; LfY := Y; Down := true; end; procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Single); procedure DrawArrow(Canvas: TCanvas; X1, Y1, X2, Y2: Single; LineSize: Integer); var Angle: Double; X, Y: Single; lBrush: TStrokeBrush; begin lBrush := TStrokeBrush.Create(TBrushKind.Solid, TAlphaColors.Blue); try lBrush.Thickness := LineSize; lBrush.Cap := TStrokeCap.Round; Canvas.DrawLine(TPointF.Create(X1, Y1), TPointF.Create(X2, Y2), 100, lBrush); Angle := ArcTan2(Y2 - Y1, X2 - X1); X := X2 - (20 * Cos(Angle - Pi / 6)); Y := Y2 - (20 * Sin(Angle - Pi / 6)); Canvas.DrawLine(TPointF.Create(X2, Y2), TPointF.Create(X, Y), 100, lBrush); X := X2 - (20 * Cos(Angle + Pi / 6)); Y := Y2 - (20 * Sin(Angle + Pi / 6)); Canvas.DrawLine(TPointF.Create(X2, Y2), TPointF.Create(X, Y), 100, lBrush); finally lBrush.Free; end; end; begin if Down then begin Self.Canvas.BeginScene; if CancelDraw then Self.Canvas.Clear(TAlphaColorRec.Darkgrey); DrawArrow(Self.Canvas, LfX, LfY, X, Y, 5); Self.Canvas.EndScene; end; end; procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single); begin Down := false; end; |
AW: Pfeil auf einem Image platzieren
Das Beispiel ist brutal simpel gehalten. Das dient ja nur dazu zu zeigen das es auch einfach geht ;-)
Was funktionieren sollte ist, ein Image zu nehmen in dem das Bild angezeigt wird und ein durchsichtiges Panel darüber zu legen in den Du zeichnen kannst. Dann sind Image und Pfeil permanent voneinander getrennt. |
AW: Pfeil auf einem Image platzieren
Zitat:
ich glaube, diese ganze Thema Canvas/Bitmap/Image, liegt mir absoult nicht :| Könntest du mir nochmal auf die Sprünge helfen? Ich hab mir jetzt was zusammen geschrieben, das mir bei jedem MouseDown, MouseMove, MouseUp ein neues TImage über meinem eigentlichen TImage erzeugt, auf dem kann ich dann zeichnen. Zugriff auf jede "Ebene" hab ich über ein TArray. Ich scheitere jetzt an der Aufgabe, diese Images einfach zu einem einzigen Image zusammen zu führen und in eine Date Abzuspeichern, ich versteh gar nicht was daran so kompliziert ist :pale: |
AW: Pfeil auf einem Image platzieren
Zeig mal was du hast. Vermutlich siehst du nur gerade den Wald vor lauter Bäumen nicht.
|
AW: Pfeil auf einem Image platzieren
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
Hab das Projekt mal in den Anhang geladen, das Konstrukt mit den Helper Klassen bitte einfach ignorieren:oops:, hab das nur Quick&Dirty als Proof of Concept zusammen geschmissen. |
AW: Pfeil auf einem Image platzieren
Zitat:
ich habe das Wochenende genutzt und mich nochmal neu sortiert. Ich glaube mein Ansatz war maximal zu kompliziert. Ich hab dein Projekt nochmal angepasst und arbeite nicht mehr mit unterschiedlichen ebenen, sondern arbeite direkt auf dem Image1.Bitmap.Canvas. Habe mittlerweile auch verstanden, dass Image1.Canvas und Image1.Bitmap.Canvas nicht das selbe sind. Könntest du den Code nochmal kurz überfliegen, ob dir etwas einfällt wo du sagen würdest, mach das auf keinen Fall so. :coder2: Merci :)
Delphi-Quellcode:
unit FMX_PaintFrm;
interface uses System.SysUtils, System.Types, System.UITypes, System.UIConsts, System.Classes, System.Variants, System.Math, FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.StdCtrls, FMX.Controls.Presentation, FMX.Objects; type TForm1 = class(TForm) btn_save: TButton; Image1: TImage; btn_Turn: TButton; btn_prev: TButton; procedure btn_prevClick(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure btn_saveClick(Sender: TObject); procedure btn_TurnClick(Sender: TObject); procedure FormShow(Sender: TObject); procedure Image1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single); procedure Image1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Single); procedure Image1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single); private { Private declarations } ImageToBitmapFactorWidth: Single; ImageToBitmapFactorHeight: Single; Down: Boolean; ImageState: Tarray<TBitmap>; ImageStateStage: Integer; procedure AppendNewState; procedure DrawArrow(Canvas: TCanvas; X1, Y1, X2, Y2: Single; LineSize: Integer; aColor: TAlphaColor); public { Public declarations } end; var Form1: TForm1; implementation {$R *.fmx} procedure TForm1.DrawArrow(Canvas: TCanvas; X1, Y1, X2, Y2: Single; LineSize: Integer; aColor: TAlphaColor); var Angle: Double; X, Y: Single; lBrush: TStrokeBrush; begin lBrush := TStrokeBrush.Create(TBrushKind.Solid, aColor); try lBrush.Thickness := LineSize; lBrush.Cap := TStrokeCap.Round; lBrush.Color := aColor; Canvas.DrawLine(TPointF.Create(X1, Y1), TPointF.Create(X2, Y2), 100, lBrush); Angle := ArcTan2(Y2 - Y1, X2 - X1); X := X2 - (20 * Cos(Angle - Pi / 6)); Y := Y2 - (20 * Sin(Angle - Pi / 6)); Canvas.DrawLine(TPointF.Create(X2, Y2), TPointF.Create(X, Y), 100, lBrush); X := X2 - (20 * Cos(Angle + Pi / 6)); Y := Y2 - (20 * Sin(Angle + Pi / 6)); Canvas.DrawLine(TPointF.Create(X2, Y2), TPointF.Create(X, Y), 100, lBrush); finally lBrush.Free; end; end; procedure TForm1.btn_prevClick(Sender: TObject); begin if ImageStateStage = 0 then if High(ImageState) = -1 then exit else ImageStateStage := High(ImageState); Inc(ImageStateStage, -1); Image1.Bitmap.Canvas.BeginScene; try Image1.Bitmap.Canvas.DrawBitmap(ImageState[ImageStateStage], ImageState[ImageStateStage].BoundsF, Image1.Bitmap.BoundsF, 1.0, true); finally Image1.Bitmap.Canvas.EndScene; end; end; procedure TForm1.FormDestroy(Sender: TObject); var lBitmap: TBitmap; begin for lBitmap in ImageState do lBitmap.Free; end; procedure TForm1.btn_saveClick(Sender: TObject); begin Image1.Bitmap.SaveToFile('C:\Users\Administrator\Desktop\BetterCallSaul.jpg'); end; procedure TForm1.btn_TurnClick(Sender: TObject); begin Image1.Bitmap.Rotate(90); end; procedure TForm1.FormShow(Sender: TObject); begin AppendNewState; ImageToBitmapFactorWidth := Image1.Bitmap.Width / Image1.Width; ImageToBitmapFactorHeight := Image1.Bitmap.Height / Image1.Height; end; procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single); begin Down := true; end; procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Single); var LastImage: TBitmap; begin if Down then begin LastImage := ImageState[high(ImageState)]; Image1.Bitmap.Canvas.BeginScene; try Image1.Bitmap.Canvas.DrawBitmap(LastImage, LastImage.BoundsF, Image1.Bitmap.BoundsF, 1.0, true); DrawArrow(Image1.Bitmap.Canvas, Image1.PressedPosition.X * ImageToBitmapFactorWidth, Image1.PressedPosition.Y * ImageToBitmapFactorHeight, X * ImageToBitmapFactorWidth, Y * ImageToBitmapFactorHeight, 4, TAlphaColors.Green); finally Image1.Bitmap.Canvas.EndScene; end; end; end; procedure TForm1.Image1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single); begin Down := false; AppendNewState; end; procedure TForm1.AppendNewState; var lBitmap: TBitmap; begin lBitmap := TBitmap.Create(Image1.Bitmap.Width, Image1.Bitmap.Height); lBitmap.CopyFromBitmap(Image1.Bitmap); ImageState := ImageState + [lBitmap]; end; end. |
AW: Pfeil auf einem Image platzieren
Eigentlich enthält deine Frage ja schon die Antwort. Auf keinen Fall ;-) Ich würde jetzt nicht sagen dass man das auf keinen Fall so machen sollte, es gibt für fast alles eine Anwendung.
Aber das Bild neu zu zeichnen und dann den Pfeil drauf, für jedesmal das man die Maus beweget ...das geht schon deutlich Richtung Ressourcenverschwendung. Allerdings finde ich jetzt auf die schnelle auch keine andere Lösung. Das FMX Panel kann nicht durchsichtig. Jedenfalls nicht so wie ich es wollen würde. Sonst würde ich den Pfeil im Panel zeichnen und erst ins Bild übernehmen wenn man die Maus loslässt. |
AW: Pfeil auf einem Image platzieren
Zitat:
|
AW: Pfeil auf einem Image platzieren
Dann zeichne doch mal drauf und lösche anschließend den Inhalt via ClearRect(), Dann kannst Du gut sehen was verkehrt. Opacity wieder setzen ist auch nicht so wie es Sinn macht.
Ich finde bisher in FMX keine Möglichkeit "XOR" zu zeichnen. Dann bräuchte man nicht vor jeder neuen Linie den ganzen Inhalt löschen, nur um die Linie weg zubekommen. Bzw, was ist die transparente Farbe? Bei ClearRect ist jedenfalls egal was ich angebe, danach ist das Bild einfach Schwarz. |
AW: Pfeil auf einem Image platzieren
Also ich hatte das vorhin mal kurz getestet. Im OnMouseMove habe ich mir die Position gemerkt und ein InvalidateRect gemacht und im OnPaint dann eine Linie gezeichnet. Das lief ohne Ruckeln etc.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:59 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz