Как конвертировать твипы в пиксели в .NET?

Я работаю над проектом миграции, в котором база данных фактически хранит размеры дисплея в твипах. Поскольку я не могу использовать twips для назначения размеров элементам управления WPF или Winforms, мне было интересно, есть ли в .NET метод преобразования, который можно использовать во время выполнения?


person Chris Pfohl    schedule 28.10.2010    source источник
comment
unitconverters.net/typography/twip-to-pixel-x.htm говорит, что 1 пиксель = 15 твипов ==> 1 твипс = 1/15 пикселя   -  person Syed Mohamed    schedule 29.12.2017


Ответы (4)


Оказывается, в инструменте миграции что-то есть, но во время выполнения это не принесет никакой пользы. Вот что я сделал (если бы жестко закодированное значение в методе расширения было изменено на значение точек на дюйм, оно также работало бы как преобразователь точек):

1 твип = 1/1440 дюйма. Объект .NET Graphics имеет методы DpiX и DpiY, которые можно использовать для определения количества пикселей в дюйме. Используя эти измерения, я создал следующие методы расширения для 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);
    }
}

Чтобы использовать эти методы, нужно просто сделать следующее (при условии, что вы находитесь в контексте, где CreateGraphics возвращает объект Drawing.Graphics (здесь this — это форма, поэтому CreateGraphics наследуется от суперкласса Form Control):

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

См. раздел «Примечания» в Graphics документации по классу. для списка способов получения графического объекта. Более полная документация доступна в руководстве Как создавать графические объекты.

Кратко о самых простых способах:

  • Control.CreateGraphics
  • PaintEventArgs события Paint имеет Graphics, доступное в его свойстве Graphics.
  • Передайте Graphics.FromImage изображение, и он вернет Graphics объект, который может рисовать на этом изображении. (ПРИМЕЧАНИЕ: маловероятно, что вы захотите использовать твипы для фактического изображения)
person Chris Pfohl    schedule 28.10.2010
comment
получил небольшую ошибку в вашем коде. В ConvertTwipsToYPixles используется DipX вместо DpiY. - person Wesley; 29.10.2010
comment
спасибо, у меня есть еще вопрос. Вы сказали, что CreateGraphics возвращает объект Drawing.Graphics. Какую графику он возвращает? Не могли бы вы привести пример метода CreateGraphics, пожалуйста? - person Serhii Kyslyi; 05.06.2013
comment
CreateGraphics является членом Control. См. документацию. Graphics — это абстрактный запечатанный класс, который инкапсулирует рисование на экране. Вам не нужно ничего знать об этом, если вы используете это. Просто используйте любой элемент управления (форма, кнопка и т. д.) и вызовите его. Если ваш класс наследуется от Control, вы можете использовать его, как я (с подразумеваемым this). - person Chris Pfohl; 05.06.2013

Для проектов миграции мы можем использовать встроенные функции поддержки конвертации.

microsoft.visualbasic.compatibility.vb6.twipsperpixelx
microsoft.visualbasic.compatibility.vb6.twipsperpixely
person Jayesh    schedule 15.07.2012

Для справки, другая версия С#, использующая API Win32 вместо того, чтобы требовать Graphics объектов:

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
}

Предполагается, что MeasureDirection должно быть указано, так как нет гарантии, что пиксели всегда будут квадратными (согласно kb).

Ссылка: kb210590: ACC2000: как конвертировать твипы в пиксели

person Renaud Bompuis    schedule 14.12.2010

Старый пост, который я знаю, но вот к вашему сведению и немного математики для 1440 ответов выше...

Твип — это не просто 1/1440 дюйма. Твип составляет 1/20 балла.

Точка, с которой вы работаете в печатном документе, обычно представляет собой постскриптум 72 dpi:

72dpi * 20Twips/Point = 1440twips.

Таким образом, при работе с отчетом Crystal с шириной твипов 15840 (и полями 0 твипов) ширина будет 11 inches (15840 / (72 * 20)).

При разрешении экрана 96 dpi отчет будет размещен на экране по адресу:

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

person ShaneLS    schedule 21.03.2014
comment
просто для всей вашей информации, кто использует Infragistics. Один дюйм равен 1440 твипам (двадцатым точкам рабочего стола). Один дюйм равен 72 точкам рабочего стола. Источник: help.infragistics.com/Help/Doc/WinForms/2016.1/CLR4.0/html/ - person Syed Mohamed; 29.12.2017