WPFの画像ビューアサンプル
WPFの画像ビューアサンプル。
- クリックで回転。
- スライダで回転。
<Window x:Class="WpfApplication1.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" > <Grid> <Viewport3D> <Viewport3D.Camera> <PerspectiveCamera FieldOfView="50" LookDirection="0,-40,300" Position="0,40,-200" UpDirection="0,1,0"/> </Viewport3D.Camera> <ModelVisual3D> <ModelVisual3D.Content> <Model3DGroup x:Name="gr"> <AmbientLight/> </Model3DGroup> </ModelVisual3D.Content> </ModelVisual3D> </Viewport3D> <Slider Name="slider1" VerticalAlignment="Bottom" ValueChanged="slider1_ValueChanged" Maximum="360" /> <TextBox VerticalAlignment="Top" Text="{Binding ElementName=slider1,Path=Value}" /> </Grid> </Window>
CS
using System; using System.Collections.Generic; using System.IO; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Media.Imaging; using System.Windows.Media.Media3D; namespace WpfApplication1 { public partial class Window1 : Window { private MyDoubleValue ta = new MyDoubleValue(); public Window1() { InitializeComponent(); string dir = @"C:\Users\Public\Pictures\Sample Pictures"; List<ImageBrush> br = new List<ImageBrush>(); foreach (string f in Directory.GetFiles(dir, "*.jpg")) br.Add(new ImageBrush(new BitmapImage(new Uri(f)))); int[] ii = { 0, 3, 1, 0, 2, 3 }; Point[] pp = { new Point(1, 1), new Point(0, 1), new Point(1, 0), new Point(0, 0), }; int n = 9; for (int i = 0; i < n; ++i) { GeometryModel3D gm = new GeometryModel3D(); gr.Children.Add(gm); gm.Material = new DiffuseMaterial(br[i%br.Count]); MeshGeometry3D mg = new MeshGeometry3D(); gm.Geometry = mg; double r = 2 * Math.PI * i / n; double x = Math.Sin(r), x1 = x * 100, x2 = x * 20; double z = Math.Cos(r), z1 = z * 100, z2 = z * 20; mg.Positions.Add(new Point3D(x1 - z2, 0, z1 + x2)); mg.Positions.Add(new Point3D(x1 + z2, 0, z1 - x2)); mg.Positions.Add(new Point3D(x1 - z2, 30, z1 + x2)); mg.Positions.Add(new Point3D(x1 + z2, 30, z1 - x2)); foreach (int j in ii) mg.TriangleIndices.Add(j); foreach (Point p in pp) mg.TextureCoordinates.Add(p); } gr.Transform = new RotateTransform3D(); Binding bnd = new Binding(); bnd.Source = ta; bnd.Path = new PropertyPath("MyValue"); slider1.SetBinding(Slider.ValueProperty, bnd); MouseDown += new MouseButtonEventHandler(Window1_MouseDown); } void Window1_MouseDown(object sender, MouseButtonEventArgs e) { DoubleAnimation da1 = new DoubleAnimation( slider1.Value, slider1.Value + 40 - slider1.Value % 40, new Duration(TimeSpan.FromSeconds(0.3))); ta.BeginAnimation(MyDoubleValue.MyValueProperty, da1); } private void slider1_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e) { RotateTransform3D rt = (RotateTransform3D)gr.Transform; rt.Rotation = new QuaternionRotation3D( new Quaternion(new Vector3D(0, 1, 0), slider1.Value)); } } public class MyDoubleValue : UIElement { public static readonly DependencyProperty MyValueProperty = DependencyProperty.Register("MyValue", typeof(double), typeof(MyDoubleValue), new PropertyMetadata(0.0, cb1, cb2)); private static void cb1(DependencyObject d, DependencyPropertyChangedEventArgs w) { } private static object cb2(DependencyObject d, object o) { double dd = (double)o; return dd % 360; } } }
解説
- 画像は、サンプルから9個とってきている。(PathはVistaのもの)
- 3Dモデルは、プログラムで生成している。ただの四角だけど。
- Sliderを動かすと、絵を回転する。絵のTransfrormを予め、RotateTransform3Dにしておき、そのRotation(QuaternionRotation3D)を置き換えている。
- DoubleAnimationでSliderを直接アニメーションさせると、スライダが手動で動かないので、アニメーション用データ(MyDoubleValue)を作成して使っている。このMyValueをアニメーションさせている。
- プログラムで、MyValueとスライダをBindingしている。
- TextBoxはXAMLでSliderとBindingしている。
- MyDoubleValueの値は角度なので、360のModを取るようにCoerceValueCallback を定義している。
- StoryBoardをプログラムで追加するには、Storyboard.SetTargetProperty を使えばよい。