[gelöst] Bild drehen im Zentrum einer Paintbox

Für alles, was in den übrigen Lazarusthemen keinen Platz, aber mit Lazarus zutun hat.
Antworten
Benutzeravatar
KoBraSoft
Beiträge: 145
Registriert: So 6. Jun 2021, 09:57
OS, Lazarus, FPC: die zu Zeit aktuellen Versionen, überwiegend Linux
CPU-Target: 64Bit 32 Bit
Kontaktdaten:

[gelöst] Bild drehen im Zentrum einer Paintbox

Beitrag von KoBraSoft »

Hallo,
ich habe ein kleines Tool geschrieben mit dem ich schnell und einfach Fotos verkleinern, drehen und zuschneiden kann.
Jedoch kriege ich die Formel zur Drehung (Rotation) nicht hin. Es soll mittels Vektorrechnung sehr einfach gehen. Also habe ich mich, das erste mal seit meiner Schulzeit, mit der Drehung von Vektoren beschäftigt. Mir schwirrt nur noch der Kopf.
Hier der Ausschnitt aus dem Programm:

Code: Alles auswählen

procedure TForm1.CW1Execute(Sender: TObject);
var
  Neu: TPoint;
begin
  stretched := stretched.RotateCW;
  if Rotation = 270 then
    Rotation := 0
  else
    Rotation := Rotation + 90;
  Neu.X := PaintBox1.Width div 2 + ((stretched.Height - YPos) - PaintBox1.Height);      // Formel stimmt nicht
  Neu.Y := PaintBox1.Height div 2 + ((stretched.Width - XPos) - PaintBox1.Width);       // Formel stimmt nicht
  XPos := Neu.X;
  YPos := Neu.Y;
  stretched.Draw(PaintBox1.Canvas,XPos,YPos,True);
  ZoomFaktor := image.Width / stretched.Width;
  PaintBox1.Refresh;
  SchreibeStausbar;
end;            
Das Bild dreht zwar aber nicht um die Mitte der Paintbox.
Wie lautet die richtige Formel?
Hier das ganze Programm:
bbse.zip
(19.25 KiB) 17-mal heruntergeladen
Zuletzt geändert von KoBraSoft am Sa 9. Mai 2026, 06:49, insgesamt 2-mal geändert.
Konrad

www.KoBraSoft.de

Soner
Beiträge: 797
Registriert: Do 27. Sep 2012, 00:07
OS, Lazarus, FPC: Win10Pro-64Bit, Immer letzte Lazarus Release mit SVN-Fixes
CPU-Target: x86_64-win64
Wohnort: Hamburg

Re: Bild drehen im Zentrum einer Paintbox

Beitrag von Soner »

Also bei mir macht es, was es machen soll, immer 90 Grad drehen. Ich weiß es nicht, ob du nur bei dem Bespiel-Programm diesen Fehler hast, aber man sieht meistens nicht, weil du PaintBox1.Refresh aufrufst aber PaintBox1.OnPaint nicht verwendest.
Ich habe das hinzugefügt, dann funktionierte es:

Code: Alles auswählen

procedure TForm1.PaintBox1Paint(Sender: TObject);
begin
  stretched.Draw(PaintBox1.Canvas,XPos,YPos,True);
end;  
Du hast es bei TForm1.OnPaint gemacht, aber mach es bei Objekt selbst.

Soner
Beiträge: 797
Registriert: Do 27. Sep 2012, 00:07
OS, Lazarus, FPC: Win10Pro-64Bit, Immer letzte Lazarus Release mit SVN-Fixes
CPU-Target: x86_64-win64
Wohnort: Hamburg

Re: Bild drehen im Zentrum einer Paintbox

Beitrag von Soner »

Noch etwas habe ich vergessen zu schreiben, das hier ist falsch:

Code: Alles auswählen

    stretched.Draw(PaintBox1.Canvas,XPos,YPos,True); //<-- das hier
    PaintBox1.Refresh;
Weil Paintbox hat kein Bitmap, alles was man dort zeichnet ist flüchtig, man muss OnPaint-Ereignis verwenden, etwa so:

Code: Alles auswählen

