在开发Silverlight应用程序时,遇到了一个需求,需要实现一个具有可移动边缘的图像裁剪控件。因此,参考了一篇关于扩展画布控件以裁剪图像的文章,并被其简洁性和实用性所吸引。基于此,决定编写自己的版本。
以下是实现的图像裁剪控件的主要特点:
在设置宽高比为4:3的情况下,如图片所示。
在之前提到的那篇文章中,裁剪区域的尺寸是通过一个名为Rectangle的UI元素来保持的。因为需要指示裁剪区域可以修改的地方的指针,所以决定将裁剪区域的尺寸存储在一个名为ClipRect的自定义对象中(它几乎与Rect相同,但是Right和Bottom属性不是只读的,并且包含一些额外的特性),并添加了四个图像来可视化裁剪指针。最初,使用第五个图像来可视化裁剪区域移动功能,但后来决定用Cursor.Hand指针来解决这个问题。为了强调被选中用于裁剪的图像部分,在控件中添加了两个可裁剪图像的实例,一个作为背景的反相掩码,另一个作为前景。然后,将前景图像的Clip尺寸绑定起来,以模仿裁剪行为。该控件还能够保持预定义的宽高比。在这种情况下,裁剪区域宽度的水平变化是根据光标的垂直移动来计算的。
简单地将CropControl控件放置到XAML中:
<c:CropControl x:Name="cropControl" Width="500" Height="390" MinimalCropSize="60.0" AspectRatio="None" />
设置源属性(也可以绑定):
C# BitmapImage bmp = new BitmapImage();
FileStream fs = imgOpenFileDialog.File.OpenRead();
bmp.SetSource(fs);
cropControl.Source = LoadFromBitmapImage(bmp);
裁剪图像:
C# imgCropped.Source = cropControl.CropImage();
发现了一篇关于“使值转换器在标记中更易于访问”的文章,这对非常有用。
在xaml代码中的数据绑定方面遇到了很多困难。最后,意识到缺少的功能叫做Multibinding,它存在于WPF中,但不存在于Silverlight中。
还遇到了一个问题,那就是图像的ActualWidth/Height只有在ImageOpened事件之后才会计算,而需要这个值来定位裁剪指针,所以决定从代码后台设置图像尺寸,而不是让框架来计算它。