首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

Windows 7 感應器開發實戰(二):WPF 應用程式整合光線與加速度感應器

     編輯:關於.NET

任務 5:整合 ViewModel 與感應器助手

在 SensorViewModel.cs 中建立感應器屬性:

private SensorHelper<AmbientLightSensor, AmbientLightSensor.LuminousIntensity> _sensor;
public SensorHelper<AmbientLightSensor, AmbientLightSensor.LuminousIntensity> LightSensor
{
    get { return _sensor; }
}

private SensorHelper<Accelerometer3D, Accelerometer3D.Acceleration3D> _accelerometerSensor;
public SensorHelper<Accelerometer3D, Accelerometer3D.Acceleration3D> AccelerometerSensor
{
    get { return _accelerometerSensor; }
}

建構函式初始化:

public SensorViewModel()
{
    _sensor = new SensorHelper<AmbientLightSensor, AmbientLightSensor.LuminousIntensity>();
    _sensor.Initialize();
    _accelerometerSensor = new SensorHelper<Accelerometer3D, Accelerometer3D.Acceleration3D>();
    _accelerometerSensor.Initialize();
}

編譯測試,確認感應器整合運作。

任務 6:UI 整合光線感應器互動

1. 新增亮度指示器(ProgressBar)

編輯 MainWindow.xaml,在左側感應器資料區域加入:

<TextBlock ... Text="LUM"/>
<ProgressBar x:Name="LightIntensityProgressBar" Width="10" Orientation="Vertical"
    Maximum="1" Minimum="0"
    Style="{StaticResource SensorProgressBar}"
    Value="{Binding Path=LightSensor.Value.Intensity, Mode=OneWay, Converter={StaticResource LuminosityConverter}}"/>

2. 建立數值轉換器:LuminosityConverter

在 MainWindow.xaml.cs 加入:

public class LuminosityConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        double d = System.Convert.ToDouble(value);
        return Math.Max(Math.Min(Math.Log(d, 10000), 1.0), 0.0);  // 對數縮放映射 0~1
    }
    public object ConvertBack(...) { throw new NotImplementedException(); }
}

3. 宣告轉換器資源

<Window.Resources>
    <local:LuminosityConverter x:Key="LuminosityConverter" />
</Window.Resources>

執行應用程式,進度條將反映環境光強度。

4. 連動圖片名稱字體大小

XAML 繫結:

<TextBlock FontSize="{Binding ElementName=LightIntensityProgressBar, Path=Value, Converter={StaticResource LuminosityToFontSizeConverter}}"
    Text="{Binding ImageName, Mode=OneWay}"/>

新增轉換器:

public class LuminosityToFontSizeConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        double d = System.Convert.ToDouble(value);
        return 70.0 * d + 13.0;  // 映射至 13~83pt
    }
    ...
}

宣告資源並執行,光線增強時字體放大。

5. 灰階效果與漸層遮罩

引入 PixelShaders 命名空間:

xmlns:PixelShaders="clr-namespace:SensorHOL.PixelShaders"

第二張圖片套用灰階效果與不透明度遮罩:

<Image Source="{Binding ImagePath}" Stretch="Uniform" Margin="10">
    <Image.Effect>
        <PixelShaders:GrayscaleEffect DesaturationFactor="{Binding ElementName=LightIntensityProgressBar, Path=Value, Converter={StaticResource InvertLuminosityConverter}}"/>
    </Image.Effect>
    <Image.OpacityMask>
        <LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
            <GradientStop Offset="{Binding ElementName=OverlayAdjustmentSlider, Path=Value}" Color="#0000"/>
            <GradientStop Offset="{Binding ElementName=OverlayAdjustmentSlider, Path=Value}" Color="#F000"/>
        </LinearGradientBrush>
    </Image.OpacityMask>
</Image>

6. 反轉亮度轉換器