procedure TForm1.CCW1Execute(Sender: TObject);
begin   
  // ....
  //das nicht: stretched.Draw(PaintBox1.Canvas,XPos,YPos,True); 
  PaintBox1.Invalidate;
end;  

procedure TForm1.PaintBox1Paint(Sender: TObject);
begin
  stretched.Draw(PaintBox1.Canvas,XPos,YPos,True);
end;

Benutzeravatar
Ally
Beiträge: 300
Registriert: Do 11. Jun 2009, 09:25
OS, Lazarus, FPC: Win und Lazarus Stable release
CPU-Target: x64

Re: Bild drehen im Zentrum einer Paintbox

Beitrag von Ally »

Hier ein Beispiel, das eine Drehung um 90/180/270° ermöglicht, aber auch um einen beliebigen Winkel.
Bei einer Drehung um einen beliebigen Winkel wird der Bildinhalt interpoliert.
Dabei bleibt die Transparenz erhalten.

Das Herzstück des Ganzen ist die Unit „rhsBitmapRotate.pas“, die ich in das beigefügte Testprogramm integriert habe.
Dateianhänge
rhsBitmapRotateTest.zip
(7.6 KiB) 20-mal heruntergeladen

siro
Beiträge: 780
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: Bild drehen im Zentrum einer Paintbox

Beitrag von siro »

Guten Morgen,
ich MUSS hier einen Kommentar hinterlassen: GEIL.
Das funktioniert ja ganz hervorragend, ich war wirklich überrascht... :shock: auch über die Geschwindigkeit.
Vielen Dank für diesen tollen Code und ein schönes Wochenende.

ich habe mal die Zeile:
// btnRotate.Enabled := False;
ausgeklammert. Nun kann man auch mehrfach rotieren. Erstaunlicherweise wird die Zeit dabei immer länger...

Ich habe immer um 45 Grad gedreht und folgende Zeiten erhalten:
141, 328, 641, 1281, 2563, 5171, 10406, 21422 ms

Okay, gefunden:
Das passiert daher, dass das Image immer größer wird.
In der Procedure BitmapRotate:

Code: Alles auswählen

// Calculate new dimensions
    NewWidth := Round(Abs(SrcImg.Width * CosTheta) + Abs(SrcImg.Height * SinTheta));
    NewHeight := Round(Abs(SrcImg.Width * SinTheta) + Abs(SrcImg.Height * CosTheta)); 
passiert übrigens nicht bei Drehungen um 90 oder 180 Grad.
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

Frank Ranis
Beiträge: 216
Registriert: Do 24. Jan 2013, 21:22

Re: Bild drehen im Zentrum einer Paintbox

Beitrag von Frank Ranis »

Hi ,

ich habe auch mal was gebaut .
Das Geheimnis liegt in einem Vektor zwischen dem Rotations-Zentrum (im Demo die Mausposition) und dem Nullpunk des Bildes (linke obere Ecke).
Dieser Vektor wird dann bei einer Aktion (rotieren , zoomen , verschieben) neu berechnet und damit dann das Bild neu positioniert .

Zum benutzen der Mausfunktionen bitte die Info im Menü lesen .

Gruß

Frank
BGRABitmap_Demo.zip
(141.09 KiB) 24-mal heruntergeladen
www.flz-vortex.de

Benutzeravatar
KoBraSoft
Beiträge: 145
Registriert: So 6. Jun 2021, 09:57
OS, Lazarus, FPC: die zu Zeit aktuellen Versionen, überwiegend Linux
CPU-Target: 64Bit 32 Bit
Kontaktdaten:

Re: Bild drehen im Zentrum einer Paintbox

Beitrag von KoBraSoft »

Frank Ranis hat geschrieben: Fr 8. Mai 2026, 14:10 ich habe auch mal was gebaut .
Gefällt mir sehr
Das Geheimnis liegt in einem Vektor zwischen dem Rotations-Zentrum (im Demo die Mausposition) und dem Nullpunk des Bildes (linke obere Ecke).
Dieser Vektor wird dann bei einer Aktion (rotieren , zoomen , verschieben) neu berechnet und damit dann das Bild neu positioniert .
Genau danach habe ich gesucht. Danke.
Konrad

www.KoBraSoft.de

Antworten