SourceChord

C#とXAML好きなプログラマの備忘録。最近はWPF系の話題が中心です。

PowerPointをBlendのかわりに使用する方法(XPS形式のデータをXAMLに持ってく)

パワポやワードなどでも出力できるファイル形式にXPS形式というのがあります。
このデータの中身はXML形式のベクターデータなどになっていて、
パスのデータはXAMLでのパス要素として扱える形式になっているそうです。


そこで、パワポの図形描画機能を、Expression Blendの代替として利用できるか試してみました。

・参考サイト
http://knowhow.sqlendia.com/pages/deecc672ddb84b8c8d731bcf3ad8c5e2.htm

パワポで適当な図形をxpsで保存

とりあえず、いかの画像のように、ギザギザの図形を1つ書いてxpsとして保存しました。

XPSの中身


xpsは、XMLで書かれたテキストファイルや画像ファイルなどを、zip形式で圧縮しているようです。
なので、xpsファイルの拡張子をzipに変更すると展開することができ、
xmlのデータなどを見ることができます。
zipを解凍すると、以下のようなフォルダが出てきます。

この中の、以下の階層にあるファイルをテキストエディタで開きます。
Documents⇒1⇒Pages⇒1.fpage

以下のような内容になってます。

<FixedPage xmlns="http://schemas.microsoft.com/xps/2005/06" Width="960"
Height="720" xml:lang="ja-JP">
 <Canvas>
  <Canvas.RenderTransform>
   <MatrixTransform Matrix="1.333333333,0,0,1.333333333,0,0"/>
  </Canvas.RenderTransform>
  <Canvas Clip="M 0,0 L 720,0 L 720,540 L 0,540 Z ">
   <Path Data="M 0,0 L 720,0 L 720,540 L 0,540 Z ">
    <Path.Fill>
     <SolidColorBrush Color="#FFFFFFFF"/>
    </Path.Fill>
   </Path>
  </Canvas>
  <Path
  Data="M 94.951,38.742 L 127.67,0.53543 L 124.45,35.613 L 161.59,29.895 L 146.84,48.721 L 185.48,54.136 L 154.8,69.537 L 189.9,88.081 L 148.03,85.788 L 159.53,119.73 L 123.26,95.768 L 116.46,130.55 L 92.595,98.917 L 74.598,142.82 L 67.829,103.48 L 41.866,116.58 L 49.823,92.343 L 1.1869,96.624 L 32.723,78.101 L 0,57.285 L 40.68,50.711 L 3.253,15.653 L 64.285,42.167 L 73.429,15.653 Z ">
   <Path.Fill>
    <SolidColorBrush Color="#FF4F81BD"/>
   </Path.Fill>
  </Path>
  <Canvas Clip="M 0,-0.000000003 L 720,-0.000000003 L 720,540 L 0,540 Z ">
   <Path
   Data="M 94.951,38.742 L 127.67,0.53543 L 124.45,35.613 L 161.59,29.895 L 146.84,48.721 L 185.48,54.136 L 154.8,69.537 L 189.9,88.081 L 148.03,85.788 L 159.53,119.73 L 123.26,95.768 L 116.46,130.55 L 92.595,98.917 L 74.598,142.82 L 67.829,103.48 L 41.866,116.58 L 49.823,92.343 L 1.1869,96.624 L 32.723,78.101 L 0,57.285 L 40.68,50.711 L 3.253,15.653 L 64.285,42.167 L 73.429,15.653 Z "
   Stroke="#FF385D8A" StrokeThickness="2" StrokeLineJoin="Round">
   </Path>
  </Canvas>
 </Canvas>
</FixedPage>

FixedPageの下のCanvas要素をWPFのアプリにコピペします。
ついでに、いらなそうな要素を削除して以下のようなXAMLにしてみました。
(XMLの中の最初の方に出てくる白色のパスを削除。ほかにもCanvasのClipプロパティを削除したり。)
あと、Viewboxにいれて、サイズがちょうどよくなるように、CanvasのWidth/Heightを調整。

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Viewbox Stretch="Fill">
            <Canvas Width="192" Height="145">
                <Path
  Data="M 94.951,38.742 L 127.67,0.53543 L 124.45,35.613 L 161.59,29.895 L 146.84,48.721 L 185.48,54.136 L 154.8,69.537 L 189.9,88.081 L 148.03,85.788 L 159.53,119.73 L 123.26,95.768 L 116.46,130.55 L 92.595,98.917 L 74.598,142.82 L 67.829,103.48 L 41.866,116.58 L 49.823,92.343 L 1.1869,96.624 L 32.723,78.101 L 0,57.285 L 40.68,50.711 L 3.253,15.653 L 64.285,42.167 L 73.429,15.653 Z ">
                    <Path.Fill>
                        <SolidColorBrush Color="#FF4F81BD"/>
                    </Path.Fill>
                </Path>
                <Canvas>
                    <Path
   Data="M 94.951,38.742 L 127.67,0.53543 L 124.45,35.613 L 161.59,29.895 L 146.84,48.721 L 185.48,54.136 L 154.8,69.537 L 189.9,88.081 L 148.03,85.788 L 159.53,119.73 L 123.26,95.768 L 116.46,130.55 L 92.595,98.917 L 74.598,142.82 L 67.829,103.48 L 41.866,116.58 L 49.823,92.343 L 1.1869,96.624 L 32.723,78.101 L 0,57.285 L 40.68,50.711 L 3.253,15.653 L 64.285,42.167 L 73.429,15.653 Z "
   Stroke="#FF385D8A" StrokeThickness="2" StrokeLineJoin="Round">
                    </Path>
                </Canvas>
            </Canvas>
        </Viewbox>
    </Grid>