public class InvertLuminosityConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        double d = System.Convert.ToDouble(value);
        return 1 - d;  // 亮度高 → 去飽和度低(保留彩色)
    }
    ...
}

宣告資源後執行,滑桿控制圖片遮罩位置,光線感應器控制灰階強度。

任務 7:整合 3D 加速度感應器(可選)

1. 新增 X/Y/Z 三軸進度條

<ProgressBar x:Name="AccelerometerX" ...
    Value="{Binding Path=AccelerometerSensor.Value, Converter={StaticResource AccelerationConverter}, ConverterParameter=X}"/>
<ProgressBar x:Name="AccelerometerY" ... ConverterParameter=Y />
<ProgressBar x:Name="AccelerometerZ" ... ConverterParameter=Z />

2. 參考 Windows API Code Pack

using Microsoft.WindowsAPICodePack.Sensors;

3. 多軸數值轉換器

public class AccelerationConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var axis = (Accelerometer3D.AccelerationAxis?)Enum.Parse(typeof(Accelerometer3D.AccelerationAxis), parameter as string);
        if (axis.HasValue)
        {
            var a3d = value as Accelerometer3D.Acceleration3D;
            if (a3d != null) return a3d[axis.Value];
        }
        return 0.0;
    }
    ...
}

4. 圖片與滑桿旋轉轉換

為 Image 與 Slider 加入 RotateTransform,繫結角度與中心點:

<Image.RenderTransform>
    <RotateTransform
        Angle="{Binding Path=AccelerometerSensor.Value, Converter={StaticResource DegreesFromAcceleratorConverter}}"
        CenterX="{Binding RelativeSource={RelativeSource AncestorType=Image}, Path=ActualWidth, Converter={StaticResource DoubleSplitConverter}}"
        CenterY="{Binding RelativeSource={RelativeSource AncestorType=Image}, Path=ActualHeight, Converter={StaticResource DoubleSplitConverter}}"/>
</Image.RenderTransform>

5. 角度計算轉換器(含平滑濾波)

public class DegreesFromAcceleratorConverter : IValueConverter
{
    private double _prevX, _prevY;
    private const double _histCoeff = 0.6, _threshold = 0.1;
    private bool _prevValuesInit;

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var a3d = value as Accelerometer3D.Acceleration3D;
        if (a3d != null)
        {
            double x = a3d[Accelerometer3D.AccelerationAxis.X];
            double y = a3d[Accelerometer3D.AccelerationAxis.Y];

            if (!_prevValuesInit) { _prevValuesInit = true; _prevX = x; _prevY = y; }
            if (Math.Abs(_prevX - x) < _threshold) x = _prevX;
            if (Math.Abs(_prevY - y) < _threshold) y = _prevY;

            _prevX = _histCoeff * _prevX + (1 - _histCoeff) * x;
            _prevY = _histCoeff * _prevY + (1 - _histCoeff) * y;

            double radians = Math.Atan2(_prevX, -_prevY);
            return radians * 180 / Math.PI;
        }
        return 0.0;
    }
    ...
}

6. 中心點計算轉換器

public class DoubleSplitConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return System.Convert.ToDouble(value) / 2.0;
    }
    ...
}

7. 宣告所有轉換器資源並執行

<Window.Resources>
    <local:LuminosityConverter x:Key="LuminosityConverter"/>
    <local:LuminosityToFontSizeConverter x:Key="LuminosityToFontSizeConverter"/>
    <local:InvertLuminosityConverter x:Key="InvertLuminosityConverter"/>
    <local:AccelerationConverter x:Key="AccelerationConverter"/>
    <local:DoubleSplitConverter x:Key="DoubleSplitConverter"/>
    <local:DegreesFromAcceleratorConverter x:Key="DegreesFromAcceleratorConverter"/>
</Window.Resources>

完成畫面

最終版本位於 Final 解決方案資料夾。透過感應器 API 整合,應用程式能即時回應環境變化,創造豐富使用者體驗。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved