Comment Excel calcule la résolution des métafichiers qu'il génère lors de la copie d'une plage « comme indiqué à l'écran »?

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

  •  25-10-2019
  •  | 
  •  

Question

J'ai un code C # Je suis de http: // bytes.com/topic/c-sharp/answers/572657-net-clipboard-metafiles qui copie une gamme de cellules dans les deux paramètres suivants:

  • Comme le montre l'écran,
  • Comme le montre l'impression .

Quand je regarde la résolution de métafichier résultant (qui est documenté comme Gets the resolution, in pixels-per-inch, of this Image object), je reçois des valeurs différentes en fonction de la méthode de copie.

  • Comme le montre l'impression , la résolution est de 600, que je crois correspond aux paramètres DPI j'ai dans Excel.

  • Comme le montre l'écran réglage, il crache sur quelque chose comme Metafile.VerticalResolution = 72.08107 et Metafile.HorizontalResolution = 71.95952. Sur d'autres machines, j'ai vu cette valeur varient beaucoup (autour de valeurs 111, 130, etc.).

Niveau de zoom ne semble pas affecter cela. D'après ce que j'ai observé, les valeurs restent cohérentes sur une seule machine, mais peuvent varier d'une machine à.

Quelqu'un peut-il expliquer la logique Excel suit lors du calcul de la résolution du métafichier dans Comme le montre l'écran Mode?

Après avoir changé les fenêtres résolution et mesure les résolutions de métafichier, voici le tableau I généré HOPE (il semble correctement formaté):

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

Après avoir exécuté une procédure similaire sur une machine virtuelle (même machine physique), ce sont les résultats. Un peu plus volatil que la machine physique lui-même. Ces données peuvent ne pas être utile, mais je pensais fournir toute façon.

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
Était-ce utile?

La solution

Mon hypothèse

Je crois que cela a à voir avec l'exécution d'une résolution non native sur un écran LCD. Dans « l'ancien temps » CRTs ne disposaient pas d'une résolution native en soi. Ainsi, l'ordinateur ne connaissait pas une résolution préférée pour une taille de moniteur donné ou rapport d'aspect. Avec des écrans numériques les plus récents (LCD) l'ordinateur est maintenant au courant de la résolution préférée et le rapport d'aspect de votre écran si elle est correctement installée. Mes fenêtres 7 appareil affiche « recommandé » à côté de ma résolution native LCD et affiche alors les 2 autres résolutions de ratios égaux en noir, avec les autres « discordances » étant sans étiquette, mais sélectionnable (résultant dans le regard ratatinée ou tendu que je déteste voir sur d'autres ordinateurs des peuples!).

Les DPIs par défaut de 96 et 120 dans les fenêtres ont été établies à l'époque CRT. Mes windows 7 machine ne dit même pas DPI plus il est dit que « plus petit », « moyen », « plus ».

De toute façon, lorsque vous achetez un moniteur LCD qui est dire 1920x1080 ou 1920x1200 mais définir la résolution d'affichage plus petit quelque chose, vous entraîne dans un facteur de conversion. Dans le cas des résolutions horizontales et verticales qui ne correspondent pas près de 72, votre résolution d'affichage non natif ne peut pas être exactement le même facteur de mise à l'échelle verticale comme il se traduit horizontalement dans ce petit écart.

Comment tester mon hypothèse

Sur chacun de vos machines de test enregistrer les systèmes d'exploitation résolution configurés et les affiche une résolution native. Voir si le rapport entre ces deux est proche du rapport entre votre métafichier « comme sur l'écran » vs 96 ou 120dpi. Je préférerais vous effectuer ce test sur des machines physiques simplement exclure la possibilité d'une nouvelle mise à l'échelle avec le bureau à distance ou les pilotes de la machine virtuelle.

Si la solution ne apparaît pas immédiatement, franchir une nouvelle étape et enregistrer les paramètres du panneau de commande et de contrôle pour DPI ou « petit », « moyen » et « plus ». Windows XP peut se comporter différemment que Windows Vista / Windows 7.

Vous pouvez également relancer le test sur la même machine physique plusieurs fois, le réglage de la résolution d'affichage configuré entre les tests et observer les changements. Si mon hypothèse est correcte, vous devriez voir une résolution différente de métafichier pour chaque résolution d'affichage configuré sur la même machine physique / combinaison d'affichage et ce résultat doit être prévisible et reproductible (retour à la première résolution devrait revenir à la même résolution Metafile)

EDIT # 1

J'ai trouvé un excellent article qui traite de DPI physique vs DPI logique. Avoir une lecture de ceci: Où 96 DPI viennent en windows

Alors maintenant, le prochain test que je vous recommande est en train de changer affiche! Avez-vous un autre écran LCD marque / taille / résolution disponible pour tester? Vous n'avez pas besoin tout autant de lignes que votre premier test ci-dessus que nous avons établi les diverses résolutions ont tendance à produire un très similaire DPI pour le même écran. Il suffit de tester peut-être une des résolutions communes couple y compris la résolution native et 1024x768 comme pour la comparaison « de base » de l'écran.

De plus en farfouillé dans Windows 7, je ne trouve le lien « Définir la taille du texte personnalisé (DPI) » dans Configuration-> affichage qui comprend une option « Utiliser Windows XP style DPI mise à l'échelle ». Bien que je ne pense pas que ce soit la principale préoccupation, la curiosité me fait intéressé par son effet, donc je pensais que je vous signale.

EDIT # 2 - RESOLU

La résolution que vous voyez dans votre métafichiers est le DPI physique de votre moniteur. Je posterai un code C # ici pour vous de vous tester:

[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);
    }
}

Ce code sur mon écran affiche le suivant:

  • Taille: 677 mm X 381 mm
  • Résolution Desktop: 1920x1080
  • DPI logique: 96x96
  • DPI physique: 72.0354505169867x72

Avis à la fois le DPI logique et physique? Est-ce que physique DPI semble familier? Il prend tout son sens après avoir lu cet article sur les 72dpi reflétant 1pt = 1px. Donnez ce code un essai sur vos différentes machines de test et laissez-moi savoir comment ça se passe! (Pour votre information, j'ai couru ce code dans une application C # WinForms, une application console devrait être en mesure d'obtenir le contexte de l'appareil de l'écran, mais peut-être pas ...)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top