如何为 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 中使用 文件、导入 Adobe 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 后,您可以使用它提供的稍微过于基础的工具构建矢量图像;但更有用的是它能够导入 Adobe Illustrator 文件。这仍然是用于工作的基准矢量图形应用程序。如果您有设计师来构建资产,或者您自己有能力构建资产,这就很棒。
如果您需要介于 Blend 的基础知识和全能的 Illustrator 之间的东西,Expression Design 是一个足够不错的选择(正如@pek 已经提到的)。
我想在我的 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 中使用 文件、导入 Adobe 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 后,您可以使用它提供的稍微过于基础的工具构建矢量图像;但更有用的是它能够导入 Adobe Illustrator 文件。这仍然是用于工作的基准矢量图形应用程序。如果您有设计师来构建资产,或者您自己有能力构建资产,这就很棒。
如果您需要介于 Blend 的基础知识和全能的 Illustrator 之间的东西,Expression Design 是一个足够不错的选择(正如@pek 已经提到的)。