WPF获取屏幕分辨率以及长度的转换

相关背景:

WPF的坐标单位是以1/96英寸为一个逻辑像素单位。如果将操作系统的DPI设置成实际的物理DPI,则可以做到分辨率与设备无关。

下面的DipHelp类,可以实现厘米与DPI,英寸与DPI的相互转换,以及获取系统分辨率,物理分辨率.。

 public static class DipHelper
    {
        /// <summary>
        /// Converts millimeters to DIP (Device Independant Pixels).
        /// </summary>
        /// <param name="mm">A millimeter value.</param>
        /// <returns>A DIP value.</returns>
        public static double MmToDip(double mm)
        {
            return CmToDip(mm / 10.0);
        }

        /// <summary>
        /// Converts centimeters to DIP (Device Independant Pixels).
        /// </summary>
        /// <param name="cm">A centimeter value.</param>
        /// <returns>A DIP value.</returns>
        public static double CmToDip(double cm)
        {
            return (cm * 96.0 / 2.54);
        }

        /// <summary>
        /// Converts inches to DIP (Device Independant Pixels).
        /// </summary>
        /// <param name="inch">An inch value.</param>
        /// <returns>A DIP value.</returns>
        public static double InchToDip(double inch)
        {
            return (inch * 96.0);
        }

        /// <summary>
        /// Converts  DIP to inches
        /// </summary>
        /// <param name="dip"></param>
        /// <returns></returns>
        public static double DipToInch(double dip)
        {
            return dip / 96D;
        }

        /// <summary>
        /// Converts font points to DIP 
        /// </summary>
        /// <param name="pt">A font point value.</param>
        /// <returns>A DIP value.</returns>
        public static double PtToDip(double pt)
        {
            return (pt * 96.0 / 72.0);
        }

        /// <summary>
        /// Converts DIP  to centimeters.
        /// </summary>
        /// <param name="dip">A DIP value.</param>
        /// <returns>A centimeter value.</returns>
        public static double DipToCm(double dip)
        {
            return (dip * 2.54 / 96.0);
        }

        /// <summary>
        /// Converts DIP to millimeters.
        /// </summary>
        /// <param name="dip">A DIP value.</param>
        /// <returns>A millimeter value.</returns>
        public static double DipToMm(double dip)
        {
            return DipToCm(dip) * 10.0;
        }

        /// <summary>
        /// Gets the system DPI scale factor (compared to 96 dpi).
        /// From http://blogs.msdn.com/jaimer/archive/2007/03/07/getting-system-dpi-in-wpf-app.aspx
        /// Should not be called before the Loaded event (else XamlException mat throw)
        /// </summary>
        /// <returns>A Point object containing the X- and Y- scale factor.</returns>
        private static Point GetSystemDpiFactor()
        {
            PresentationSource source = PresentationSource.FromVisual(Application.Current.MainWindow);
            Matrix m = source.CompositionTarget.TransformToDevice;
            return new Point(m.M11, m.M22);
        }

        private const double DpiBase = 96.0;

        /// <summary>
        /// Gets the system configured DPI.
        /// </summary>
        /// <returns>A Point object containing the X- and Y- DPI.</returns>
        public static Point GetSystemDpi()
        {
            Point sysDpiFactor = GetSystemDpiFactor();
            return new Point(
                 sysDpiFactor.X * DpiBase,
                 sysDpiFactor.Y * DpiBase);
        }

        /// <summary>
        /// Gets the physical pixel density (DPI) of the screen.
        /// </summary>
        /// <param name="diagonalScreenSize">Size - in inch - of the diagonal of the screen.</param>
        /// <returns>A Point object containing the X- and Y- DPI.</returns>
        public static Point GetPhysicalDpi(double diagonalScreenSize)
        {
            Point sysDpiFactor = GetSystemDpiFactor();
            double pixelScreenWidth = SystemParameters.PrimaryScreenWidth * sysDpiFactor.X;
            double pixelScreenHeight = SystemParameters.PrimaryScreenHeight * sysDpiFactor.Y;
            double formatRate = pixelScreenWidth / pixelScreenHeight;

            double inchHeight = diagonalScreenSize / Math.Sqrt(formatRate * formatRate + 1.0);
            double inchWidth = formatRate * inchHeight;

            double xDpi = Math.Round(pixelScreenWidth / inchWidth);
            double yDpi = Math.Round(pixelScreenHeight / inchHeight);

            return new Point(xDpi, yDpi);
        }

        /// <summary>
        /// Converts a DPI into a scale factor (compared to system DPI).
        /// </summary>
        /// <param name="dpi">A Point object containing the X- and Y- DPI to convert.</param>
        /// <returns>A Point object containing the X- and Y- scale factor.</returns>
        public static Point DpiToScaleFactor(Point dpi)
        {
            Point sysDpi = GetSystemDpi();
            return new Point(
                 dpi.X / sysDpi.X,
                 dpi.Y / sysDpi.Y);
        }

        /// <summary>
        /// Gets the scale factor to apply to a WPF application
        /// so that 96 DIP always equals 1 inch on the screen (whatever the system DPI).
        /// </summary>
        /// <param name="diagonalScreenSize">Size - in inch - of the diagonal of the screen</param>
        /// <returns>A Point object containing the X- and Y- scale factor.</returns>
        public static Point GetScreenIndependentScaleFactor(double diagonalScreenSize)
        {
            return DpiToScaleFactor(GetPhysicalDpi(diagonalScreenSize));
        }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值