Thema: Delphi TMetaFile zuschneiden

Einzelnen Beitrag anzeigen

Redeemer

Registriert seit: 19. Jan 2009
Ort: Kirchlinteln (LK Verden)
1.010 Beiträge
 
Delphi 2009 Professional
 
#5

AW: TMetaFile zuschneiden

  Alt 7. Mai 2020, 11:37
Man kann auch den PENHMETAHEADER benutzen. Hier ein Beispiel aus einem anderen Kontext:
Delphi-Quellcode:
procedure TSVGMetafile.FixRDPBug(const Handle: HDC);
var
  Temp: TMemoryStream;
  Header: PENHMETAHEADER;
begin
  // Workaround für einen Fehler in RDP, durch den szlMillimeters und rclFrame falsch sind, wenn der Hauptbildschirm des verbindenden Rechners nicht das Seitenverhältnis 4:3 hat
  // vgl. https://stackoverflow.com/a/1533053
  // Kann leider nicht beim geladenen Bild geändert werden, da man an szlDevice (HORZRES und VERTRES bei GetDeviceCaps) nicht im Speicher des vorhandenen Bildes ran kommt
  // Bug scheint in Windows 10 nicht mehr zu existieren.

  // Besteht KEINE Remote-Desktop-Verbindung? Dann Abbruch.
  // Keine Ahnung, ob das Anfang August funktioniert hat, aber ich habe jetzt Ende Oktober keinen Self.Handle mehr, die Methode gibt daher 0 zurück, was anders als 320 bzw. 240 ist.
  // Daher wird der Handle von TMetafileCanvas übergeben.
  if GetDeviceCaps(Handle, HORZSIZE) <> 320 then Exit;
  if GetDeviceCaps(Handle, VERTSIZE) <> 240 then Exit;
  // Theoretisch können diese Werte auch ohne RDP auftreten, wenn der Nutzer einen 4:3-Bildschirm besitzt.
  // FixRDPBug macht korrekte Bilder nicht kaputt, daher geht es hier ausschließlich um die Performance, die bei einem Durchlauf des folgenden Codes verloren geht.

  Temp := TMemoryStream.Create();
  try
    Self.SaveToStream(Temp);
    if Temp.Size > 0 then
    begin
      Temp.Position := 0;
      Header := Temp.Memory;

      Header^.rclFrame.Right := (Header^.rclBounds.Right + 1) * 100;
      Header^.rclFrame.Bottom := (Header^.rclBounds.Bottom + 1) * 100;
      Header^.szlDevice.cx := 320; // gleiche Werte für beide szl-Felder machen es einfacher, Rundungsfehler hierüber zu vermeiden (man kann einfach mit 100 multiplizieren)
      Header^.szlDevice.cy := 240;
      Header^.szlMillimeters.cx := 320;
      Header^.szlMillimeters.cy := 240;

      inherited LoadFromStream(Temp);
    end;
  finally
    Temp.Free();
  end;
end;
Janni
2005 PE, 2009 PA, XE2 PA
  Mit Zitat antworten Zitat