如何为 WPF 创建矢量图像

How do I create vector images for WPF

我想在我的 WPF 应用程序中使用矢量图像(用于按钮和菜单)。我怎么做?我应该使用哪些工具?有人可以给我看一个完整的例子吗?

创建XAML 矢量图像的工具

创建 XAML 矢量图像的最佳应用程序可能是 Microsoft Expression Design。这是一个免费工具,可以从 https://www.microsoft.com/en-gb/download/details.aspx?id=36180

下载

安装 Expression Design 后,启动它并 select 编辑 -> 选项 -> 剪贴板 (XAML)。将 剪贴板格式 更改为 XAML WPF 资源字典。同时将 Group By 更改为 Document (否则每一层将是一个图像)。

在 Expression Design 中编辑图像。完成后,select 所有内容并打开 编辑 菜单,然后 复制 XAML。将其粘贴到适当的 XAML 文件中。您在下面的示例中看到它应该是什么样子。需要注意的一件事是,您需要将 DrawingImage 标签更改为 DrawingBrush.

绘制图像时,将文档大小设置为您在 WPF 应用程序中所需的大小(如 32x32 像素)。这不是必需的,但可以使工作更轻松。在将图像复制到 XAML 之前,您可能想制作一个与文档大小相同的透明矩形(否则边距可能会出错)。或者您可以在绘图组 children 中手动添加:

<GeometryDrawing Brush="#00FFFFFF" Geometry="M 0,0L 32,0L 32,32L 0,32L 0,0 Z " />

如果您使用的是 Inkscape

Inkscape 支持生成 XAML 文件。但是 - 这可能不是您想要的格式! WPF 有两种不同的方式来处理 XAML 中的图形——形状和几何图形。您可以在此处找到更多详细信息:http://www.intertech.com/Blog/WPF-Shapes-vs-WPF-Geometries/

但在 short shapes 中支持输入,而 geometrys 只是纯粹的绘图,因此更轻量级。

Inkscape 生成形状格式的文件,这对某些情况很有用,但不适用于应在按钮等中使用的图像。所以你想要的是将你的图像放入 Expression Design 中。您可以将图像另存为 PDF 文件,将文件扩展名更改为 AI,然后在 Expression Design 中使用 文件导入 Adob​​e Illustrator 文件。使用 EPS 是另一种选择。

大多数东西都可以导入到 Expression Design 中。但这可能是一些边界问题。当您获得了 Expression Design 所需的内容时,最好在其中完成所有工作。如果需要,您可以将图像导出为可在 Inkscape 中使用的 SVG,通常可以正常工作。

示例

当您为图像创建 XAML 代码后,它就非常简单了。下面是在菜单和两个按钮上使用矢量图像的示例。

如果要绘制一条非常细的线(1 像素),您可能需要将 RenderOptions.EdgeMode="Aliased"SnapsToDevicePixels="True" 添加到绘制图像的控件的属性中。

另一件要记住的事情是禁用按钮时要做什么。在下面的示例中,无论按钮是否启用,图像看起来都是一样的(对于普通位图也是如此)。将不透明度更改为 50% 是一种看起来很不错的方法。将其转换为灰度比较困难,但也有解决方案。

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
    xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
    x:Class="VectorGraphicsDemo.MainWindow"
    Title="MainWindow"
    Height="350"
    Width="616">

<Window.Resources>
    <!-- Note: When Expression Designed generated the code it was generated
         as DrawingBrush. Remember to change this to DrawingImage. -->
    <DrawingImage x:Key="TestImage">
        <DrawingImage.Drawing>
            <DrawingGroup>
                <GeometryDrawing Brush="#00FFFFFF"
                                 Geometry="M 0,0L 32,0L 32,32L 0,32L 0,0 Z " />
                <GeometryDrawing Brush="#FFFF0000"
                                 Geometry="F1 M 6.25,3.97918L 23.125,3.97918L 23.125,16.1458L 6.25,16.1458L 6.25,3.97918 Z ">
                    <GeometryDrawing.Pen>
                        <Pen LineJoin="Round"
                             Brush="#FF000000" />
                    </GeometryDrawing.Pen>
                </GeometryDrawing>
                <GeometryDrawing Brush="#FF00C800"
                                 Geometry="F1 M 21.8542,11.0625C 26.399,11.0625 30.0833,14.7468 30.0833,19.2917C 30.0833,23.8365 26.399,27.5208 21.8542,27.5208C 17.3093,27.5208 13.625,23.8365 13.625,19.2917C 13.625,14.7468 17.3093,11.0625 21.8542,11.0625 Z ">
                    <GeometryDrawing.Pen>
                        <Pen LineJoin="Round"
                             Brush="#FF000000" />
                    </GeometryDrawing.Pen>
                </GeometryDrawing>
                <GeometryDrawing Brush="#FFFFFF00"
                                 Geometry="F1 M 16.8731,14.9035L 11.9668,16.2498L 8.58953,12.5761L 8.25831,17.6042L 3.62852,19.7405L 8.33013,21.5017L 8.84603,26.4958L 12.083,22.5562L 17.0316,23.5064L 14.3306,19.3103L 16.8731,14.9035 Z ">
                    <GeometryDrawing.Pen>
                        <Pen LineJoin="Round"
                             Brush="#FF000000" />
                    </GeometryDrawing.Pen>
                </GeometryDrawing>
            </DrawingGroup>
        </DrawingImage.Drawing>
    </DrawingImage>

    <DrawingImage x:Key="TestThinLineImage">
        <DrawingImage.Drawing>
            <DrawingGroup>
                <GeometryDrawing Brush="#00FFFFFF"
                                 Geometry="M 0,0L 32,0L 32,32L 0,32L 0,0 Z " />
                <GeometryDrawing Geometry="F1 M 2,2L 30,2L 30,30L 2,30L 2,2 Z ">
                    <GeometryDrawing.Pen>
                        <Pen LineJoin="Round"
                             Brush="#FF000000" />
                    </GeometryDrawing.Pen>
                </GeometryDrawing>
                <GeometryDrawing Geometry="F1 M 7,8L 25,8L 25,24L 7,24L 7,8 Z ">
                    <GeometryDrawing.Pen>
                        <Pen LineJoin="Round"
                             Brush="#FFFF0000" />
                    </GeometryDrawing.Pen>
                </GeometryDrawing>
            </DrawingGroup>
        </DrawingImage.Drawing>
    </DrawingImage>
