![]() |
TMetaFile zuschneiden
Liste der Anhänge anzeigen (Anzahl: 2)
Ja, ich habe die Suche zu "EMF" und "TMetaFile" bemüht.
Ich benutze den Steema TeeChart um mir eine Vektorgrafik erstellen zu lassen. Eine entsprechende Routine gibt ein
Delphi-Quellcode:
zurück. Ich habe Null Erfahrung mit der Klasse. Ich stehe vor dem Problem dass das TMetaFile rechts und unten leeren Raum enthält wenn die Anwendung vom Betriebssystem hochskaliert wird. Also nicht "DPI-Aware" ist, Windows aber mit > 100 % Skalierung läuft.
TMetaFile
Im Anhang einmal die EMF-Datei als PNG und einmal in einer ZIP-Datei. Ich möchte dieses Bild zuschneiden. Ich habe keine Ahnung wie. Kann mir jemand einen Tipp geben? PS: Wenn man das Manifest der Anwendung erweitert und sie selbst die Skalierung übernimmt stimmt die Grafik wieder. Die Anwendung "dpi aware" zu machen haben wir auf der Roadmap, aber eine schnelle Lösung für dieses TMetaFile wäre natürlich trotzdem schön. |
AW: TMetaFile zuschneiden
Hm, tricky. Hatte ich mir einfacher und weniger aufwendig vorgestellt.
Ich habe es nur über den Umweg über ein TBitmap "geschafft". Und die neue Datei ist auch 744 KB groß, gegenüber dem Original mit 47,8 KB. Da steht die Befürchtung im Raum, dass nicht wirklich die GDI-Befehle platzsparend in der neuen EMF-Datei stehen, sondern einfach nur das Bitmap (also als eine Ansammlung von Bytes) drin steckt.
Delphi-Quellcode:
procedure TForm1.btn1Click(Sender: TObject);
var Metafile: TMetafile; Metafile2: TMetafile; MetafileCanvas: TMetafileCanvas; OldSize, NewSize: TRect; Bitmap: TBitmap; begin Metafile := TMetafile.Create; try Metafile.LoadFromFile('C:\Temp\metafile\metafile.emf'); OldSize := TRect.Create(0, 0, Metafile.Width, Metafile.Height); NewSize := TRect.Create(0, 0, 680, 280); Bitmap := TBitmap.Create; try Bitmap.SetSize(OldSize.Width, OldSize.Height); Bitmap.Canvas.StretchDraw(OldSize, Metafile); Bitmap.SetSize(NewSize.Width, NewSize.Height); Bitmap.SaveToFile('C:\Temp\metafile\metafile2.bmp'); Metafile2 := TMetafile.Create; try Metafile2.SetSize(NewSize.Width, NewSize.Height); MetafileCanvas := TMetafileCanvas.Create(Metafile2, 0); try MetafileCanvas.StretchDraw(NewSize, Bitmap); finally MetafileCanvas.Free; end; Metafile2.SaveToFile('C:\Temp\metafile\metafile2.emf'); finally Metafile2.Free; end; finally Bitmap.Free; end; finally Metafile.Free; end; end; |
AW: TMetaFile zuschneiden
Schuß ins Blaue:
Über die Draw-Commmands/GDI-Befehle iterieren und die Befehle ignorieren, die den weißen Rand zeichnen und das auf ein neues Metafile umlenken. ![]() ![]() Aufwand zu nutzen Verhältnis steht in Frage? Gegenfalls einfach mal Steema anschreiben, ob man das beim Export einfach weg bekommt? |
AW: TMetaFile zuschneiden
Bei Steema habe ich ehrlich gesagt die Hoffnung aufgegeben dass die noch etwas in die Delphi-Welt investieren. Vor ein paar Jahren war das noch besser, aber der Fehler ist denen seit 2015 bekannt. Er wurde 2018 nochmal ausgekramt und hat es anscheinend nicht mal im zweiten Anlauf in den Bugtracker geschafft.
Klar, das Problem lässt sich beheben indem man die Anwendung "Dpi aware" macht, aber das auch nicht an einem Nachmittag gemacht. Alternativ könnte ich in den Steema Source code einsteigen aber die Zeit investiere ich lieber um die VCL-Oberfläche mit DPI-Skalierung vertraut zu machen. |
AW: TMetaFile zuschneiden
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; |
AW: TMetaFile zuschneiden
Ich habe noch einen Workaround... naja eher Trick entdeckt der einem das Leben hier vielleicht etwas einfacher macht:
Ein einzelner Thread kann mittels ![]() |
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:11 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz