您的位置:首页 > 其它

WPF and Silverlight 学习笔记(二十七):基本图形的使用(2)Path和位图操作

2009-06-16 16:18 1001 查看
在上一篇文章中主要讨论的是除Path之外的基本图形,本文主要讨论使用Path创建更加复杂的图形以及位图的处理。

一、使用Path构建复杂图形

Path所构建的图形由Data属性来定义,其属性的类型为Geometry(几何类),几何类类型的继承关系请参考我上一篇文章。例如要创建一个100*30的矩形,可以有两种做法:

1: <StackPanel>


2:     <!--使用Rectangle直接创建矩形图形-->


3:     <Rectangle Fill="Red" Width="100" Height="30" HorizontalAlignment="Left" />


4:     <!--使用Path创建矩形图形-->


5:     <Path Fill="Blue">


6:         <Path.Data>


7:             <RectangleGeometry Rect="0,0,100,30" />


8:         </Path.Data>


9:     </Path>


10: </StackPanel>


从上面的代码来看,如果创建单一的图形,使用相应的图形类更简单,但是通过Path可以构建更加复杂的图形,例如想创建一个圆环,一种做法是使用两个圆形构建,另一种做法就是例如Path,可以直接绘制出圆环:

1: <Grid>


2:     <Grid.RowDefinitions>


3:         <RowDefinition />


4:         <RowDefinition />


5:     </Grid.RowDefinitions>


6:     <!--使用两个圆形叠加出圆环,但要受到其所有容器的限制-->


7:     <Canvas Grid.Row="0">


8:         <Ellipse Fill="Red" Canvas.Left="10" Canvas.Top="10"


9:                  Width="100" Height="100" />


10:         <Ellipse Fill="White" Canvas.Left="35" Canvas.Top="35"


11:                  Width="50" Height="50" />


12:     </Canvas>


13:     <!--直接使用Path构建圆环-->


14:     <Canvas Grid.Row="1">


15:         <Path Fill="Red">


16:             <Path.Data>


17:                 <GeometryGroup>


18:                     <!--Center为圆心的坐标,RadiusX、RadiusY分别为X、Y两轴的半径-->


19:                     <EllipseGeometry RadiusX="50" RadiusY="50"


20:                                      Center="60,60" />


21:                     <EllipseGeometry RadiusX="25" RadiusY="25"


22:                                      Center="60,60" />


23:                 </GeometryGroup>


24:             </Path.Data>


25:         </Path>


26:     </Canvas>


27: </Grid>




另外,由于第一种做法是一种“虚假”的圆环,所以,当给两个圆环所在的Canvas添加背景时,第一种做法的圆环不能出现“镂空”的效果,例如为两个Canvas添加如下的背景图片:

1: <Canvas.Background>


2:     <ImageBrush ImageSource="Images/Logo.png" Stretch="Uniform" />


3: </Canvas.Background>


效果为:



此外Path还可以构建很多更复杂的图形,在这里就不一一列举了,请感兴趣的朋友自行尝试。

二、位图操作

WPF支持以下格式的位图:BMP、JPEG、PNG、TIFF、Windows Media Photo、GIF和ICO。在System.Windows.Media.Imaging命名空间定义了一系列处理图像文件的类型,其中最常使用的是Image类处理位图。

使用Image类型的Source属性加载图片,Source属性的类型是ImageSource类型。ImageSource有两个子类DrawingImage和BitmapSource,分别用来处理不依赖分辨率的图画对象和依赖分辨率的图画对象(位图)。其继承关系如下图所示:



1、使用BitmapImage加载图片

BitmapImage类型是Image类型Source属性默认的类型,它用来加载已存在的图片,这个图片可以是存放在网络上的,也可以是本地或项目资源中的图片,例如:

1: <StackPanel Orientation="Horizontal">


2:     <!--使用绝对URL定位网络上的图片-->


3:     <Image Source="http://images.cnblogs.com/logo.gif"


4:        Margin="10"/>


5:     <!--使用绝对URL定位本地计算机上的图片-->


6:     <Image Source="D:\Pictures\mct.gif"


7:        Margin="10"/>


8:     <!--使用相对URL定位到项目中的资源图片-->


9:     <Image Source="Images/Logo.png"


10:            Margin="10"/>


11: </StackPanel>




2、使用RenderTargetBitmap创建图片

使用RenderTargetBitmap可以自定义任意一个Visual类型的子类,将其作为图片的内容,创建一个ImageSource,供界面显示,例如创建一个红色的五角星:

XAML代码如下:

1: <Window x:Class="WPF_27.Window4"


2:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"


3:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"


4:     Title="Window4" Height="250" Width="250">


5:     <Canvas Background="Yellow" Width="200" Height="200">


6:         <Image x:Name="img" Stretch="None"/>


7:     </Canvas>


8: </Window>


在后台的代码中:

1: private void DrawImage()


2: {


3:     // 创建一个RenderTargetBitmap对象


4:     RenderTargetBitmap bmp = new RenderTargetBitmap(


5:         200, 200,       // 设置图片的大小(单位为像素)


6:         96, 96,         // 设置图片的水平及竖直分辨率


7:                         //(注间此处应与系统定义的DPI相同,否则会出现图形异常)


8:         PixelFormats.Pbgra32);  // 图片的格式


9: 


10:     // 定义五角星的五个顶点


11:     Point p1 = new Point(


12:         100 + 100 * Math.Sin(0),


13:         100 - 100 * Math.Cos(0));


14:     Point p2 = new Point(


15:         100 + 100 * Math.Sin(2 * Math.PI / 5),


16:         100 - 100 * Math.Cos(2 * Math.PI / 5));


17:     Point p3 = new Point(


18:         100 + 100 * Math.Sin(2 * Math.PI * 2 / 5),


19:         100 - 100 * Math.Cos(2 * Math.PI * 2 / 5));


20:     Point p4 = new Point(


21:         100 + 100 * Math.Sin(2 * Math.PI * 3 / 5),


22:         100 - 100 * Math.Cos(2 * Math.PI * 3 / 5));


23:     Point p5 = new Point(


24:         100 + 100 * Math.Sin(2 * Math.PI * 4 / 5),


25:         100 - 100 * Math.Cos(2 * Math.PI * 4 / 5));


26: 


27:


28:     // 定义红色的五角星


29:     Polygon p = new Polygon();


30:     p.Fill = new SolidColorBrush(Colors.Red);


31:     p.FillRule = FillRule.Nonzero;


32: 


33:     p.Points.Add(p1);


34:     p.Points.Add(p3);


35:     p.Points.Add(p5);


36:     p.Points.Add(p2);


37:     p.Points.Add(p4);


38: 


39:     // 定义圆


40:     Ellipse e = new Ellipse();


41:     e.Stroke = new SolidColorBrush(Colors.Red);


42:     e.Width = 200;


43:     e.Height = 200;


44: 


45:     Canvas.SetLeft(p,0);


46:     Canvas.SetTop(p,0);


47:     Canvas.SetLeft(e,0);


48:     Canvas.SetTop(e,0);


49: 


50:     // 定义承载两个图形的Canvas对象


51:     Canvas c = new Canvas();


52:     c.Background = new SolidColorBrush(Colors.Yellow);


53:     c.Children.Add(e);


54:     c.Children.Add(p);


55: 


56:     // 处理其显示的大小及位置


57:     c.Measure(new Size(200, 200));


58:     c.Arrange(new Rect(0, 0, 200, 200));


59: 


60:     // 生成图片并显示


61:     bmp.Render(c);


62:     img.Source = bmp;


63: }


执行之后的效果如下图所示:



在此处要注意显示器的像素和分辨率的关系,有关两者间的关系,园子中有一篇文章写的比较清楚,大家可以参考:

/article/5062757.html

3、为图片添加水印

例如,对上节第二张图片加水印,可以使用如下代码:

1: private void ShowPicture()


2: {


3:     BitmapImage source = new BitmapImage();


4:     source.BeginInit();


5:     // 获取网络上的一张图片


6:     source.UriSource =


7:         new Uri(


8:             "http://images.cnblogs.com/cnblogs_com/DragonInSea/" +


9:             "WindowsLiveWriter/WPFandSilverlight1_B8D5/26-2_6.png");


10: 


11:     // 当图片下载完成后,对源图片加水印


12:     source.DownloadCompleted += delegate


13:     {


14:         // 源图片


15:         Image backImage = new Image();


16:         backImage.Source = source;


17: 


18:         // 水印


19:         TextBlock water = new TextBlock();


20:         water.Text = "Dragon In Sea";


21:         water.FontSize = 24;


22:         water.FontFamily = new FontFamily("Consolas");


23:         water.Background = new SolidColorBrush(Color.FromArgb(128, 0, 0, 0));


24:         water.Foreground = Brushes.Gold;


25: 


26:         Canvas.SetLeft(backImage,0);


27:    Canvas.SetTop(backImage,0);


28: 


29:         Canvas.SetLeft(water, source.Width - 200);


30:         Canvas.SetTop(water,source.Height-50);


31: 


32:         // 将源图片与水印添加到同一个Canvas容器中


33:         Canvas canvas = new Canvas();


34:         canvas.Children.Add(backImage);


35:         canvas.Children.Add(water);


36: 


37:         canvas.Measure(new Size(source.Width, source.Height));


38:         canvas.Arrange(new Rect(0, 0, source.Width, source.Height));


39: 


40:         // 显示全成后的图片


41:         RenderTargetBitmap newImage = new RenderTargetBitmap(


42:             (int)source.Width, (int)source.Height,


43:             source.DpiX, source.DpiY,


44:             PixelFormats.Pbgra32);


45:         newImage.Render(canvas);


46: 


47:         img.Source = newImage;


48:     };


49: 


50:     source.EndInit();


51: }


执行的结果如下图所示:



用此方法,不更改源图片,显示出来的是合成后的图片。

下一篇,我们将继续讨论对于图片的操作。

本系列博客索引页
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