Wie berechnet Excel die Auflösung der Metafiles, die er erzeugt, wenn ein Bereich „wie auf dem Bildschirm gezeigt“ kopiert?

StackOverflow https://stackoverflow.com/questions/8317313

  •  25-10-2019
  •  | 
  •  

Frage

Ich habe einen C# Code, von dem ich bekommen habe http://bytes.com/topic/c-sharp/answers/572657-net-clipboard-metafiles Das kopiert einen Zellbereich unter den folgenden zwei Einstellungen:

  • Wie auf dem Bildschirm gezeigt,
  • Wie beim Druck gezeigt.

Wenn ich mir die resultierende Auflösung von Metafile anschaue (die als dokumentiert ist wie Gets the resolution, in pixels-per-inch, of this Image object), Ich erhalte je nach Kopiermethode unterschiedliche Werte.

  • Mit dem Wie beim Druck gezeigt Option, die Auflösung beträgt 600, was meiner Meinung nach den DPI -Einstellungen entspricht, die ich in Excel habe.

  • Mit dem Wie auf dem Bildschirm gezeigt Einstellung spuckt so etwas wie aus Metafile.VerticalResolution = 72.08107 und Metafile.HorizontalResolution = 71.95952. Bei anderen Maschinen habe ich gesehen, dass dieser Wert stark variiert (Werte um 111, 130 usw.).

Das Zoom -Level scheint dies nicht zu beeinflussen. Nach dem, was ich beobachtet habe, bleiben die Werte auf einer einzelnen Maschine konsistent, können sich jedoch von Maschine zu Maschine unterscheiden.

Kann jemand die logische Excel erklären, die bei der Berechnung der Auflösung des Metafiles in folgt Wie auf dem Bildschirm gezeigt Modus?

Nachdem ich die Windows -Auflösung geändert und die metafilen Auflösungen gemessen hatte, ist hier die Tabelle, die ich generiert habe (hoffe, sie sieht richtig formatiert aus):

Width   Height  HorizontalResolution    VerticalResolution
1680    1050        71.95952                72.08107
1600    1024        72.05672                72.04874
1600    900         72.05672                71.88678
1360    768         71.96666                71.98228
1280    1024        71.9292                 72.04874
1280    960         71.9292                 71.9292
1280    800         71.9292                 72.05672
1280    768         71.9292                 71.98228
1280    720         71.9292                 71.99999
1152    864         72.07093                71.95278
1088    612         71.96666                71.96666
1024    768         72.04874                71.98228
960     600         71.9292                 71.88678
800     600         72.05672                71.88678

Nach einem ähnlichen Verfahren auf einer virtuellen Maschine (gleiche physische Maschine) sind dies die Ergebnisse. Etwas volatiler als die physische Maschine selbst. Diese Daten sind vielleicht nicht nützlich, aber ich dachte, ich würde sie sowieso bereitstellen.

Width   Height  HorizontalResolution    VerticalResolution
1680    1050    133.35                  111.125
1280    800     101.6                   84.66666
1024    768     81.27999                81.27999
800     600     63.5                    63.5
War es hilfreich?

Lösung

Meine Hypothese

Ich glaube, dies hat damit zu tun, dass eine nicht einheimische Auflösung auf einem LCD-Monitor durchgeführt wird. In "The Old Days" hatte CRTS keine native Auflösung an sich. Daher war der Computer keine bevorzugte Auflösung für eine bestimmte Überwachungsgröße oder ein Seitenverhältnis. Mit neueren digitalen Displays (LCD) ist der Computer nun die bevorzugte Auflösung und das Seitenverhältnis für Ihr Display kennen, wenn sie ordnungsgemäß installiert sind. Meine Windows 7 -Maschine zeigt "Empfohlen" neben der nativen Auflösung meines LCD und zeigt dann die anderen 2 -gleichgeeigneten Auflösungen in Schwarz, wobei die verbleibenden "Fehlanpassungen" unbeschreiblich, aber wählbar sind (was zu dem zerquetschten oder gestreckten Look führt, den ich hasse zu sehen hasse es zu sehen auf anderen Völkern Computer!).

Die Standard -DPIs von 96 und 120 in Fenstern wurden in den CRT -Tagen festgelegt. Meine Windows 7 -Maschine sagt nicht einmal mehr DPI. Es heißt nur "kleiner", "mittel", "größer".

In jedem Fall, wenn Sie einen LCD -Monitor kaufen, der 1920x1080 oder 1920x1200 heißt, die Anzeigeauflösung jedoch auf etwas kleineres festlegen, führen Sie zu einem Conversion -Faktor. Bei den nicht passenden horizontalen und vertikalen Auflösungen in der Nähe von 72 ist Ihre nicht einheimische Anzeigeauflösung möglicherweise nicht genau der gleiche Skalierungsfaktor vertikal, wie sie horizontal zu dieser geringen Diskrepanz führt.

Wie man meine Hypothese testet

