Entwickler-Ecke

Multimedia / Grafik - Image1.Refresh klappt nicht mit Canvas!?


ultra2k - Sa 24.05.03 13:14
Titel: Image1.Refresh klappt nicht mit Canvas!?
Also ich hab folgendes Problem:

Ich will auf einem TImage einen Bereich per Canvas.DrawFocusRect markieren. Der Code ist:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
procedure TMainForm.Image1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  StartX := X;  // Integer, wurden im Teil über 
  StartY := Y;  // Implementation Deklariert...
end;

procedure TMainForm.Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
var
  MyRect: TRect;
begin
  if ssLeft in Shift then
  begin
    MyRect.Left := StartX;
    MyRect.Top := StartY;
    MyRect.Right := X;
    MyRect.Bottom := Y;
    Image1.Repaint;
    Image1.Canvas.DrawFocusRect(MyRect);
  end;
end;

procedure TMainForm.Image1MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  Image1.Canvas.Pen.Color := clWhite;
  Image1.Canvas.Rectangle(StartX, StartY, X, Y);
end;


Image1.Repaint funktioniert aber nicht. Wenn ich das Programm laufen lasse werden aber die mit DrawFocusRect erzeugten gestrichelten Rechtecke nicht entfernt...
Weis jemand eine Lösung???


Aya - Sa 24.05.03 14:41

Hi,

das liegt daran das wenn du etwas mit Canvas auf ein Image zeichnest, du direkt in das Bild reinmals.

Das ist so als wenn du mit dem Stift auf ein Blatt papier nen strich ziehst, der is da.. geht auch nichmehr weg ;)

Das einzige was du machen kannst, ist das Image am anfang, wenn es noch unverändert ist, in ein z.B. TBitmap zu speichern, und jedesmal wenn du deine Canvas sachen löschen willst, packst du das Bitmap wieder auf das Image, also übermals es im grunde komplett :)

Hoffe das hat dir geholfen.. *guckt unsicher*

Au'revoir,
Aya~


ultra2k - Sa 24.05.03 14:48

Bringts was wenn ich statt Image1.Canvas.DrawFocusRect einfach Image1.Canvas.Canvas.DrawFocusRect nehme???


Aya - Sa 24.05.03 15:07

ultra2k hat folgendes geschrieben:
Bringts was wenn ich statt Image1.Canvas.DrawFocusRect einfach Image1.Canvas.Canvas.DrawFocusRect nehme???


Hi, da ein Canvas keinen Canvas hat, kannst du Image1.Canvas.Canvas.DrawFocusRect garnicht nehmen = es bringt nix ;)

Au'revoir,
Aya~


ultra2k - So 25.05.03 02:52

Ja, das hab ich kurz nach meinem Beitrag auch gecheckt...

hab jetz ne andere methode, ich lade den Inhalt von Image1 auch in WorkBmp(: TBitmap) und mach dann sowas wie Image1.Picture.Bitmap := WorkBmp; ... Glaub ich... hab Delphi grad net laufen, sonst wüsst ichs!
Naja, egal, Vielen Dank nochma....


P.S.: Bei TForm oder so gibts doch einen Canvas vom Canvas, oder??? Ich mein ich hätt sowas neulich hier gelesen, per Suchfunktion


UGrohne - So 25.05.03 11:06

Es gibt dazu eine ganz einfache Lösung, da gabs ne Zeichenoperation mit XOR. Du willst doch so ein Markierungsrechteck zeichnen, hab ich das richtig verstanden? Also wie wenn Du eine Zoom-Bereich kennzeichnest, oder sowas?

Hab dazu zu Hause ein bisschen Code, hab ich im INet gefunden. Wenn ich Dein Problem gerade richtig interpretiert habe, dann sag Bescheid, ich poste dann heute nachmittag den Code.

Gruß


ultra2k - So 25.05.03 14:34

Ja, das is korrekt, ein Markierungsrechteck...

kannste gern mal posten, würd mich freuen....


