Die Angabe DPI von einem GDI-Gerätekontext
Ich habe eine Anwendung, die generiert metafiles (EMF). Es verwendet das Referenz-Gerät (aka dem Bildschirm), um diese Metadateien, also die DPI der Metadatei ändert sich abhängig davon, auf welcher Maschine der code ausgeführt wird.
Let ' s sagen, mein code ist beabsichtigt, erstellen Sie eine Metadatei, 8.5 x 11 in. Mit meiner Entwicklung workstation als Referenz, dass ich am Ende mit einem EMF hat
- eine rclFrame von { 0, 0, 21590, 27940 } (Abmessungen der Metadatei in Tausendstel mm)
- eine szlDevice von { 1440, 900 } (Abmessungen des Referenz-Gerät (in Pixeln)
- eine szlMillimeters von { 416, 260 } (Abmessungen der Referenz-Gerät in mm)
Okay, also die rclFrame sagt mir, dass die Größe des EMF-sollte
- 21590 /2540 = 8.5 in weiten
- 27940 /2540 = 11 in groß
Richtig auf. Mithilfe dieser Informationen können wir bestimmen die physikalische DPI von meinem monitor, auch, wenn mein Mathe richtig ist:
- (1440 * 25.4) /416 = 87.9231 horizontale dpi
- (900 * 25.4) /260 = 87.9231 vertikale dpi
Das problem
Alles, spielt dieser Metadatei-ein EMF-zu-PDF-Konvertierung, die Seite "Zusammenfassung" wenn Sie mit der rechten Maustaste auf die EMF im Windows-Explorer, etc--scheint zum abschneiden der berechneten DPI-Wert der Anzeige 87 statt 87.9231 (sogar 88 wäre in Ordnung).
Diese Ergebnisse in eine Seite, ist physisch sortiert als 8.48 in x 10.98 in (mit 87 dpi) anstelle von 8,5 x 11 in (mit 88 dpi), wenn die Metadatei wiedergegeben wird.
- Ist es möglich, ändern Sie den DPI-Wert des Referenz-Gerät so, dass die Informationen in der Metadatei gespeichert werden verwendet, um die Berechnung der DPI kommt zu einem schönen integer?
- Kann ich meine eigenen Gerätekontext, und geben Sie den DPI? Oder muss ich wirklich haben, um zu verwenden, einen Drucker zu tun?
Vielen Dank für jede Einsicht.
- Ist die Größe auf der Seite "Zusammenfassung" angezeigt, richtig? Ist es 748x968 oder 747x967?
- mit der Mathematik gelegt, die Sie wie in dieser Frage - ist von unschätzbarem Wert für mich
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich bin neugierig, wie Windows kennt die physische Größe des Monitors. Sie verändert haben muß eine Konfiguration irgendwo? Vielleicht können Sie es ändern, um bequemer Werte teilen schön.
Impliziert durch die Namen, einen "Device Context" muss mit einem system-Gerät. Dies bedeutet jedoch nicht um ein hardware-Treiber, es könnte ein Geräte-emulator wie ein PDF-writer-Druckertreiber. Ich habe gesehen, mindestens eine, die Sie können eine beliebige DPI.
Habe ich jetzt gelernt, mehr als ich gepflegt wissen über Metadateien.
1. Einige der
Metafile
Klasse Konstruktor-überladungen arbeiten schlecht und wird sich auf eine abgeschnittene DPI-Wert.Folgendes:
Wenn Sie bestanden in einer
SizeF
von { 8.5, 11 }, die Sie erwarten, zu bekommenMetafile
hat einerclFrame
von { 21590, 27940 }. Konvertieren von Zoll in Millimeter ist auch nicht schwer, nachdem alle. Aber Sie wahrscheinlich nicht. Je nach Auflösung, GDI+, so scheint es, wird die Verwendung einer verkürzten DPI-Wert bei der Umwandlung des Zoll-parameter. Um es richtig zu machen, ich habe es selbst zu tun in Hundertstel millimeter, die GDI+ nur durchläuft, denn das ist, wie es ist nativ in der Metadatei gespeichert werden header:Rundungsfehler #1 gelöst--die
rclFrame
meiner Metadatei ist nun korrekt.2. Die DPI auf
Graphics
Instanz die Aufnahme zu einemMetafile
ist immer falsch.Sehen, dass
metafileGraphics
variable, die ich setzen Sie durch aufrufenGraphics.FromImage()
auf die Metadatei? Nun ja, es scheint, dassGraphics
Instanz immer einen DPI-Wert von 96 dpi. (Wenn ich raten müsste, ist es immer das logische DPI, nicht die körperliche ein.)Können Sie sich vorstellen, dass die Heiterkeit, die entsteht, wenn Sie die Zeichnung auf einem
Graphics
Instanz, die unter 96 dpi und die Aufnahme auf eineMetafile
Instanz, die 87.9231 dpi "aufgezeichnet" in der überschrift. (Ich sage "aufgenommen", weil es berechnet sich aus den anderen Werten.) Die Metadatei ist "Pixel" (Sie erinnern sich, die GDI-Befehle in der Metadatei gespeichert werden, angegeben werden Pixel) sind größer, und so ist Sie Fluch und, der mutter, warum Ihr Aufruf, etwas zu zeichnen einen Zoll lang, endet als ein-und-etwas-über Zoll lang.Die Lösung ist, verkleinere die
Graphics
Beispiel:Ain ' T that a hoot? Aber es scheint zu funktionieren.
"Rundung" Fehler #2 gelöst-wenn ich sage, zeichnen Sie etwas auf "1 Zoll" bei 88 dpi, das pixel hatte besser $%$^! aufgezeichnet als pixel #88.
3.
szlMillimeters
können sehr stark variieren; Remote Desktop verursacht eine Menge Spaß.So, wir entdeckten (pro Mark ' s Antwort), dass, manchmal, Windows fragt die EDID des Monitors und der tatsächlich weiß, wie groß es ist physisch. GDI+ hilfsbereit nutzt diese (
HORZSIZE
etc) beim ausfüllen desszlMillimeters
Eigenschaft.Nun stellen Sie sich vor, dass Sie nach Hause gehen, um diese debug-code des remote-desktop. Lassen Sie uns sagen, dass Ihr computer zu Hause geschieht mit einem 16:9-Breitbild-monitor.
Offensichtlich, kann Windows keine Abfrage der EDID von einem display mit Fernbedienung. So verwendet er das uralte Standard 320 x 240 mm, das wäre gut, außer, dass es geschieht, um ein Seitenverhältnis von 4:3, und jetzt der exakt gleiche code generiert eine Metadatei auf einem display, das angeblich nicht-quadratischen physikalischen Pixel: horizontale DPI und vertikalen DPI sind Verschieden, und ich kann mich nicht erinnern, das Letzte mal, dass ich sah, dass passieren.
Mein workaround für jetzt ist: "Gut, laufen nicht unter remote-desktop."
4. Die EMF-to-PDF-tool, das ich mit hatte einen Rundungsfehler, wenn man die
rclFrame
header.Dies war die Hauptursache für mein problem ausgelöst hat, diese Frage. Meine Metadatei "richtig" alle zusammen (gut, richtig, nachdem ich Feste die ersten beiden Fragen), und alle diese Suche für die Erstellung einer "high-resolution" Metadatei ist ein Roter Hering. Es ist wahr, dass einige treue ist verloren, wenn die Aufnahme die Metadatei auf einem low-resolution-display-Gerät, weil die GDI-Befehle angegeben, die in der Metadatei werden in Pixel angegeben. Es spielt keine Rolle, dass es ein Vektor-format und können nach oben oder unten skaliert, gehen einige Informationen verloren während der eigentlichen Aufnahme, wenn GDI+ entscheidet, die "pixel" zu schnappen, eine operation zu.
Ich den Verkäufer kontaktiert und Sie gab mir eine korrigierte version.
Rundungsfehler #3 gelöst.
5. Die "Summary" - Fenster in Windows Explorer passiert einfach so abschneiden Werte bei der Anzeige der berechneten DPI.
Es passiert einfach so, dass das abgeschnittene Wert vertreten die gleichen fehlerhaften Wert, dass die EMF-to-PDF-tool wurde mithilfe von intern. Abgesehen davon, ist diese Marotte nicht dazu beitragen, etwas sinnvolles zu der Diskussion.
Schlussfolgerungen
Da war meine Frage, über futzing mit DPI-Gerät zusammenhängen, Mark ' s ist eine gute Antwort.
Beachten Sie, dass ich mit 120 dpi auf WXP die ganze Zeit (große Schriftarten) was bedeutet metafileGraphics.DpiX werden wieder 120.
Die EMF-Datei nicht angezeigt wird, zu notieren, was die dpi wurde der Referenz-Rahmen (120, in diesem Fall, 96 für die meisten anderen Menschen).
Interessanter zu gestalten, ist es möglich, eine EMF-über die Zeichnung auf einer in-memory bitmap, hatte SetResolution() gesetzt, um, sagen wir, 300 dpi. In diesem Fall, glaube ich, dass der Skalierungsfaktor hat 300 und nicht, was der monitor (86.x) oder Windows (120) verwenden könnten.
Scheint, wie die Werte auf der Seite "Zusammenfassung" sind falsch. Sie sind wie folgt berechnet:
Wo precize Werte berechnet werden ohne Rundung oder abschneiden.