AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Pfeil auf einem Image platzieren

Ein Thema von fisipjm · begonnen am 16. Okt 2023 · letzter Beitrag vom 23. Okt 2023
Antwort Antwort
Seite 2 von 3     12 3      
fisipjm

Registriert seit: 28. Okt 2013
298 Beiträge
 
#11

AW: Pfeil auf einem Image platzieren

  Alt 17. Okt 2023, 16:28
Hm, Ich finde Blumen besser als Kanonen. Bekommt man auch Spatzen und Ameisen darunter versteckt. Trotzdem war ich jetzt zu Faul eine zu malen. Selbst für einen Pfeil war ich jetzt zu Faul.
Aber man sieht trotzdem dass es geht. Siehe Anhang!
Okay, ich habe mich mal an einem Pfeil versucht das Ergebnis passt für meine Zwecke. Danke für die Hilfe. Ich muss auch die Möglichkeit haben, Änderungen an dem Bild wieder rückgängig zu machen, das kann ich ja nur, wenn ich ein eigenes Overlay mache, wie Himitsu das z.B. schon angemerkt hat, richtig?

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;

Geändert von fisipjm (17. Okt 2023 um 16:34 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Sinspin
Sinspin

Registriert seit: 15. Sep 2008
Ort: Dubai
670 Beiträge
 
Delphi 10.3 Rio
 
#12

AW: Pfeil auf einem Image platzieren

  Alt 17. Okt 2023, 17:13
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.
Stefan
Nur die Besten sterben jung
A constant is a constant until it change.
  Mit Zitat antworten Zitat
fisipjm

Registriert seit: 28. Okt 2013
298 Beiträge
 
#13

AW: Pfeil auf einem Image platzieren

  Alt 19. Okt 2023, 15:10
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.
Hi Sinspin,

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
  Mit Zitat antworten Zitat
Benutzerbild von Sinspin
Sinspin

Registriert seit: 15. Sep 2008
Ort: Dubai
670 Beiträge
 
Delphi 10.3 Rio
 
#14

AW: Pfeil auf einem Image platzieren

  Alt 19. Okt 2023, 17:48
Zeig mal was du hast. Vermutlich siehst du nur gerade den Wald vor lauter Bäumen nicht.
Stefan
Nur die Besten sterben jung
A constant is a constant until it change.
  Mit Zitat antworten Zitat
fisipjm

Registriert seit: 28. Okt 2013
298 Beiträge
 
#15

AW: Pfeil auf einem Image platzieren

  Alt 20. Okt 2023, 10:24
Zeig mal was du hast. Vermutlich siehst du nur gerade den Wald vor lauter Bäumen nicht.
Das befürchte ich auch
Hab das Projekt mal in den Anhang geladen, das Konstrukt mit den Helper Klassen bitte einfach ignorieren, hab das nur Quick&Dirty als Proof of Concept zusammen geschmissen.
Angehängte Dateien
Dateityp: zip FMX_PaintFrm.zip (4,67 MB, 1x aufgerufen)
  Mit Zitat antworten Zitat
fisipjm

Registriert seit: 28. Okt 2013
298 Beiträge
 
#16

AW: Pfeil auf einem Image platzieren

  Alt 23. Okt 2023, 10:53
Zeig mal was du hast. Vermutlich siehst du nur gerade den Wald vor lauter Bäumen nicht.
Moin Sinspin,

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.

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.
  Mit Zitat antworten Zitat
Benutzerbild von Sinspin
Sinspin

Registriert seit: 15. Sep 2008
Ort: Dubai
670 Beiträge
 
Delphi 10.3 Rio
 
#17

AW: Pfeil auf einem Image platzieren

  Alt 23. Okt 2023, 13:33
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.
Stefan
Nur die Besten sterben jung
A constant is a constant until it change.
  Mit Zitat antworten Zitat
Benutzerbild von Olli73
Olli73

Registriert seit: 25. Apr 2008
Ort: Neunkirchen
732 Beiträge
 
#18

AW: Pfeil auf einem Image platzieren

  Alt 23. Okt 2023, 17:13
Das FMX Panel kann nicht durchsichtig. Jedenfalls nicht so wie ich es wollen würde.
Was ist an "Opacity := 0" verkehrt?
  Mit Zitat antworten Zitat
Benutzerbild von Sinspin
Sinspin

Registriert seit: 15. Sep 2008
Ort: Dubai
670 Beiträge
 
Delphi 10.3 Rio
 
#19

AW: Pfeil auf einem Image platzieren

  Alt 23. Okt 2023, 18:31
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.
Stefan
Nur die Besten sterben jung
A constant is a constant until it change.
  Mit Zitat antworten Zitat
Benutzerbild von Olli73
Olli73

Registriert seit: 25. Apr 2008
Ort: Neunkirchen
732 Beiträge
 
#20

AW: Pfeil auf einem Image platzieren

  Alt 23. Okt 2023, 19:01
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.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 3     12 3      

 

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:52 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