In che modo Excel calcola la risoluzione dei metafile che genera durante la copia di una gamma “come mostrato sullo schermo”?

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

  •  25-10-2019
  •  | 
  •  

Domanda

Ho qualche codice C # che ho ricevuto da http: // bytes.com/topic/c-sharp/answers/572657-net-clipboard-metafiles che copia un intervallo di celle in presenza delle seguenti due impostazioni:

  • Come mostrato sullo schermo,
  • Come mostrato in fase di stampa .

Quando guardo la risoluzione del metafile risultante (che è documentato come Gets the resolution, in pixels-per-inch, of this Image object), ottengo valori diversi a seconda del metodo di copia.

  • Con il Come mostrato in fase di stampa , la risoluzione è di 600, che credo corrisponda alle impostazioni DPI che ho in Excel.

  • Con il Come mostrato sullo schermo impostazione, sputa fuori qualcosa come Metafile.VerticalResolution = 72.08107 e Metafile.HorizontalResolution = 71.95952. Su altre macchine, ho visto questo valore variano molto (valori intorno a 111, 130, ecc.).

livello

Lo zoom non sembra influenzare questo. Da quello che ho osservato, i valori rimangono coerenti su una singola macchina, ma potrebbero differire da macchina a macchina.

Qualcuno può spiegare la logica di Excel segue quando si calcola la risoluzione del metafile in Come mostrato sullo schermo modalità?

Dopo aver modificato la risoluzione di Windows e misurando le risoluzioni metafile, qui è la tabella I generato (speranza sembra formattato correttamente):

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

Dopo l'esecuzione di una procedura simile in una macchina virtuale (stessa macchina fisica), questi sono i risultati. Un po 'più volatile rispetto alla macchina fisica in sé. Questi dati non potrebbe essere utile, ma ho pensato di fornire in ogni modo.

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
È stato utile?

Soluzione

La mia ipotesi

Credo che questo abbia a che fare con l'esecuzione di una risoluzione non nativa su un monitor LCD. In "vecchi tempi" CRT non hanno una risoluzione nativa di per sé. Quindi il computer non era a conoscenza di qualsiasi risoluzione preferito per una data dimensione del monitor o le proporzioni. Con display digitali più recenti (LCD) il computer è ora a conoscenza della risoluzione preferita e rapporto di aspetto per lo schermo, se installato correttamente. Le mie finestre 7 macchina mostra "raccomandato" accanto alla risoluzione nativa del mio LCD e quindi mostra gli altri 2 pari risoluzioni proporzioni in nero, con i restanti "mismatch" di essere privi di etichetta, ma selezionabili (con conseguente sguardo schiacciata o allungata che odio vedere su altri computer popoli!).

I DPI di default di 96 e 120 in finestre sono state stabilite nei giorni CRT. Le mie finestre 7 macchina non dice nemmeno DPI più si dice solo, 'medium' 'piccolo', 'grande'.

In entrambi i casi, quando si acquista un monitor LCD che è dire 1920x1080 o 1920x1200, ma impostare la risoluzione del display a qualcosa di più piccolo, è risultato un fattore di conversione. Nel caso delle risoluzioni orizzontali e verticali non corrispondenza vicino a 72, la risoluzione dello schermo non nativa non può essere esattamente lo stesso fattore di scala verticale come è orizzontalmente traduce in questa piccola discrepanza.

Come testare la mia ipotesi

In ciascuna delle vostre macchine di prova registrare la risoluzione configurato i sistemi operativi ei display risoluzione nativa. Vedere se il rapporto tra i due è vicino al rapporto tra il metafile 'come sullo schermo' vs sia 96 o 120dpi. Io preferirei di condurre il test su macchine fisiche semplicemente escludere la possibilità di un ulteriore ridimensionamento con il desktop remoto o driver delle macchine virtuali.

Se la soluzione non è immediatamente evidente, fare un passo avanti e registrare le impostazioni del pannello comando e di controllo per DPI o 'più piccolo', 'media' e 'grande'. Windows XP può comportarsi in modo diverso rispetto a Windows Vista / Windows 7.

Si potrebbe anche ri-eseguire il test sulla stessa macchina fisica più volte, regolare la risoluzione visualizzazione configurata tra un test e osservare eventuali modifiche. Se la mia ipotesi è corretta si dovrebbe vedere risoluzione metafile diverso per ogni risoluzione dello schermo configurato sulla stessa combinazione di fisica della macchina / display e questo risultato dovrebbe essere prevedibile e ripetibile (tornando alla prima risoluzione dovrebbe tornare alla stessa risoluzione metafile)

EDIT # 1

Ho trovato un eccellente articolo che discute DPI fisico vs logica DPI. Avere una lettura di questo: dove viene 96 DPI provengono in di Windows?

Così ora il prossimo test io consiglierei sta cambiando schermi! Avete un differente del monitor LCD di marca / formato / risoluzione per il test? Non hai bisogno di più così tante linee come il primo test di cui sopra come abbiamo stabilito le varie risoluzioni tendono a produrre una molto simile DPI per lo stesso display. Proprio di prova forse un paio risoluzioni comuni, tra cui la risoluzione nativa del display e 1024x768 come "base" per il confronto.

Anche mentre rovistando in Windows 7, ho trovato il "Formato Custom Text (DPI)" collegamento nel Pannello di controllo-> display che includeva un'opzione "Usa ridimensionamento di Windows XP Style DPI". Anche se non credo che questo sia la preoccupazione principale, la curiosità mi fa interessata nei suoi effetti, così ho pensato di parlarne.

EDIT # 2 - Risolto

La risoluzione che state vedendo nelle vostre metafile è il DPI fisica del monitor. Vi posto qualche codice C # qui per voi per mettervi alla prova:

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

Questo codice sul mio display emette il seguente:

  • Dimensioni: 677 millimetri x 381 millimetri
  • Risoluzione Desktop: 1920x1080
  • Logical DPI: 96x96
  • DPI fisico: 72.0354505169867x72

Avviso sia la logica e fisica DPI? Ritiene che PHYSical DPI sembra familiare? Tutto ha un senso dopo aver letto quell'articolo merito 72dpi riflettente 1pt = 1 pixel. Dare a questo codice di una prova sulle varie macchine di prova e fammi sapere come va! (FYI, ho eseguito questo codice in un C # WinForms app, una console app dovrebbe essere in grado di ottenere il contesto di periferica schermo, ma forse no ...)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top