</Window.Resources>
<Grid>

    <!-- Menu with image -->
    <Menu HorizontalAlignment="Stretch"
          VerticalAlignment="Top">
        <MenuItem Header="Hello">
            <MenuItem Header="World">
                <MenuItem.Icon>
                    <Image Source="{StaticResource TestImage}" />
                </MenuItem.Icon>
            </MenuItem>
        </MenuItem>
    </Menu>

    <!-- Small standard image -->
    <Button HorizontalAlignment="Left"
            Margin="12,66,0,0"
            VerticalAlignment="Top"
            Width="142"
            Height="43">
        <StackPanel Orientation="Horizontal">
            <Image x:Name="imageSmall"
                   Source="{StaticResource TestImage}"
                   Height="32"
                   Width="32" />
            <Label VerticalAlignment="Center"
                   Content="Small image" />
        </StackPanel>
    </Button>

    <!-- Large standard image -->
    <Button HorizontalAlignment="Left"
            Margin="12,149,0,0"
            VerticalAlignment="Top"
            Width="142"
            Height="75">
        <StackPanel Orientation="Horizontal">
            <Image x:Name="imageLarge"
                   Source="{StaticResource TestImage}"
                   Height="64"
                   Width="64">
            </Image>
            <Label VerticalAlignment="Center"
                   Content="Large image" />
        </StackPanel>
    </Button>

    <!-- Small image with thin line with antialising enabled - looks bad! -->
    <Button HorizontalAlignment="Left"
            Margin="180,67,0,0"
            VerticalAlignment="Top"
            Width="177"
            Height="43">
        <StackPanel Orientation="Horizontal">
            <Image x:Name="imageSmall1"
                   Source="{StaticResource TestThinLineImage}"
                   Height="32"
                   Width="32" />
            <Label VerticalAlignment="Center"
                   Content="Small thin anti alias" />
        </StackPanel>
    </Button>

    <!-- Large image with thin line with antialising enabled - looks bad! -->
    <Button HorizontalAlignment="Left"
            Margin="180,149,0,0"
            VerticalAlignment="Top"
            Width="177"
            Height="75">
        <StackPanel Orientation="Horizontal">
            <Image Source="{StaticResource TestThinLineImage}"
                   Height="64"
                   Width="64">
            </Image>
            <Label VerticalAlignment="Center"
                   Content="Large thin anti alias" />
        </StackPanel>
    </Button>

    <!-- Small image with thin line with antialising disabled - looks OK! -->
    <Button HorizontalAlignment="Left"
            Margin="391,67,0,0"
            VerticalAlignment="Top"
            Width="177"
            Height="43">
        <StackPanel Orientation="Horizontal">
            <Image SnapsToDevicePixels="True"
                   RenderOptions.EdgeMode="Aliased"
                   Source="{StaticResource TestThinLineImage}"
                   Height="32"
                   Width="32" />
            <Label VerticalAlignment="Center"
                   Content="Small thin alias" />
        </StackPanel>
    </Button>

    <!-- Large image with thin line with antialising disabled - looks OK! -->
    <Button HorizontalAlignment="Left"
            SnapsToDevicePixels="True"
            RenderOptions.EdgeMode="Aliased"
            Margin="391,149,0,0"
            VerticalAlignment="Top"
            Width="177"
            Height="75">
        <StackPanel Orientation="Horizontal">
            <Image Source="{StaticResource TestThinLineImage}"
                   Height="64"
                   Width="64" />
            <Label VerticalAlignment="Center"
                   Content="Large thin alias" />
        </StackPanel>
    </Button>
</Grid>

如果你有 VS2013,你应该有 Blend。如果没有,您可以从 Add/Remove 程序 添加它,方法是修改您的 Studio 安装并选中复选框。

获得 Blend 后,您可以使用它提供的稍微过于基础的工具构建矢量图像;但更有用的是它能够导入 Adob​​e Illustrator 文件。这仍然是用于工作的基准矢量图形应用程序。如果您有设计师来构建资产,或者您自己有能力构建资产,这就很棒。

如果您需要介于 Blend 的基础知识和全能的 Illustrator 之间的东西,Expression Design 是一个足够不错的选择(正如@pek 已经提到的)。