Я работаю над проектом миграции, в котором база данных фактически хранит размеры дисплея в твипах. Поскольку я не могу использовать twips для назначения размеров элементам управления WPF или Winforms, мне было интересно, есть ли в .NET метод преобразования, который можно использовать во время выполнения?
Как конвертировать твипы в пиксели в .NET?
Ответы (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
объект, который может рисовать на этом изображении. (ПРИМЕЧАНИЕ: маловероятно, что вы захотите использовать твипы для фактического изображения)
CreateGraphics
является членом Control
. См. документацию. Graphics
— это абстрактный запечатанный класс, который инкапсулирует рисование на экране. Вам не нужно ничего знать об этом, если вы используете это. Просто используйте любой элемент управления (форма, кнопка и т. д.) и вызовите его. Если ваш класс наследуется от Control, вы можете использовать его, как я (с подразумеваемым this
).
- person Chris Pfohl; 05.06.2013
Для проектов миграции мы можем использовать встроенные функции поддержки конвертации.
microsoft.visualbasic.compatibility.vb6.twipsperpixelx
microsoft.visualbasic.compatibility.vb6.twipsperpixely
Для справки, другая версия С#, использующая 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: как конвертировать твипы в пиксели
Старый пост, который я знаю, но вот к вашему сведению и немного математики для 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)
.