I'm working on a migration project in which a database actually stores display sizes in twips. Since I can't use twips to assign sizes to WPF or Winforms controls, I was wondering if .NET has a conversion method usable at runtime?
-
https://www.unitconverters.net/typography/twip-to-pixel-x.htm says 1 Pixel = 15 twips ==> 1 twips = 1/15 px – Syed Mohamed Dec 29 '17 at 05:37
4 Answers
It turns out that the migration tool has something, but it wouldn't do any good at runtime. Here's what I did (if the hard-coded value in the extension method were changed to the value for points per inch it would work as a point converter too):
1 Twip = 1/1440th of an inch.
The .NET Graphics
object has a method DpiX
and DpiY
which can be used to determine how many pixels are in an inch.
Using those measurements I created the following extension methods for 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);
}
}
To use these methods one simply has to do the following (assuming you're in a context where CreateGraphics
returns a Drawing.Graphics
object (here this
is a Form, so CreateGraphics
is inherited from Form
's super-class Control
):
using( Graphics g = CreateGraphics() )
{
Width = g.ConvertTwipsToXPixels(sizeInTwips);
Height = g.ConvertTwipsToYPixels(sizeInTwips);
}
See the "Remarks" section in the Graphics
Class documentation for a list of ways to obtain a graphics object. More complete documentation is available in the tutorial How to: Create Graphics Objects.
Brief summary of easiest ways:
Control.CreateGraphics
- a Paint event's
PaintEventArgs
has aGraphics
available in itsGraphics
property. - Hand
Graphics.FromImage
an image and it will return aGraphics
object that can draw on that image. (NOTE: It is unlikely that you'll want to use twips for an actual image)

- 18,220
- 9
- 68
- 111
-
2got a small error in your code. In the ConvertTwipsToYPixles, you have it using the DipX instead of the DpiY – Wesley Oct 28 '10 at 20:12
-
thanks, I have another question. You said that CreateGraphics returns a Drawing.Graphics object. What kind of Graphics it returns? Could you give an example of CreateGraphics method please? – Serhii Kyslyi Jun 05 '13 at 10:27
-
1`CreateGraphics` is a member of `Control`. See the [documentation](http://msdn.microsoft.com/en-us/library/system.windows.forms.control.creategraphics.aspx). `Graphics` is an abstract sealed class that encapsulates drawing to the screen. You don't need to know anything about it if you're using this. Just use any control (Form, Button, etc.) and call it on that. If your class inherits from Control you can use it like I did (with the implied `this`). – Chris Pfohl Jun 05 '13 at 16:59
For migration projects we can use built in converstion support functions
microsoft.visualbasic.compatibility.vb6.twipsperpixelx
microsoft.visualbasic.compatibility.vb6.twipsperpixely

- 18,220
- 9
- 68
- 111

- 61
- 1
- 1
For reference, another C# version, using the Win32 API instead of requiring a Graphics
objects:
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
}
The MeasureDirection
is supposed to be specified as there is no guarantee that pixels are always square (according to the kb).
Reference: kb210590: ACC2000: How to Convert Twips to Pixels

- 16,596
- 4
- 56
- 86
Old post I know but here is an FYI and some math for the 1440 answers above...
A twip is not simply 1/1440
th of an inch. A twip is 1/20
of a point.
The point you are working with in a printable document, typically, is a postscript 72dpi:
72dpi * 20Twips/Point = 1440twips
.
So in dealing with say a Crystal report, with a twips width of 15840
(and margins of 0 twips),
the width would be 11 inches (15840 / (72 * 20))
.
Based on a screen density of 96 dpi, the report will post to the screen at:
1056px wide (96dpi * 11in = 1056px)
.

- 466
- 6
- 14
-
1just for all your information who are using Infragistics One inch is equal to 1,440 twips (twentieths of a desktop point). One inch is equal to 72 desktop points. Source : http://help.infragistics.com/Help/Doc/WinForms/2016.1/CLR4.0/html/Infragistics4.Documents.IO.v16.1~Infragistics.Documents.Word.WordDocumentWriter~ConvertUnits.html – Syed Mohamed Dec 29 '17 at 06:50