UGrohne - So 25.05.03 15:36

OK, du brauchst die drei Ereignisse




Folgende globale Variablen werden benötigt:

Delphi-Quelltext
1:
2:
3:
DragStartX,DragStartY,LastX,LastY:integer;
DragAction:Boolean;
OldPenMode:TPen


Und hier ist der Code:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
if Button=mbLeft then begin
   DragStartX:=x;
   DragStartY:=y;
   LastX:=x;
   LastY:=y;
   DragAction:=True;
   end;
end;



Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
if DragAction then begin
   OldPenMode:=Image1.Canvas.Pen;
   with Image1.Canvas do begin
        //altes Rechteck überschreiben
        Pen.Color:=clgray;
        Pen.Mode:=pmNot;
        Brush.Style:=bsClear;
        Rectangle(DragStartX,DragStartY,LastX,LastY);
        //neues Rechteck zeichnen
        if (x-DragstartX)<(y-DragstartY) then x:=(y-DragstartY+DragstartX) else y:=(x-DragstartX+DragstartY);
        Rectangle(DragStartX,DragStartY,x,y);
        LastX:=x;LastY:=y;
        end;
   end;
end;



Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
procedure TForm1.Image1MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
if DragAction then begin
     with Image1.Canvas do begin
        //altes Rechteck überschreiben
        Pen.Color:=clgray;
        Pen.Mode:=pmNot;
        Brush.Style:=bsClear;
        Rectangle(DragStartX,DragStartY,LastX,LastY);
        DragAction:=False;
        //Einstellungen wiederherstellen
        Pen:=OldPenMode;
        end;
        if (x=DragStartX) OR (y=DragStartY) then begin
      Exit;
      end;
     end;
end;


Ich hoffe, ich hab alles nicht dazugehörende richtig rausgeschnitten, was war Teil einer ziemlich großen Prozedur :wink:


ultra2k - So 25.05.03 20:14

Also, habs eingebaut und es funzt super! DANKE!
Habe aber noch folgende Zeile rausgenommen:

Delphi-Quelltext
1:
if (x-DragstartX)<(y-DragstartY) then x:=(y-DragstartY+DragstartX) else y:=(x-DragstartX+DragstartY);                    

Dann klebt der Punkt an der Maus, das will ich nämlich...
Aber in jedem Fall is diese Methode besser, als meine Alte. Is nich so rechenaufwendig!

Aber eine Frage noch: erst hatte ich irgendwo im unteren Teil einmal Y fälschlicherweise durch X getauscht, und da kam ein Fehler, der sehr gut aussah. ein teil des markierten bereichs erschien negativ. Hab sowas schon mal bei ner Delphi anwendung gesehen...
Weißt du wie das geht???


UGrohne - Mo 26.05.03 11:54

Da musst Du mal ein bisschen mit den Brush-Optionen Style und Mode rumspielen, dann kriegste das vll. Genaueres weiß ich leider net, aber wenn Du's rausfindest, sags bitte, interessiert mich auch :wink:


ultra2k - Mo 26.05.03 22:46

Hi nochma, villeicht kannst du mir nochma helfen :oops:
Hab noch was:


Delphi-Quelltext
1:
Format('R,%d,%d,%d,%d,', [rc.Left, rc.Top, rc.Right, rc.Bottom]);                    

Mit dieser Funktion werden die koordinaten eines Rechtecks in eine Stringlist geschrieben, kannst du mir sagen, wie genau ich die wieder in dem Format rauskriege??? (R steht für Rectangle, der Rest is ja klar...)


ultra2k - Mi 28.05.03 17:14

okay, alles paletti, ich machs jetz mit


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
var
  Region: String;
  reg := String;

(...)

while Region[i] <> ',' do begin
  reg := reg + Region[i];
  Inc(i)
end;


diesen code lass ich viermal laufen, und an jedem Ende wird der Wert in rc: TRect geschrieben...

Aber nochma: thx