AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Image in einer ScrollBox richtig positionieren...

Image in einer ScrollBox richtig positionieren...

Ein Thema von Thunder1968 · begonnen am 18. Apr 2015 · letzter Beitrag vom 21. Jun 2016
Antwort Antwort
Thunder1968

Registriert seit: 19. Mai 2009
8 Beiträge
 
#1

Image in einer ScrollBox richtig positionieren...

  Alt 18. Apr 2015, 20:26
Hallo und Guten Abend,

seit langem habe ich mal wieder ein Problemchem. Ich habe eine ScrollBox die ein TImage enthält. In dieses TImage wird dann ein PNG-File geladen was ca. 2,5 MB groß ist. Das verschieben des TImages funktioniert problemlos. Aber jetzt möchte ich das ganze mit dem Mausrad vergrößern und auch verkleinern. Mein Problem liegt jetzt darin das ich gerne den aktuellen Mittelpunkt der ScrollBox / TImage auch mittig bleiben soll. Wenn ich das Mausrad betätige (vergrößern, verkleinern) verschiebt sich das TImage so das der aktuell angezeigte Mittelpunkt sich verschiebt und ich dann mit der Maus das die alte Position wieder in die Mitte ziehen muß um es beim nächsten Zoom-Vorgang nicht wieder aus den Augen zu verlieren. Wo liegt mein Denkfehler oder hat jemand eine Idee??? Wäre auch Dankbar für ein komplettes Beispiel... Den Quellcode habe ich angehängt und für eine rasche Hilfe wäre ich Euch sehr Dankbar... Bei den beiden Bilder im Anhang soll verdeutlicht werden wie sich das ganze auswirkt und darstellt... Viele Grüße...


Delphi-Quellcode:
function TFormMain.DoMouseWheelDown(Shift: TShiftState; MousePos: TPoint): Boolean;
var
   NewScrollPosX, NewScrollPosY : Integer;
   OldScrollPosX, OldScrollPosY : Integer;
   TempValue : Integer;

begin
     // Bild zoomen

     if ssCtrl in Shift then
     begin
          Image1.AutoSize := False;
          Image1.Center := True;
          Image1.Proportional := True;
          Image1.Stretch := True;

          OldScrollPosX := ScrollBox1.HorzScrollBar.Position;
          OldScrollPosY := ScrollBox1.VertScrollBar.Position;

          Image1.Left := Round(Image1.Left - (((Image1.Width * ZoomFactor) - Image1.Width) / 2));
          Image1.Top := Round(Image1.Top - (((Image1.Height * ZoomFactor) - Image1.Height) / 2));
          Image1.Width := Round(Image1.Width * ZoomFactor);
          Image1.Height := Round(Image1.Height * ZoomFactor);

          TempValue := Round(OldScrollPosX * ZoomFactor);
          NewScrollPosX := Round((OldScrollPosY - TempValue) / (ZoomFactor));

          TempValue := Round(OldScrollPosX * ZoomFactor);
          NewScrollPosY := Round((OldScrollPosY - TempValue) / (ZoomFactor));

          ScrollBox1.HorzScrollBar.Position := ScrollBox1.HorzScrollBar.Position + (NewScrollPosX div 2);
          ScrollBox1.VertScrollBar.Position := ScrollBox1.VertScrollBar.Position + (NewScrollPosY div 2);
     end;

     Image1.Repaint;

     ScrollBox1.DoubleBuffered := True;
end;

function TFormMain.DoMouseWheelUp(Shift: TShiftState; MousePos: TPoint): Boolean;
var
   NewScrollPosX, NewScrollPosY : Integer;
   OldScrollPosX, OldScrollPosY : Integer;
   TempValue : Integer;

begin
     // Bild verkleinern

     if ssCtrl in Shift then
     begin
          Image1.AutoSize := False;
          Image1.Center := True;
          Image1.Proportional := True;
          Image1.Stretch := True;

          OldScrollPosX := ScrollBox1.HorzScrollBar.Position;
          OldScrollPosY := ScrollBox1.VertScrollBar.Position;

          Image1.Left := Round(Image1.Left + (((Image1.Width * ZoomFactor) - Image1.Width) / 2));
          Image1.Top := Round(Image1.Top + (((Image1.Height * ZoomFactor) - Image1.Height) / 2));
          Image1.Width := Round(Image1.Width / ZoomFactor);
          Image1.Height := Round(Image1.Height / ZoomFactor);

          TempValue := Round(OldScrollPosX / ZoomFactor);
          OldScrollPosX := Round((OldScrollPosX - TempValue) / (ZoomFactor));

          TempValue := Round(OldScrollPosY / ZoomFactor);
          OldScrollPosY := Round((OldScrollPosY - TempValue) / (ZoomFactor));

          ScrollBox1.HorzScrollBar.Position := ScrollBox1.HorzScrollBar.Position - (OldScrollPosX div 2);
          ScrollBox1.VertScrollBar.Position := ScrollBox1.VertScrollBar.Position - (OldScrollPosY div 2);
     end;

     Image1.Repaint;

     ScrollBox1.DoubleBuffered := True;
end;
Miniaturansicht angehängter Grafiken
vorher.png   nachher.png  

Geändert von Thunder1968 (18. Apr 2015 um 21:00 Uhr)
  Mit Zitat antworten Zitat