</Window>

パワポで書いたパスをWPFのボタンに適用してみた

以下のサイトの記事などを参考に、Button.Styleも指定する。
(このへんの指定をしておかないと、ホバーしても色が変わらなかったり、クリックしても色が変わらず、ボタンっぽくならない。)
結果とコードは↓の通り。

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Button Content="Button" Name="button1" Margin="68,69,218,130">
            <Button.Style>
                <Style TargetType="{x:Type Button}">
                    <Style.Triggers>
                        <Trigger Property="IsMouseOver" Value="true">
                            <Setter Property="Foreground" Value="Blue" />
                        </Trigger>
                        <Trigger Property="IsPressed" Value="true">
                            <Setter Property="Background" Value="Yellow" />
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </Button.Style>
            <Button.Template>
                <ControlTemplate TargetType="Button">
                    <Grid>
                        <Viewbox Stretch="Fill">
                            <Canvas Width="192" Height="145">
                                <Path  Fill="{TemplateBinding Property=Background}" 
      Data="M 94.951,38.742 L 127.67,0.53543 L 124.45,35.613 L 161.59,29.895 L 146.84,48.721 L 185.48,54.136 L 154.8,69.537 L 189.9,88.081 L 148.03,85.788 L 159.53,119.73 L 123.26,95.768 L 116.46,130.55 L 92.595,98.917 L 74.598,142.82 L 67.829,103.48 L 41.866,116.58 L 49.823,92.343 L 1.1869,96.624 L 32.723,78.101 L 0,57.285 L 40.68,50.711 L 3.253,15.653 L 64.285,42.167 L 73.429,15.653 Z ">
                                </Path>
                                <Canvas>
                                    <Path Stroke="{TemplateBinding Property=Foreground}"
       Data="M 94.951,38.742 L 127.67,0.53543 L 124.45,35.613 L 161.59,29.895 L 146.84,48.721 L 185.48,54.136 L 154.8,69.537 L 189.9,88.081 L 148.03,85.788 L 159.53,119.73 L 123.26,95.768 L 116.46,130.55 L 92.595,98.917 L 74.598,142.82 L 67.829,103.48 L 41.866,116.58 L 49.823,92.343 L 1.1869,96.624 L 32.723,78.101 L 0,57.285 L 40.68,50.711 L 3.253,15.653 L 64.285,42.167 L 73.429,15.653 Z "
       StrokeThickness="2" StrokeLineJoin="Round">
                                    </Path>
                                </Canvas>
                            </Canvas>
                        </Viewbox>
                        <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
                    </Grid>
                </ControlTemplate>
            </Button.Template>
        </Button>
    </Grid>
</Window>

パワポをパスを描くツールとして利用してみる


パワポの図形のフリーフォームを使うとベジェ曲線で色々描ける。
パスとしてトレースしたい画像を表示して、その上でフリーフォームでなぞっていくと、手っ取り早くパスが書けそう。

パスの細かい編集

パスを右クリックして、「頂点の編集」を選ぶと、パスの詳細な編集ができる。
頂点を移動させるのはもちろん、2つのハンドルでベジェの曲がり具合も編集できる。

感想

とりあえず、Visualstudio上で座標を直接入力するよりは随分ましと思います。
でも、そのパスをWPFの方で使うには、XAMLを色々いじって微調整が必要な感じ。


Windows PhoneのSDKをインストールすれば、Windows Phone用のBlendがインストールされるので、そっちでパスだけ書いてパス要素の部分だけWPFプロジェクトのXAMLコードに持ってきた方が使い勝手良いかも。。。


ただ、パワポでも想像以上にいじれるなぁ、と。
意外とベジェ曲線の編集がやりやすかった。