Auf jedem Ihrer Testmaschinen zeichnen Sie die konfigurierte Auflösung der Betriebssysteme und die native Auflösung anzeigen. Sehen Sie, ob das Verhältnis zwischen diesen beiden nahe am Verhältnis zwischen Ihrem Metafile „auf dem Bildschirm“ gegenüber 96 oder 120DPI liegt. Ich würde es vorziehen, dass Sie diesen Test auf physischen Maschinen durchführen, um einfach die Möglichkeit einer weiteren Skalierung mit Remote -Desktop- oder virtuellen Maschinentreibern auszuschließen.

Wenn die Lösung nicht sofort erkennbar ist, gehen Sie einen Schritt weiter und zeichnen Sie die Einstellungen für das Betriebs- und Bedienfeld für DPI oder "kleiner", "mittel" und "größer" auf. Windows XP kann sich anders verhalten als Windows Vista/Windows 7.

Sie können den Test auch mehrmals auf derselben physischen Maschine erneut ausführen, um die konfigurierte Anzeigeauflösung zwischen Tests anzupassen und Änderungen zu beobachten. Wenn meine Hypothese korrekt ist, sollten Sie für jede konfigurierte Anzeigeauflösung auf derselben physischen Maschine/Anzeige -Kombination eine andere Metafilenauflösung sehen, und dieses Ergebnis sollte vorhersehbar und wiederholbar sein (die Rückkehr zur ersten Auflösung sollte auf dieselbe Metafile -Auflösung zurückkehren)

Bearbeiten #1

Ich fand einen ausgezeichneten Artikel, in dem physische DPI gegen logische DPI erörtert wird. Lesen Sie dies: Woher kommt 96 DPI in Windows?

Jetzt ist der nächste Test, den ich empfehlen würde, die Anzeige! Haben Sie einen anderen LCD -Monitor für Marke/Größe/Auflösung zum Testen verfügbar? Sie brauchen nicht so viele Zeilen wie Ihr erster Test oben, da wir die verschiedenen Auflösungen erstellt haben, die dazu neigen, ein sehr ähnliches DPI für das gleiche Display zu erzeugen. Testen Sie nur ein paar gemeinsame Auflösungen, einschließlich der nativen Auflösung des Displays und 1024x768 als "Grundlinie" zum Vergleich.

Auch während ich in Windows 7 herumstochte, fand ich den Link "Benutzerdefinierte Textgröße (Benutzerdefinierte Textgröße)" in der Bedienfelder-> Anzeige, das eine Option "DPI-Skalierung von Windows XP-Stil verwenden" enthielt. Obwohl ich nicht denke, dass dies das Hauptanliegen ist, interessiert mich Neugier für seine Wirkung, und ich dachte, ich würde es erwähnen.

Bearbeiten #2 - gelöst!

Die Auflösung, die Sie in Ihren Metafiles sehen, ist der physische DPI Ihres Monitors. Ich werde hier einen C# -Code veröffentlichen, damit Sie sich selbst testen:

[DllImport("user32.dll")]
static extern IntPtr GetDC(IntPtr hWnd);

[DllImport("user32.dll")]
static extern bool ReleaseDC(IntPtr hWnd, IntPtr hDC);

[DllImport("gdi32.dll")]
static extern int GetDeviceCaps(IntPtr hdc, int nIndex);

public enum DeviceCap
{
    /// <summary>
    /// Device driver version
    /// </summary>
    DRIVERVERSION = 0,
    /// <summary>
    /// Device classification
    /// </summary>
    TECHNOLOGY = 2,
    /// <summary>
    /// Horizontal size in millimeters
    /// </summary>
    HORZSIZE = 4,
    /// <summary>
    /// Vertical size in millimeters
    /// </summary>
    VERTSIZE = 6,
    /// <summary>
    /// Horizontal width in pixels
    /// </summary>
    HORZRES = 8,
    /// <summary>
    /// Vertical height in pixels
    /// </summary>
    VERTRES = 10,
    /// <summary>
    /// Number of bits per pixel
    /// </summary>
    BITSPIXEL = 12,
    /// <summary>
    /// Number of planes
    /// </summary>
    PLANES = 14,
    /// <summary>
    /// Number of brushes the device has
    /// </summary>
    NUMBRUSHES = 16,
    /// <summary>
    /// Number of pens the device has
    /// </summary>
    NUMPENS = 18,
    /// <summary>
    /// Number of markers the device has
    /// </summary>
    NUMMARKERS = 20,
    /// <summary>
    /// Number of fonts the device has
    /// </summary>
    NUMFONTS = 22,
    /// <summary>
    /// Number of colors the device supports
    /// </summary>
    NUMCOLORS = 24,
    /// <summary>
    /// Size required for device descriptor
    /// </summary>
    PDEVICESIZE = 26,
    /// <summary>
    /// Curve capabilities
    /// </summary>
    CURVECAPS = 28,
    /// <summary>
    /// Line capabilities
    /// </summary>
    LINECAPS = 30,
    /// <summary>
    /// Polygonal capabilities
    /// </summary>
    POLYGONALCAPS = 32,
    /// <summary>
    /// Text capabilities
    /// </summary>
    TEXTCAPS = 34,
    /// <summary>
    /// Clipping capabilities
    /// </summary>
    CLIPCAPS = 36,
    /// <summary>
    /// Bitblt capabilities
    /// </summary>
    RASTERCAPS = 38,
    /// <summary>
    /// Length of the X leg
    /// </summary>
    ASPECTX = 40,
    /// <summary>
    /// Length of the Y leg
    /// </summary>
    ASPECTY = 42,
    /// <summary>
    /// Length of the hypotenuse
    /// </summary>
    ASPECTXY = 44,
    /// <summary>
    /// Shading and Blending caps
    /// </summary>
    SHADEBLENDCAPS = 45,