mh18058

Registriert seit: 21. Nov 2008
15 Beiträge
 
#2

AW: Image in einer ScrollBox richtig positionieren...

  Alt 22. Mai 2016, 23:51
Hallo Thunder1968,
und an Alle, die sich auch mit dem Thema befassen,

Ich hatte so eine ähnliche Frage, nur daß ich statt eines TImage eine TPaintBox habe.
Die PaintBox ist auf einer ScrollBox und ich zeichne auf die PaintBox eine Vektorgrafik.
Natürlich ist die PaintBox größer als die ScrollBox und die Zeichnung soll sich beim
Zoomen nicht verschieben, sondern genau unter der Maus bleiben.

Ich habe dazu folgende Lösung gefunden:
Im WheelUp und WheelDown ist eine Positionskorrektur durchzuführen. Dazu nehme ich den
Abstand vom Mittelpunkt der PaintBox und der Maus (Fluchtpunkt) und skaliere diesen
Abstand mit Hilfe des Zoom-Faktors nur für diesen einen Schritt. D.h. ich berechne die
Änderung dX/dY um die sich der Mittelpunkt bei einem Zoomschritt verschiebt.
Um diese dX/dY-Werte verschiebe ich dann die Zeichnung unter der Maus sozusagen zurück.
Zum Schluß wird alles mit redraw mit der gewünschten Skalierung neu gezeichnet.
Logischerweise ist der Korrekturfaktor in WheelUp und WheelDown unterschiedlich.
Außerdem: Scrollby(dX,dY) funktioniert zwar, nimmt aber die Scrollbalken nicht mit.
Das alles sieht dann so aus:

Gruß
Martin
P.S.: Wer Lust hat, kann sich auch meinen ZoomTest anschauen.

Delphi-Quellcode:
procedure TForm1.FormMouseWheelDown(Sender: TObject; Shift: TShiftState;
  MousePos: TPoint; var Handled: Boolean);
var P: TPoint;
    dX,dY: Integer;
begin
  inc(MouseWheelTics);
  if MouseWheelTics > 2 then begin
    MouseWheelTics := 0;

    if ((ZoomLevel-1 >= -ZoomLevelRange) and
        (ZoomLevel-1 <= ZoomLevelRange)) then begin
      P := get_MausPos_on_PB;
      zoomIn;

   // Mittelpunktverschiebung korrigieren
      dX := ArithRound((PaintBox1.Width div 2 - P.X) * (ZoomStep-1)/ZoomStep);
      dY := ArithRound((PaintBox1.Height div 2 - P.Y) * (ZoomStep-1)/ZoomStep);
// ScrollBox1.Scrollby(dX,dY);
      with ScrollBox1 do begin
        with HorzScrollBar do Position := Position + dX;
        with VertScrollBar do Position := Position + dY;
      end;

      redraw(true);
    end;
  end;
end;


procedure TForm1.FormMouseWheelUp(Sender: TObject; Shift: TShiftState;
  MousePos: TPoint; var Handled: Boolean);
var P: TPoint;
    dX,dY: Integer;
begin
  inc(MouseWheelTics);
  if MouseWheelTics > 2 then begin
    MouseWheelTics := 0;

    if ((ZoomLevel+1 >= -ZoomLevelRange) and
        (ZoomLevel+1 <= ZoomLevelRange)) then begin
      P := get_MausPos_on_PB;
      zoomOut;

   // Mittelpunktverschiebung korrigieren
      dX := ArithRound((PaintBox1.Width div 2 - P.X) * (ZoomStep-1));
      dY := ArithRound((PaintBox1.Height div 2 - P.Y) * (ZoomStep-1));
// ScrollBox1.Scrollby(dX,dY);
      with ScrollBox1 do begin
        with HorzScrollBar do Position := Position - dX;
        with VertScrollBar do Position := Position - dY;
      end;

      redraw(true);
    end;
  end;
end;
Angehängte Dateien
Dateityp: rar ZoomTest.rar (204,7 KB, 85x aufgerufen)
  Mit Zitat antworten Zitat
Thunder1968

Registriert seit: 19. Mai 2009
8 Beiträge
 
#3

AW: Image in einer ScrollBox richtig positionieren...

  Alt 21. Jun 2016, 10:02
Hallo mh18058,

sorry das ich mich jetzt erst melde. Hatte noch andere Projekte und habe deshalb auch nicht mehr so den Fokus auf diesen Beitrag. Vor allem vielen Dank für Dein Beispiel. Sieht echt super aus und funktioniert. Genau soetwas habe ich gesucht.

Vielen Dank...
  Mit Zitat antworten Zitat
mh18058

Registriert seit: 21. Nov 2008
15 Beiträge
 
#4

AW: Image in einer ScrollBox richtig positionieren...

  Alt 21. Jun 2016, 18:41
Hallo Thunder1968,

gerne doch!
Für Alle, die den Code verwenden wollen:
Ich habe inzwischen festgestellt, daß statt
Delphi-Quellcode:
  inc(MouseWheelTics);
  if MouseWheelTics > 2 then begin
    MouseWheelTics := 0;
auch einfach
Delphi-Quellcode:

Handled := true;
geschrieben werden kann.
Grüße
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 10:41 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