2010-10-28 12 views
22

Estoy trabajando en un proyecto de migración en el que una base de datos realmente almacena tamaños de pantalla en twips. Dado que no puedo usar twips para asignar tamaños a los controles WPF o Winforms, me preguntaba si .NET tiene un método de conversión utilizable en tiempo de ejecución.¿Cómo convierto Twips a Pixels en .NET?

+0

https://www.unitconverters.net/typography/twip-to-pixel-x.htm dice 1 Pixel = 15 twips ==> twips = 1/15 px – Syed

Respuesta

26

Resulta que la herramienta de migración tiene algo, pero no serviría de nada en el tiempo de ejecución. Esto es lo que hice (si el valor codificado en el método de extensión se cambiara por el valor de puntos por pulgada también funcionaría como un convertidor de punto):

1 Twip = 1/1440th of inch. El objeto .NET Graphics tiene un método DpiX y DpiY que se puede utilizar para determinar cuántos píxeles hay en una pulgada. Usando estas mediciones que crearon los siguientes métodos de extensión para Graphics:

using System.Drawing; 

static class Extensions 
{ 
    /// <summary> 
    /// Converts an integer value in twips to the corresponding integer value 
    /// in pixels on the x-axis. 
    /// </summary> 
    /// <param name="source">The Graphics context to use</param> 
    /// <param name="inTwips">The number of twips to be converted</param> 
    /// <returns>The number of pixels in that many twips</returns> 
    public static int ConvertTwipsToXPixels(this Graphics source, int twips) 
    { 
     return (int)(((double)twips) * (1.0/1440.0) * source.DpiX); 
    } 

    /// <summary> 
    /// Converts an integer value in twips to the corresponding integer value 
    /// in pixels on the y-axis. 
    /// </summary> 
    /// <param name="source">The Graphics context to use</param> 
    /// <param name="inTwips">The number of twips to be converted</param> 
    /// <returns>The number of pixels in that many twips</returns> 
    public static int ConvertTwipsToYPixels(this Graphics source, int twips) 
    { 
     return (int)(((double)twips) * (1.0/1440.0) * source.DpiY); 
    } 
} 

Para utilizar estos métodos uno simplemente tiene que hacer lo siguiente (asumiendo que usted está en un contexto en CreateGraphics devuelve un objeto Drawing.Graphics (en este caso es un this forma, por lo CreateGraphics se hereda de la clase super-Form 's Control): sección

using(Graphics g = CreateGraphics()) 
{ 
    Width = g.ConvertTwipsToXPixels(sizeInTwips); 
    Height = g.ConvertTwipsToYPixels(sizeInTwips); 
} 

Ver las 'Observaciones' en el Graphics Class documentation para una lista de formas de obtener un gráfico objeto ics La documentación más completa está disponible en el tutorial How to: Create Graphics Objects.

Breve resumen de las maneras más fáciles:

  • Control.CreateGraphics
  • PaintEventArgs de un evento de pintura tiene un Graphics disponible en su propiedad Graphics.
  • Mano Graphics.FromImage una imagen y devolverá un objeto Graphics que puede dibujar en esa imagen. (NOTA: Es poco probable que usted desee utilizar twips para una imagen real)
+2

tiene un pequeño error en su código. En ConvertTwipsToYPixles, lo tienes usando el DipX en lugar del DpiY – Wesley

+0

@downvoter ??? ¿Le importaria explicar? – Crisfole

+0

gracias, tengo otra pregunta. Dijiste que CreateGraphics devuelve un objeto Drawing.Graphics. ¿Qué tipo de gráficos devuelve? ¿Podría dar un ejemplo del método CreateGraphics por favor? –

3

Como referencia, otra versión C#, utilizando la API de Win32 en lugar de requerir un Graphics objetos:

using System.Runtime.InteropServices; 

static class SomeUtils { 

    public static int ConvertTwipsToPixels(int twips, MeasureDirection direction) { 
    return (int)(((double)twips)*((double)GetPixperinch(direction))/1440.0); 
    } 

    public static int ConvertPixelsToTwips(int pixels, MeasureDirection direction) { 
    return (int)((((double)pixels)*1440.0)/((double)GetPixperinch(direction))); 
    } 

    public static int GetPPI(MeasureDirection direction) { 
    int ppi; 
    IntPtr dc = GetDC(IntPtr.Zero); 

    if (direction == MeasureDirection.Horizontal) 
     ppi = GetDeviceCaps(dc, 88); //DEVICECAP LOGPIXELSX 
    else 
     ppi = GetDeviceCaps(dc, 90); //DEVICECAP LOGPIXELSY 

    ReleaseDC(IntPtr.Zero, dc); 
    return ppi; 
    } 

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

public enum MeasureDirection { 
    Horizontal, 
    Vertical 
} 

Se supone que se debe especificar MeasureDirection, ya que no hay garantía de que los píxeles sean siempre cuadrados (según el kb).

Referencia: kb210590: ACC2000: How to Convert Twips to Pixels

+0

+1 para una forma sin problemas de gráficos para hacer esto. – Crisfole

4

Para proyectos de migración podemos utilizar construido en funciones de apoyo converstion

microsoft.visualbasic.compatibility.vb6.twipsperpixelx 
microsoft.visualbasic.compatibility.vb6.twipsperpixely 
2

Mensaje viejo lo sé, pero aquí es un FYI y algo de matemáticas para las 1440 respuestas anteriores ...

Un twip no es simplemente 1/1440 de pulgada. Un twip es 1/20 de punto.

El punto que está trabajando en un documento imprimible, por lo general, es una posdata:

72dpi. 72dpi * 20Twips/Point = 1440twips.

Así dicen en el trato con un informe de Crystal, con un ancho de twips 15840 (y márgenes de 0 twips), el ancho sería 11 inches (15840/(72 * 20)).

Basado en una densidad de pantalla de 96 dpi, el informe a publicar a la pantalla en:

1056px wide (96dpi * 11in = 1056px).

+0

solo para toda su información que esté usando Infragistics Una pulgada es igual a 1,440 twips (vigésima parte de un punto de escritorio). Una pulgada es igual a 72 puntos de escritorio. Fuente: http://help.infragistics.com/Help/Doc/WinForms/2016.1/CLR4.0/html/Infragistics4.Documents.IO.v16.1~Infragistics.Documents.Word.WordDocumentWriter~ConvertUnits.html – Syed

Cuestiones relacionadas