    /// <summary>
    /// Logical pixels inch in X
    /// </summary>
    LOGPIXELSX = 88,
    /// <summary>
    /// Logical pixels inch in Y
    /// </summary>
    LOGPIXELSY = 90,

    /// <summary>
    /// Number of entries in physical palette
    /// </summary>
    SIZEPALETTE = 104,
    /// <summary>
    /// Number of reserved entries in palette
    /// </summary>
    NUMRESERVED = 106,
    /// <summary>
    /// Actual color resolution
    /// </summary>
    COLORRES = 108,

    // Printing related DeviceCaps. These replace the appropriate Escapes
    /// <summary>
    /// Physical Width in device units
    /// </summary>
    PHYSICALWIDTH = 110,
    /// <summary>
    /// Physical Height in device units
    /// </summary>
    PHYSICALHEIGHT = 111,
    /// <summary>
    /// Physical Printable Area x margin
    /// </summary>
    PHYSICALOFFSETX = 112,
    /// <summary>
    /// Physical Printable Area y margin
    /// </summary>
    PHYSICALOFFSETY = 113,
    /// <summary>
    /// Scaling factor x
    /// </summary>
    SCALINGFACTORX = 114,
    /// <summary>
    /// Scaling factor y
    /// </summary>
    SCALINGFACTORY = 115,

    /// <summary>
    /// Current vertical refresh rate of the display device (for displays only) in Hz
    /// </summary>
    VREFRESH = 116,
    /// <summary>
    /// Horizontal width of entire desktop in pixels
    /// </summary>
    DESKTOPVERTRES = 117,
    /// <summary>
    /// Vertical height of entire desktop in pixels
    /// </summary>
    DESKTOPHORZRES = 118,
    /// <summary>
    /// Preferred blt alignment
    /// </summary>
    BLTALIGNMENT = 119
}

private void GetScreenInfo()
{
    IntPtr sdc = IntPtr.Zero;
    try
    {
        //Get the Screen Device Context
        sdc = GetDC(IntPtr.Zero);

        // Get the Screen Devive Context Capabilities Information
        Console.WriteLine(string.Format("Size: {0} mm X {1} mm", GetDeviceCaps(sdc, (int)DeviceCap.HORZSIZE), GetDeviceCaps(sdc, (int)DeviceCap.VERTSIZE)));
        Console.WriteLine(string.Format("Desktop Resolution: {0}x{1}", GetDeviceCaps(sdc, (int)DeviceCap.DESKTOPHORZRES), GetDeviceCaps(sdc, (int)DeviceCap.DESKTOPVERTRES)));
        Console.WriteLine(string.Format("Logical DPI: {0}x{1}", GetDeviceCaps(sdc, (int)DeviceCap.LOGPIXELSX), GetDeviceCaps(sdc, (int)DeviceCap.LOGPIXELSY)));

        //Remember: Convert Millimeters to Inches 25.4mm = 1 inch
        double PhsyicalDPI_X = GetDeviceCaps(sdc, (int)DeviceCap.DESKTOPHORZRES) * 25.4 / GetDeviceCaps(sdc, (int)DeviceCap.HORZSIZE);
        double PhsyicalDPI_Y = GetDeviceCaps(sdc, (int)DeviceCap.DESKTOPVERTRES) * 25.4 / GetDeviceCaps(sdc, (int)DeviceCap.VERTSIZE);
        Console.WriteLine(string.Format("Physical DPI: {0}x{1}", PhsyicalDPI_X, PhsyicalDPI_Y));

    }
    finally
    {
        ReleaseDC(IntPtr.Zero, sdc);
    }
}

Dieser Code auf meiner Anzeige gibt Folgendes aus:

  • Größe: 677 mm x 381 mm
  • Desktop -Auflösung: 1920x1080
  • Logischer DPI: 96x96
  • Physischer DPI: 72.0354505169867x72

Beachten Sie sowohl den logischen als auch den physischen DPI? Sieht dieser physische DPI bekannt vor? Nach dem Lesen dieses Artikels über 72DPI, das 1PT = 1PX reflektiert, ist es sinnvoll. Probieren Sie diesen Code an Ihre verschiedenen Testmaschinen und lassen Sie mich wissen, wie es geht! (Zu Ihrer Information, ich habe diesen Code in einer C# Winforms -App, einer Konsolen -App, ausgeführt sollte in der Lage sein, den Kontext des Bildschirmgeräts zu erhalten, aber vielleicht auch nicht ...)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top