发布基于silverlight4的HaoRna.WebCam摄像头应用源码
2010-08-31 11:45
537 查看
在去年年底,为了学习Silverlight4.0的新特性,我萌生了开发一个基于其新特性的项目。当然在这个项目中使用了包括鼠标右键菜单
(Popup),打印功能
(PrintDocument),导航功能
,摄像头
,图片上传等。当然目前这个产品已在我们的官方产品Discuz!NT3.1中使用,今天开源的仅是本应用的源码。
下面链接中是产品的运行截图:
http://www.cnblogs.com/daizhj/archive/2010/02/26/1674389.html
好了,接下来介绍一下产品的源码分布:
其中:
ChildWindows/
CWMessageBox.xaml:显示窗口信息控件,用于显示系统提示的各种消息
CWViewUploadedImage.xaml:显示用于上传头像或文件之后的显示结果(包括大中小三种尺寸)
Controls/
FocusRectangle.xaml: 焦点选择区域控件及相应用户拖动效果
ImageButton.xaml:图片控件
InkMenu.xaml:ink涂鸦工具栏控件
Cursors/
CustomCursors.xaml: 定制鼠标图标控件, 用于当鼠标进入FocusRectangle区域后显示定制的十字箭头
Shader/
三个silverlight滤镜
Images/
项目中使用的图标
Utils/
相关工具类
Constants.cs,Converter.cs,UserFile.cs,FileCollection.cs, FileUploader.cs 图片上传代码
Utils.cs 常用函数封装工具类
AdvanceMode.xaml:高级模式的编辑窗口
ImageBrowser.xaml:图片浏览和编辑上传窗口
NavPage.xaml:导航窗口
WebCam.xaml:摄像头功能和上传窗口
好的,产品布局就介绍到这里了,下面是对于之前朋友感兴趣的一些功能的代码介绍。
首先就是焦点选择框(矩形)的实现原理和相应代码,位于FocusRectangle.xaml和FocusRectangle.xaml.cs 原理就
是首先绘制8个小矩形,作为用户进行鼠标操作的入口(均定制了鼠标点击操作代码),然后将这8个小矩形分布在一个大矩形的四角和两两节点间的中心位置,当
然也加入鼠标的拖动和“上下左右扩展”代码,明确了实现方式之后,就看一下源码来加深一下理解了:
XAML:
<
Canvas x:Name
=
"
LayoutRoot
"
>
<
Canvas Name
=
"
ViewportHost
"
Height
=
"
270
"
Width
=
"
270
"
Background
=
"
Gray
"
>
<
ScrollViewer Canvas.ZIndex
=
"
0
"
Name
=
"
imageScroll
"
BorderThickness
=
"
0
"
Background
=
"
Transparent
"
Width
=
"
270
"
Height
=
"
270
"
VerticalScrollBarVisibility
=
"
Hidden
"
HorizontalScrollBarVisibility
=
"
Hidden
"
>
<
Rectangle Name
=
"
Viewport
"
Width
=
"
270
"
Height
=
"
270
"
Canvas.ZIndex
=
"
100
"
>
<
Rectangle.Fill
>
<
ImageBrush
>
<
ImageBrush.ImageSource
>
<
BitmapImage x:Name
=
"
selectedImage
"
UriSource
=
"
../Images/main.jpg
"
/>
</
ImageBrush.ImageSource
>
</
ImageBrush
>
</
Rectangle.Fill
>
</
Rectangle
>
</
ScrollViewer
>
<!--<
TextBlock x:Name
=
"
msgBox
"
Width
=
"
269
"
Text
=
"
000
"
Foreground
=
"
Red
"
Height
=
"
100
"
Canvas.ZIndex
=
"
10000
"
/>-->
<
local:CustomCursors x:Name
=
"
customCursors
"
Visibility
=
"
Collapsed
"
></
local:CustomCursors
>
<
Rectangle Name
=
"
FocusRect
"
Canvas.Left
=
"
5
"
Canvas.Top
=
"
5
"
Fill
=
"
Transparent
"
Opacity
=
"
1
"
Stroke
=
"
White
"
StrokeThickness
=
"
1
"
/>
</
Canvas
>
</
Canvas
>
XAML文件中包括一个ScrollViewer用于实现图片的缩放效果,CustomCursors用于鼠标移入焦点区域时显示焦点图标而不是鼠标沙漏。
下面则是FocusRectangle.xaml.cs代码,包括8个小矩形的枚举标识:
#region
方形中八个点的相对位置
///
<summary>
///
方形中八个点的相对位置
///
</summary>
enum
HitDownSquare
{
HDS_NONE
=
0
,
///
<summary>
///
顶
///
</summary>
HDS_TOP
=
1
,
///
<summary>
///
右
///
</summary>
HDS_RIGHT
=
2
,
///
<summary>
///
底
///
</summary>
HDS_BOTTOM
=
3
,
///
<summary>
///
左
///
</summary>
HDS_LEFT
=
4
,
///
<summary>
///
左上
///
</summary>
HDS_TOPLEFT
=
5
,
///
<summary>
///
右上
///
</summary>
HDS_TOPRIGHT
=
6
,
///
<summary>
///
左下
///
</summary>
HDS_BOTTOMLEFT
=
7
,
///
<summary>
///
右下
///
</summary>
HDS_BOTTOMRIGHT
=
8
}
#endregion
主要的控件类实体,实现各种相关鼠标操作事件和图形绘制事件代码(详见注释):
public
partial
class
FocusRectangle : UserControl
{
#region
属性设置
///
<summary>
///
8个允许调整控件大小的小正方形
///
</summary>
Rectangle[] SmallRect
=
new
Rectangle[
8
];
///
<summary>
///
8个小正方形的大小
///
</summary>
Size Square
=
new
Size(
6
,
6
);
///
<summary>
///
上一次鼠标点击的位置
///
</summary>
Point prevLeftClick;
///
<summary>
///
8个小正方形的填充色
///
</summary>
Color color
=
Colors.White;
///
<summary>
///
标识鼠标左键已被按下并且已开始移动
///
</summary>
bool
trackingMouseMove
=
false
;
///
<summary>
///
当前鼠标点击位置信息
///
</summary>
HitDownSquare CurrHitPlace
=
new
HitDownSquare();
#endregion
public
FocusRectangle()
{
InitializeComponent();
this
.Loaded
+=
new
RoutedEventHandler(FocusRectangle_Loaded);
}
#region
初始化相应元素信息
///
<summary>
///
初始化相应元素信息
///
</summary>
///
<param name="sender"></param>
///
<param name="e"></param>
void
FocusRectangle_Loaded(
object
sender, RoutedEventArgs e)
{
Viewport.MinHeight
=
Viewport.MinWidth
=
16
;
Viewport.SetValue(Canvas.TopProperty, (
double
)ViewportHost.GetValue(Canvas.TopProperty)
+
(ViewportHost.Height
-
Viewport.Height)
/
2
);
Viewport.SetValue(Canvas.LeftProperty, (
double
)ViewportHost.GetValue(Canvas.LeftProperty)
+
(ViewportHost.Width
-
Viewport.Width)
/
2
);
//
初始设置FocusRect
FocusRect.Width
=
FocusRect.Height
=
100
;
FocusRect.MaxWidth
=
ViewportHost.Width;
FocusRect.MaxHeight
=
ViewportHost.Height;
FocusRect.MinHeight
=
FocusRect.MinWidth
=
8
;
FocusRect.SetValue(Canvas.TopProperty, (
double
)ViewportHost.GetValue(Canvas.TopProperty)
+
(ViewportHost.Height
-
FocusRect.Height)
/
2
);
FocusRect.SetValue(Canvas.LeftProperty, (
double
)ViewportHost.GetValue(Canvas.LeftProperty)
+
(ViewportHost.Width
-
FocusRect.Width)
/
2
);
#region
8个小正方形位置
//
左上
SmallRect[
0
]
=
new
Rectangle() { Name
=
"
SmallRect0
"
, Width
=
Square.Width, Height
=
Square.Height, Fill
=
new
SolidColorBrush(color) };
//
上中间
SmallRect[
4
]
=
new
Rectangle() { Name
=
"
SmallRect4
"
, Width
=
Square.Width, Height
=
Square.Height, Fill
=
new
SolidColorBrush(color) };
//
右上
SmallRect[
1
]
=
new
Rectangle() { Name
=
"
SmallRect1
"
, Width
=
Square.Width, Height
=
Square.Height, Fill
=
new
SolidColorBrush(color) };
//
左下
SmallRect[
2
]
=
new
Rectangle() { Name
=
"
SmallRect2
"
, Width
=
Square.Width, Height
=
Square.Height, Fill
=
new
SolidColorBrush(color) };
//
下中间
SmallRect[
5
]
=
new
Rectangle() { Name
=
"
SmallRect5
"
, Width
=
Square.Width, Height
=
Square.Height, Fill
=
new
SolidColorBrush(color) };
//
右下
SmallRect[
3
]
=
new
Rectangle() { Name
=
"
SmallRect3
"
, Width
=
Square.Width, Height
=
Square.Height, Fill
=
new
SolidColorBrush(color) };
//
左中间
SmallRect[
6
]
=
new
Rectangle() { Name
=
"
SmallRect6
"
, Width
=
Square.Width, Height
=
Square.Height, Fill
=
new
SolidColorBrush(color) };
//
右中间
SmallRect[
7
]
=
new
Rectangle() { Name
=
"
SmallRect7
"
, Width
=
Square.Width, Height
=
Square.Height, Fill
=
new
SolidColorBrush(color) };
SetRectangles();
#endregion
#region
事件绑定
foreach
(Rectangle smallRectangle
in
SmallRect)
{
smallRectangle.Fill
=
new
SolidColorBrush(color);
smallRectangle.MouseMove
+=
new
MouseEventHandler(smallRectangle_MouseMove);
smallRectangle.MouseLeftButtonUp
+=
new
MouseButtonEventHandler(smallRectangle_MouseLeftButtonUp);
smallRectangle.MouseLeftButtonDown
+=
new
MouseButtonEventHandler(smallRectangle_MouseLeftButtonDown);
smallRectangle.MouseEnter
+=
new
MouseEventHandler(smallRectangle_MouseEnter);
LayoutRoot.Children.Add(smallRectangle);
}
FocusRect.MouseMove
+=
new
MouseEventHandler(FocusRect_MouseMove);
FocusRect.MouseLeftButtonDown
+=
new
MouseButtonEventHandler(FocusRect_MouseLeftButtonDown);
FocusRect.MouseLeftButtonUp
+=
new
MouseButtonEventHandler(FocusRect_MouseLeftButtonUp);
FocusRect.MouseEnter
+=
new
MouseEventHandler(FocusRect_MouseEnter);
FocusRect.MouseLeave
+=
new
MouseEventHandler(FocusRect_MouseLeave);
#endregion
}
#endregion
#region
FocusRect鼠标事件
void
FocusRect_MouseLeave(
object
sender, MouseEventArgs e)
{
customCursors.Visibility
=
System.Windows.Visibility.Collapsed;
}
void
FocusRect_MouseEnter(
object
sender, MouseEventArgs e)
{
FrameworkElement element
=
sender
as
FrameworkElement;
element.Cursor
=
Cursors.None;
customCursors.Visibility
=
System.Windows.Visibility.Visible;
customCursors.SetPostion(e.GetPosition(LayoutRoot));
}
void
FocusRect_MouseLeftButtonUp(
object
sender, MouseButtonEventArgs e)
{
FrameworkElement element
=
sender
as
FrameworkElement;
trackingMouseMove
=
false
;
element.ReleaseMouseCapture();
prevLeftClick.X
=
prevLeftClick.Y
=
0
;
element.Cursor
=
Cursors.None;
if
(Viewport.Width
<
FocusRect.Width)
FocusRect.Width
=
Viewport.Width;
if
(Viewport.Height
<
FocusRect.Height)
FocusRect.Height
=
Viewport.Height;
AssureFocusRectMoveInZone(element.Name);
SetRectangles();
}
void
FocusRect_MouseLeftButtonDown(
object
sender, MouseButtonEventArgs e)
{
FrameworkElement element
=
sender
as
FrameworkElement;
prevLeftClick
=
e.GetPosition(element);
trackingMouseMove
=
true
;
if
(
null
!=
element)
{
element.CaptureMouse();
element.Cursor
=
Cursors.None;
}
}
///
<summary>
///
计算并设置Scroll的偏移量
///
</summary>
///
<param name="offSetX">
鼠标X轴移动的偏移量
</param>
///
<param name="offSetY">
鼠标Y轴移动的偏移量
</param>
void
ComputeScrollOffSet(
double
offSetX,
double
offSetY)
{
double
FocusRectTop
=
(
double
)FocusRect.GetValue(Canvas.TopProperty);
double
FocusRectLeft
=
(
double
)FocusRect.GetValue(Canvas.LeftProperty);
double
ViewportHostTop
=
(
double
)ViewportHost.GetValue(Canvas.TopProperty);
double
ViewportHostLeft
=
(
double
)ViewportHost.GetValue(Canvas.LeftProperty);
//
msgBox.Text = "FocusRect.Height" + FocusRect.Height + " ViewportHost.Height" + ViewportHost.Height;
if
(offSetY
>
0
&&
(FocusRect.Height
+
8
)
<
ViewportHost.Height
&&
(ViewportHostTop
+
ViewportHost.Height)
>
(FocusRectTop
+
FocusRect.Height))
//
鼠标向下且未出ViewportHost区域时
imageScroll.ScrollToVerticalOffset(imageScroll.VerticalOffset
+
(offSetY
/
2
)
*
(Viewport.Height
/
(ViewportHost.Height
-
FocusRectTop
-
FocusRect.Height)));
if
(offSetY
<
0
&&
(FocusRect.Height
+
8
)
<
ViewportHost.Height
&&
ViewportHostTop
<
FocusRectTop)
//
鼠标向上且未出ViewportHost区域时
imageScroll.ScrollToVerticalOffset(imageScroll.VerticalOffset
+
(offSetY
/
2
)
*
((Viewport.Height
/
FocusRectTop)));
if
(offSetX
>
0
&&
(FocusRect.Width
+
8
)
<
ViewportHost.Width
&&
(ViewportHostLeft
+
ViewportHost.Width)
>
(FocusRectLeft
+
FocusRect.Width))
//
鼠标向右且未出ViewportHost区域时
imageScroll.ScrollToHorizontalOffset(imageScroll.HorizontalOffset
+
(offSetX
/
2
)
*
(Viewport.Width
/
(ViewportHost.Width
-
FocusRectLeft
-
FocusRect.Width)));
if
(offSetX
<
0
&&
(FocusRect.Width
+
8
)
<
ViewportHost.Width
&&
ViewportHostLeft
<
FocusRectLeft)
//
鼠标向左且未出ViewportHost区域时
imageScroll.ScrollToHorizontalOffset(imageScroll.HorizontalOffset
+
(offSetX
/
2
)
*
((Viewport.Width
/
FocusRectLeft)));
//
msgBox.Text = imageScroll.HorizontalOffset.ToString();
}
///
<summary>
///
FocusRect鼠标移动事件
///
</summary>
///
<param name="sender"></param>
///
<param name="e"></param>
void
FocusRect_MouseMove(
object
sender, MouseEventArgs e)
{
FrameworkElement element
=
sender
as
FrameworkElement;
if
(element
!=
null
)
element.Cursor
=
Cursors.None;
if
(trackingMouseMove)
{
double
offSetX
=
e.GetPosition(element).X
-
prevLeftClick.X;
double
offSetY
=
e.GetPosition(element).Y
-
prevLeftClick.Y;
if
(((
double
)element.GetValue(Canvas.TopProperty)
+
offSetY)
>=
4
&&
(((
double
)FocusRect.GetValue(Canvas.TopProperty)
+
FocusRect.Height)
+
offSetY
+
3
)
<=
ViewportHost.Height)
element.SetValue(Canvas.TopProperty, (
double
)element.GetValue(Canvas.TopProperty)
+
offSetY);
if
(((
double
)element.GetValue(Canvas.LeftProperty)
+
offSetX)
>=
4
&&
(((
double
)FocusRect.GetValue(Canvas.LeftProperty)
+
FocusRect.Width)
+
offSetX
+
3
)
<=
ViewportHost.Width)
element.SetValue(Canvas.LeftProperty, (
double
)element.GetValue(Canvas.LeftProperty)
+
offSetX);
ComputeScrollOffSet(offSetX, offSetY);
SetRectangles();
}
customCursors.SetPostion(e.GetPosition(LayoutRoot));
}
#endregion
#region
确保FocusRect在Viewport中进行移动和缩放
///
<summary>
///
确保FocusRect在Viewport中进行缩放
///
</summary>
public
void
AssureFocusRectZoomInZone(
double
zoom,
double
mininum)
{
double
ViewPortTop
=
(
double
)Viewport.GetValue(Canvas.TopProperty);
double
ViewPortLeft
=
(
double
)Viewport.GetValue(Canvas.LeftProperty);
double
FocusRectTop
=
(
double
)FocusRect.GetValue(Canvas.TopProperty);
double
FocusRectLeft
=
(
double
)FocusRect.GetValue(Canvas.LeftProperty);
if
(zoom
==
mininum)
{
FocusRect.SetValue(Canvas.LeftProperty, ViewPortLeft);
FocusRect.Width
=
Viewport.Width;
}
else
{
//
确保顶部不越界
if
(ViewPortTop
>
FocusRectTop)
FocusRect.SetValue(Canvas.TopProperty, ViewPortTop);
//
确保左侧不越界
if
(ViewPortLeft
>
FocusRectLeft)
FocusRect.SetValue(Canvas.LeftProperty, ViewPortLeft);
//
判断x是否右侧越界
if
((Viewport.Width
+
ViewPortLeft)
<
(FocusRect.Width
+
FocusRectLeft))
{
//
如果已越界,但左侧未越界
if
(Viewport.Width
>
FocusRect.Width)
FocusRect.SetValue(Canvas.LeftProperty, ViewPortLeft
+
Viewport.Width
-
FocusRect.Width);
else
FocusRect.Width
=
Viewport.Width;
}
//
判断是否底部越界
if
((Viewport.Height
+
ViewPortTop)
<
(FocusRect.Height
+
FocusRectTop))
{
//
如果已越界,但顶部未越界
if
(Viewport.Height
>
FocusRect.Height)
FocusRect.SetValue(Canvas.TopProperty, ViewPortTop
+
Viewport.Height
-
FocusRect.Height);
else
FocusRect.Height
=
Viewport.Height;
}
}
SetRectangles();
}
///
<summary>
///
FocusRect是否在Viewport中,如不在,则确保其不超出Viewport区域
///
</summary>
///
<returns></returns>
bool
AssureFocusRectMoveInZone(
string
elementName)
{
bool
result
=
true
;
//
try
//
{
double
ViewPortTop
=
(
double
)Viewport.GetValue(Canvas.TopProperty);
double
ViewPortLeft
=
(
double
)Viewport.GetValue(Canvas.LeftProperty);
double
FocusRectTop
=
(
double
)FocusRect.GetValue(Canvas.TopProperty);
double
FocusRectLeft
=
(
double
)FocusRect.GetValue(Canvas.LeftProperty);
if
(Viewport.Height
>
ViewportHost.Height)
//
已使用放大功能,向上拖动
{
if
(
0
>
FocusRectTop)
{
FocusRect.SetValue(Canvas.TopProperty, (
double
)ViewportHost.GetValue(Canvas.TopProperty)
+
4
);
result
=
false
;
}
}
else
{
if
(ViewPortTop
>
FocusRectTop)
{
FocusRect.SetValue(Canvas.TopProperty, ViewPortTop);
result
=
false
;
}
}
if
(Viewport.Width
>=
ViewportHost.Width)
//
已使用放大功能,向左拖动
{
if
(
0
>
FocusRectLeft)
{
FocusRect.SetValue(Canvas.LeftProperty, (
double
)ViewportHost.GetValue(Canvas.LeftProperty)
+
4
);
result
=
false
;
}
}
else
{
if
(ViewPortLeft
>
FocusRectLeft)
{
FocusRect.SetValue(Canvas.LeftProperty, ViewPortLeft);
result
=
false
;
}
}
if
(Viewport.Width
>=
ViewportHost.Width)
//
已使用放大功能,向右拖动
{
if
((ViewportHost.Width)
<
(FocusRect.Width
+
FocusRectLeft))
{
if
(elementName
==
"
FocusRect
"
)
FocusRect.SetValue(Canvas.LeftProperty, ViewportHost.Width
-
FocusRect.Width
-
4
);
else
{
FocusRect.Width
=
ViewportHost.Width
-
FocusRectLeft
-
4
;
}
result
=
false
;
}
}
else
{
if
((Viewport.Width
+
ViewPortLeft)
<
(FocusRect.Width
+
FocusRectLeft))
{
if
(elementName
==
"
FocusRect
"
)
FocusRect.SetValue(Canvas.LeftProperty, ViewPortLeft
+
Viewport.Width
-
FocusRect.Width);
else
FocusRect.Width
=
ViewPortLeft
+
Viewport.Width
-
FocusRectLeft;
result
=
false
;
}
}
if
(Viewport.Height
>
ViewportHost.Height)
//
已使用放大功能,向下拖动
{
if
((ViewportHost.Height)
<
(FocusRect.Height
+
FocusRectTop))
{
if
(elementName
==
"
FocusRect
"
)
FocusRect.SetValue(Canvas.TopProperty, ViewportHost.Height
-
FocusRect.Height
-
4
);
else
FocusRect.Height
=
ViewportHost.Height
-
FocusRectTop
-
4
;
result
=
false
;
}
}
else
{
if
((Viewport.Height
+
ViewPortTop)
<
(FocusRect.Height
+
FocusRectTop))
{
if
(elementName
==
"
FocusRect
"
)
FocusRect.SetValue(Canvas.TopProperty, ViewPortTop
+
Viewport.Height
-
FocusRect.Height);
else
FocusRect.Height
=
ViewPortTop
+
Viewport.Height
-
FocusRectTop;
result
=
false
;
}
}
//
}
//
catch
//
{
//
result = false;
//
}
return
result;
}
#endregion
#region
smallRectangle 鼠标事件
void
smallRectangle_MouseLeftButtonUp(
object
sender, MouseButtonEventArgs e)
{
FrameworkElement element
=
sender
as
FrameworkElement;
trackingMouseMove
=
false
;
element.ReleaseMouseCapture();
prevLeftClick.X
=
prevLeftClick.Y
=
0
;
element.Cursor
=
null
;
if
(Viewport.Width
<
FocusRect.Width)
FocusRect.Width
=
Viewport.Width;
if
(Viewport.Height
<
FocusRect.Height)
FocusRect.Height
=
Viewport.Height;
AssureFocusRectMoveInZone(element.Name);
SetRectangles();
}
///
<summary>
///
鼠标按下事件
///
</summary>
///
<param name="sender"></param>
///
<param name="e"></param>
void
smallRectangle_MouseLeftButtonDown(
object
sender, MouseButtonEventArgs e)
{
FrameworkElement element
=
sender
as
FrameworkElement;
prevLeftClick
=
e.GetPosition(element);
trackingMouseMove
=
true
;
if
(
null
!=
element)
{
element.CaptureMouse();
element.Cursor
=
Cursors.Hand;
}
}
///
<summary>
///
SmallRect[]鼠标移动事件
///
</summary>
///
<param name="sender"></param>
///
<param name="e"></param>
void
smallRectangle_MouseMove(
object
sender, MouseEventArgs e)
{
if
(trackingMouseMove)
{
FrameworkElement element
=
sender
as
FrameworkElement;
double
offSetY
=
e.GetPosition(element).Y
-
prevLeftClick.Y;
double
offSetX
=
e.GetPosition(element).X
-
prevLeftClick.X;
if
(AssureFocusRectMoveInZone(element.Name))
{
switch
(
this
.CurrHitPlace)
{
case
HitDownSquare.HDS_TOP:
if
((FocusRect.Height
-
offSetY)
>
4
)
{
FocusRect.Height
=
FocusRect.Height
-
offSetY;
if
(FocusRect.Height
>
4
)
FocusRect.SetValue(Canvas.TopProperty, (
double
)FocusRect.GetValue(Canvas.TopProperty)
+
offSetY);
}
break
;
case
HitDownSquare.HDS_TOPLEFT:
if
((FocusRect.Height
-
offSetY)
>
4
)
{
FocusRect.Height
=
FocusRect.Height
-
offSetY;
if
(FocusRect.Height
>
4
)
FocusRect.SetValue(Canvas.TopProperty, (
double
)FocusRect.GetValue(Canvas.TopProperty)
+
offSetY);
}
if
((FocusRect.Width
-
offSetX)
>
4
)
{
FocusRect.Width
=
FocusRect.Width
-
offSetX;
if
(FocusRect.Width
>
4
)
FocusRect.SetValue(Canvas.LeftProperty, (
double
)FocusRect.GetValue(Canvas.LeftProperty)
+
offSetX);
}
break
;
case
HitDownSquare.HDS_TOPRIGHT:
if
((FocusRect.Height
-
offSetY)
>
4
)
{
FocusRect.Height
=
FocusRect.Height
-
offSetY;
if
(FocusRect.Height
>
4
)
FocusRect.SetValue(Canvas.TopProperty, (
double
)FocusRect.GetValue(Canvas.TopProperty)
+
offSetY);
}
if
((FocusRect.Width
+
offSetX)
>
4
)
FocusRect.Width
=
FocusRect.Width
+
offSetX;
break
;
case
HitDownSquare.HDS_RIGHT:
if
((FocusRect.Width
+
offSetX)
>
4
)
FocusRect.Width
=
FocusRect.Width
+
offSetX;
break
;
case
HitDownSquare.HDS_BOTTOM:
if
((FocusRect.Height
+
offSetY)
>
4
)
FocusRect.Height
=
FocusRect.Height
+
offSetY;
break
;
case
HitDownSquare.HDS_BOTTOMLEFT:
if
((FocusRect.Height
+
offSetY)
>
4
)
FocusRect.Height
=
FocusRect.Height
+
offSetY;
if
((FocusRect.Width
-
offSetX)
>
4
)
{
FocusRect.Width
=
FocusRect.Width
-
offSetX;
if
(FocusRect.Width
>
4
)
FocusRect.SetValue(Canvas.LeftProperty, (
double
)FocusRect.GetValue(Canvas.LeftProperty)
+
offSetX);
}
break
;
case
HitDownSquare.HDS_BOTTOMRIGHT:
if
((FocusRect.Height
+
offSetY)
>
4
)
FocusRect.Height
=
FocusRect.Height
+
offSetY;
if
((FocusRect.Width
+
offSetX)
>
4
)
FocusRect.Width
=
FocusRect.Width
+
offSetX;
break
;
case
HitDownSquare.HDS_LEFT:
if
((FocusRect.Width
-
offSetX)
>
4
)
{
FocusRect.Width
=
FocusRect.Width
-
offSetX;
if
(FocusRect.Width
>
4
)
FocusRect.SetValue(Canvas.LeftProperty, (
double
)FocusRect.GetValue(Canvas.LeftProperty)
+
offSetX);
}
break
;
case
HitDownSquare.HDS_NONE:
FocusRect.SetValue(Canvas.LeftProperty, (
double
)FocusRect.GetValue(Canvas.LeftProperty)
+
offSetX);
FocusRect.SetValue(Canvas.TopProperty, (
double
)FocusRect.GetValue(Canvas.TopProperty)
+
offSetY);
break
;
}
}
SetRectangles();
}
}
#endregion
#region
设置8个小正方形位置
///
<summary>
///
设置8个小正方形位置
///
</summary>
public
void
SetRectangles()
{
//
msgBox.Text = "FocusRect height: " + FocusRect.Height + " Width:" + FocusRect.Width + " Top:" + FocusRect.GetValue(Canvas.TopProperty) + " Left:" + FocusRect.GetValue(Canvas.LeftProperty);
//
左上
SmallRect[
0
].SetValue(Canvas.LeftProperty, (
double
)FocusRect.GetValue(Canvas.LeftProperty)
-
Square.Width
/
2
);
SmallRect[
0
].SetValue(Canvas.TopProperty, (
double
)FocusRect.GetValue(Canvas.TopProperty)
-
Square.Height
/
2
);
//
上中间
SmallRect[
4
].SetValue(Canvas.LeftProperty, (
double
)FocusRect.GetValue(Canvas.LeftProperty)
+
(FocusRect.Width
-
Square.Width)
/
2
);
SmallRect[
4
].SetValue(Canvas.TopProperty, (
double
)FocusRect.GetValue(Canvas.TopProperty)
-
Square.Height
/
2
);
//
右上
SmallRect[
1
].SetValue(Canvas.LeftProperty, (
double
)FocusRect.GetValue(Canvas.LeftProperty)
+
FocusRect.Width
-
Square.Width
/
2
);
SmallRect[
1
].SetValue(Canvas.TopProperty, (
double
)FocusRect.GetValue(Canvas.TopProperty)
-
Square.Height
/
2
);
//
左下
SmallRect[
2
].SetValue(Canvas.LeftProperty, (
double
)FocusRect.GetValue(Canvas.LeftProperty)
-
Square.Width
/
2
);
SmallRect[
2
].SetValue(Canvas.TopProperty, (
double
)FocusRect.GetValue(Canvas.TopProperty)
+
FocusRect.Height
-
Square.Height
/
2
);
//
下中间
SmallRect[
5
].SetValue(Canvas.LeftProperty, (
double
)FocusRect.GetValue(Canvas.LeftProperty)
+
(FocusRect.Width
-
Square.Width)
/
2
);
SmallRect[
5
].SetValue(Canvas.TopProperty, (
double
)FocusRect.GetValue(Canvas.TopProperty)
+
FocusRect.Height
-
Square.Height
/
2
);
//
右下
SmallRect[
3
].SetValue(Canvas.LeftProperty, (
double
)FocusRect.GetValue(Canvas.LeftProperty)
+
FocusRect.Width
-
Square.Height
/
2
);
SmallRect[
3
].SetValue(Canvas.TopProperty, (
double
)FocusRect.GetValue(Canvas.TopProperty)
+
FocusRect.Height
-
Square.Height
/
2
);
//
左中间
SmallRect[
6
].SetValue(Canvas.LeftProperty, (
double
)FocusRect.GetValue(Canvas.LeftProperty)
-
Square.Width
/
2
);
SmallRect[
6
].SetValue(Canvas.TopProperty, (
double
)FocusRect.GetValue(Canvas.TopProperty)
+
(FocusRect.Height
-
Square.Height)
/
2
);
//
右中间
SmallRect[
7
].SetValue(Canvas.LeftProperty, (
double
)FocusRect.GetValue(Canvas.LeftProperty)
+
FocusRect.Width
-
Square.Width
/
2
);
SmallRect[
7
].SetValue(Canvas.TopProperty, (
double
)FocusRect.GetValue(Canvas.TopProperty)
+
(FocusRect.Height
-
Square.Height)
/
2
);
}
#endregion
#region
设置鼠标Cursor和相应位置CurrHitPlace
void
smallRectangle_MouseEnter(
object
sender, MouseEventArgs e)
{
FrameworkElement element
=
sender
as
FrameworkElement;
Hit_Test(element, e.GetPosition(
null
));
}
///
<summary>
///
设置鼠标Cursor和相应位置CurrHitPlace
///
</summary>
///
<param name="element"></param>
///
<param name="point"></param>
///
<returns></returns>
public
bool
Hit_Test(FrameworkElement element, Point point)
{
switch
(element.Name)
{
case
"
SmallRect0
"
:
{
element.Cursor
=
Cursors.Hand;
//
.SizeNWSE;
CurrHitPlace
=
HitDownSquare.HDS_TOPLEFT;
break
;
}
case
"
SmallRect3
"
:
{
element.Cursor
=
Cursors.Hand;
//
.SizeNWSE;
CurrHitPlace
=
HitDownSquare.HDS_BOTTOMRIGHT;
break
;
}
case
"
SmallRect1
"
:
{
element.Cursor
=
Cursors.Hand;
//
.SizeNESW;
CurrHitPlace
=
HitDownSquare.HDS_TOPRIGHT;
break
;
}
case
"
SmallRect2
"
:
{
element.Cursor
=
Cursors.Hand;
//
.SizeNESW;
CurrHitPlace
=
HitDownSquare.HDS_BOTTOMLEFT;
break
;
}
case
"
SmallRect4
"
:
{
element.Cursor
=
Cursors.SizeNS;
CurrHitPlace
=
HitDownSquare.HDS_TOP;
break
;
}
case
"
SmallRect5
"
:
{
element.Cursor
=
Cursors.SizeNS;
CurrHitPlace
=
HitDownSquare.HDS_BOTTOM;
break
;
}
case
"
SmallRect6
"
:
{
element.Cursor
=
Cursors.SizeWE;
CurrHitPlace
=
HitDownSquare.HDS_LEFT;
break
;
}
case
"
SmallRect7
"
:
{
element.Cursor
=
Cursors.SizeWE;
CurrHitPlace
=
HitDownSquare.HDS_RIGHT;
break
;
}
default
:
{
FocusRect.Cursor
=
Cursors.Arrow;
CurrHitPlace
=
HitDownSquare.HDS_NONE;
break
;
}
}
return
true
;
}
#endregion
#region
滑动条事件处理代码
///
<summary>
///
滑动条事件处理代码
///
</summary>
///
<param name="sender"></param>
///
<param name="e"></param>
public
void
ViewportSlider_ValueChanged(
object
sender, RoutedPropertyChangedEventArgs
<
double
>
e)
{
Slider ZoomInOut
=
sender
as
Slider;
if
(ZoomInOut.Value
>=
ZoomInOut.Minimum
&&
imageRatio
*
ZoomInOut.Value
>=
ZoomInOut.Minimum)
{
Viewport.Width
=
ZoomInOut.Value;
Viewport.Height
=
imageRatio
*
ZoomInOut.Value;
Viewport.SetValue(Canvas.TopProperty, (
double
)ViewportHost.GetValue(Canvas.TopProperty)
+
(ViewportHost.Width
-
Viewport.Height)
/
2
);
Viewport.SetValue(Canvas.LeftProperty, (
double
)ViewportHost.GetValue(Canvas.LeftProperty)
+
(ViewportHost.Width
-
Viewport.Width)
/
2
);
AssureFocusRectZoomInZone(ZoomInOut.Value, ZoomInOut.Minimum);
}
}
#endregion
#region
加载图片流信息并设置宽高比例
///
<summary>
///
图片的高宽比
///
</summary>
private
double
imageRatio
=
1
;
///
<summary>
///
加载图片文件信息
///
</summary>
///
<param name="fileStream"></param>
public
void
LoadImageStream(FileStream fileStream, Slider zoomInOut)
{
double
width
=
ViewportHost.Width, height
=
ViewportHost.Height;
//
hack:获取相应的图片高宽信息
BitmapImage bitmapImage
=
new
BitmapImage();
bitmapImage.SetSource(fileStream);
zoomInOut.Maximum
=
bitmapImage.PixelWidth;
#region
用获取的图片高宽初始化Viewport,FocusRect区域和以slider
if
(bitmapImage.PixelWidth
<
bitmapImage.PixelHeight)
//
当图片宽小于高时
{
if
(bitmapImage.PixelWidth
>
width)
//
当图片宽度超过可视区域的宽度时
{
height
=
((
double
)width
/
bitmapImage.PixelWidth)
*
bitmapImage.PixelHeight;
//
zoomInOut.Value = (double)width / bitmapImage.PixelWidth;
}
else
//
未超过时则使用图片的高宽初始化显示区域
{
width
=
bitmapImage.PixelWidth;
height
=
bitmapImage.PixelHeight;
}
}
else
//
当图片高小于宽时
{
if
(bitmapImage.PixelHeight
>
height)
//
当图片高度超过可视区域的高度时
{
width
=
((
double
)height
/
bitmapImage.PixelHeight)
*
bitmapImage.PixelWidth;
//
zoomInOut.Value = (double)height / bitmapImage.PixelHeight;
}
else
//
未超过时则使用图片的高宽初始化显示区域
{
width
=
bitmapImage.PixelWidth;
height
=
bitmapImage.PixelHeight;
}
}
Viewport.Width
=
zoomInOut.Value
=
width;
Viewport.Height
=
height;
Viewport.SetValue(Canvas.TopProperty, (
double
)ViewportHost.GetValue(Canvas.TopProperty)
+
(ViewportHost.Height
-
Viewport.Height)
/
2
);
Viewport.SetValue(Canvas.LeftProperty, (
double
)ViewportHost.GetValue(Canvas.LeftProperty)
+
(ViewportHost.Width
-
Viewport.Width)
/
2
);
FocusRect.Width
=
width
>=
100
?
100
: width;
FocusRect.Height
=
height
>=
100
?
100
: height;
FocusRect.SetValue(Canvas.TopProperty, (
double
)ViewportHost.GetValue(Canvas.TopProperty)
+
(ViewportHost.Height
-
FocusRect.Height)
/
2
);
FocusRect.SetValue(Canvas.LeftProperty, (
double
)ViewportHost.GetValue(Canvas.LeftProperty)
+
(ViewportHost.Width
-
FocusRect.Width)
/
2
);
zoomInOut.Minimum
=
16
;
zoomInOut.ValueChanged
+=
new
RoutedPropertyChangedEventHandler
<
double
>
(ViewportSlider_ValueChanged);
imageRatio
=
(
double
)bitmapImage.PixelHeight
/
bitmapImage.PixelWidth;
SetRectangles();
#endregion
selectedImage.SetSource(fileStream);
}
#endregion
}
下面是鼠标右键菜单代码(位于ChildWindows/CWViewUploadedImage.xaml),采取动态加载控件方式来加载菜单项并绑定相应事件(如打印):
///
<summary>
///
初始化右键菜单
///
</summary>
void
InitPopMenu()
{
Border border
=
new
Border()
{
BorderBrush
=
new
SolidColorBrush(Color.FromArgb(
255
,
167
,
171
,
176
)),
CornerRadius
=
new
CornerRadius(
2
),
BorderThickness
=
new
Thickness(
1
),
Background
=
new
SolidColorBrush(Colors.White),
Effect
=
new
DropShadowEffect() { BlurRadius
=
3
, Color
=
Color.FromArgb(
255
,
230
,
227
,
236
) }
};
StackPanel stackPanel
=
new
StackPanel() { Orientation
=
Orientation.Vertical };
stackPanel.Children.Insert(
0
, AddMenuItem(
"
打印头像
"
,
"
images/print.png
"
, PrintButton_Click));
stackPanel.Children.Insert(
1
, AddMenuItem(
"
保存到本地
"
,
"
images/save.png
"
, DownLoadAvatar_Click));
border.Child
=
stackPanel;
popMenu.Child
=
border;
}
下面就是菜单项的样式绑定代码:
///
<summary>
///
加载菜单项
///
</summary>
///
<param name="menuName">
菜单名称
</param>
///
<param name="imageUrl">
图片
</param>
///
<param name="eventHandler">
处理事件
</param>
///
<returns></returns>
Grid AddMenuItem(
string
menuName,
string
imageUrl, RoutedEventHandler eventHandler)
{
Grid grid
=
new
Grid();
//
{ Margin = new Thickness(1) };
grid.ColumnDefinitions.Add(
new
ColumnDefinition() { Width
=
new
GridLength(
25
) });
grid.ColumnDefinitions.Add(
new
ColumnDefinition() { Width
=
new
GridLength(
80
) });
grid.Children.Add(
new
Rectangle() { Fill
=
new
SolidColorBrush(Color.FromArgb(
255
,
233
,
238
,
238
)) });
grid.Children.Add(
new
Rectangle() { Fill
=
new
SolidColorBrush(Color.FromArgb(
255
,
226
,
228
,
231
)), HorizontalAlignment
=
HorizontalAlignment.Right, Width
=
1
});
Button roButton
=
new
Button()
{
Height
=
22
,
Margin
=
new
Thickness(
0
,
0
,
0
,
0
),
HorizontalAlignment
=
HorizontalAlignment.Stretch,
VerticalAlignment
=
VerticalAlignment.Top,
HorizontalContentAlignment
=
HorizontalAlignment.Left,
Style
=
Application.Current.Resources[
"
ContextMenuButton
"
]
as
Style
};
roButton.Click
+=
eventHandler;
Grid.SetColumnSpan(roButton,
2
);
StackPanel sp
=
new
StackPanel() { Orientation
=
Orientation.Horizontal };
Image roImage
=
new
Image() { HorizontalAlignment
=
HorizontalAlignment.Left, Width
=
16
, Height
=
16
, Margin
=
new
Thickness(
1
,
0
,
0
,
0
) };
roImage.Source
=
new
BitmapImage(
new
Uri(
"
/HaoRan.WebCam;component/
"
+
imageUrl, UriKind.RelativeOrAbsolute));
sp.Children.Add(roImage);
sp.Children.Add(
new
TextBlock() { HorizontalAlignment
=
HorizontalAlignment.Left, Margin
=
new
Thickness(
16
,
0
,
0
,
0
), Text
=
menuName });
roButton.Content
=
sp;
grid.Children.Add(roButton);
return
grid;
}
接下来就是用户选择下载或打印的实现代码(里面的JpegHelper类是一个将WriteableBitmap转为jpeg图片的辅助类):
///
<summary>
///
保存到本地
///
</summary>
private
void
DownLoadAvatar_Click(
object
sender, RoutedEventArgs e)
{
if
(saveFileDlg.ShowDialog().Value)
{
using
(Stream dstStream
=
saveFileDlg.OpenFile())
{
try
{
Image image;
double
Size
=
FocusWidth
>
FocusHeight
?
FocusWidth : FocusHeight;
//
hack:将高宽转为size,这样就可以将ui元素中的内容保存到本地了
if
(popMenu.Tag.ToString()
==
"
LargeImageScrollViewer
"
)
image
=
new
Image() { Width
=
Size, Height
=
Size, Source
=
LargeImage.Source };
else
if
(popMenu.Tag.ToString()
==
"
MediumImageScrollViewer
"
)
image
=
new
Image() { Width
=
Size
*
0.8
, Height
=
Size
*
0.8
, Source
=
MediumImage.Source };
else
image
=
new
Image() { Width
=
Size
*
0.6
, Height
=
Size
*
0.6
, Source
=
SmallImage.Source };
WriteableBitmap bmp
=
new
WriteableBitmap(image,
null
);
JpegHelper.EncodeJpeg(bmp, dstStream);
}
catch
(Exception ex)
{
Utils.ShowMessageBox(
"
Error saving snapshot
"
, ex.Message);
}
}
}
}
下面是打印代码:
#region
打印代码
///
<summary>
///
点击打印按钮事件
///
</summary>
///
<param name="sender"></param>
///
<param name="e"></param>
private
void
PrintButton_Click(
object
sender, RoutedEventArgs e)
{
PrintDocument doc
=
new
PrintDocument() {};
//
doc.StartPrint += new EventHandler<StartPrintEventArgs>(doc_StartPrint);
doc.EndPrint
+=
OnEndPrint;
doc.PrintPage
+=
new
EventHandler
<
PrintPageEventArgs
>
(doc_PrintPage);
doc.Print(
"
打印头像
"
);
}
///
<summary>
///
打印处理代码
///
</summary>
///
<param name="sender"></param>
///
<param name="e"></param>
void
doc_PrintPage(
object
sender, PrintPageEventArgs e)
{
PrintImage.Height
=
FocusHeight;
PrintImage.Width
=
FocusWidth;
if
(popMenu.Tag.ToString()
==
"
MediumImageScrollViewer
"
)
{
PrintImage.Height
*=
0.8
;
PrintImage.Width
*=
0.8
;
}
else
if
(popMenu.Tag.ToString()
==
"
SmallImageScrollViewer
"
)
{
PrintImage.Height
*=
0.6
;
PrintImage.Width
*=
0.6
;
}
ImageInf.Text
=
"
头像类型:
"
+
popMenu.Tag.ToString().Replace(
"
ScrollViewer
"
,
""
)
+
"
宽:
"
+
PrintImage.Width
+
"
px 高:
"
+
PrintImage.Height
+
"
px
"
;
AppInf.Text
=
"
Product Details: HaoRan.WebCam Beta2
"
;
PrintArea.Width
=
e.PrintableArea.Width;
PrintArea.Height
=
e.PrintableArea.Height;
e.PageVisual
=
PrintArea;
//
指定是否再次调用另一个页
e.HasMorePages
=
false
;
}
Action
<
Exception
>
completedCallback
=
(ex)
=>
{
if
(ex
!=
null
)
{
Utils.ShowMessageBox(
"
打印错误
"
, ex.Message);
}
};
///
<summary>
///
打印结束事件
///
</summary>
///
<param name="sender"></param>
///
<param name="e"></param>
void
OnEndPrint(
object
sender, EndPrintEventArgs e)
{
if
(completedCallback
!=
null
)
{
completedCallback(e.Error);
}
}
void
pd_PrintPage(
object
sender, PrintPageEventArgs e)
{
throw
new
NotImplementedException();
}
#endregion
下面是使用Silverlight4摄像头的代码(WebCam.xaml.cs):
///
<summary>
///
WebCam页
///
</summary>
public
partial
class
WebCam : Page
{
///
<summary>
///
初始化视频捕捉设备
///
</summary>
private
CaptureSource captureSource
=
new
CaptureSource()
{
VideoCaptureDevice
=
CaptureDeviceConfiguration.GetDefaultVideoCaptureDevice(),
AudioCaptureDevice
=
CaptureDeviceConfiguration.GetDefaultAudioCaptureDevice()
};
///
<summary>
///
保存文件对话框
///
</summary>
private
SaveFileDialog saveFileDlg
=
new
SaveFileDialog
{
DefaultExt
=
"
.jpg
"
,
Filter
=
"
JPEG Images (*jpeg *.jpg)|*.jpeg;*.jpg
"
,
};
public
WebCam()
{
InitializeComponent();
this
.Loaded
+=
new
RoutedEventHandler(WebCam_Loaded);
}
void
WebCam_Loaded(
object
sender, RoutedEventArgs e)
{
BtnUploadImage.IsEnabled
=
BtnAdvanceMode.IsEnabled
=
false
;
BtnCapture.IsEnabled
=
goBack.IsEnabled
=
CaptureDeviceConfiguration.GetDefaultVideoCaptureDevice()
!=
null
;
}
protected
override
void
OnNavigatedTo(NavigationEventArgs e)
{}
///
<summary>
///
捕捉图像信息
///
</summary>
///
<param name="sender"></param>
///
<param name="e"></param>
private
void
BtnCapture_Click(
object
sender, RoutedEventArgs e)
{
try
{
//
开始捕捉
if
(captureSource.State
!=
CaptureState.Started)
{
captureSource.Stop();
//
创建 video brush 并填充到 rectangle
VideoBrush vidBrush
=
new
VideoBrush();
vidBrush.Stretch
=
Stretch.UniformToFill;
vidBrush.SetSource(captureSource);
focusRectangle.Viewport.Fill
=
vidBrush;
//
询问是否接入
if
(CaptureDeviceConfiguration.AllowedDeviceAccess
||
CaptureDeviceConfiguration.RequestDeviceAccess())
{
focusRectangle.Viewport.MaxHeight
=
focusRectangle.Viewport.MaxWidth
=
ZoomInOut.Maximum
=
400
;
ZoomInOut.Value
=
270
;
ZoomInOut.Minimum
=
16
;
ZoomInOut.ValueChanged
+=
new
RoutedPropertyChangedEventHandler
<
double
>
(focusRectangle.ViewportSlider_ValueChanged);
captureSource.Start();
BtnCapture.Text
=
"
打开摄像头
"
;
BtnUploadImage.IsEnabled
=
BtnAdvanceMode.IsEnabled
=
true
;
}
}
else
{
captureSource.Stop();
BtnCapture.Text
=
"
关闭摄像头
"
;
BtnUploadImage.IsEnabled
=
BtnAdvanceMode.IsEnabled
=
false
;
}
}
catch
(Exception ex)
{
Utils.ShowMessageBox(
"
Error using webcam
"
, ex.Message);
}
}
///
<summary>
///
上传头像
///
</summary>
///
<param name="sender"></param>
///
<param name="e"></param>
private
void
BtnUploadImage_Click(
object
sender, RoutedEventArgs e)
{
captureSource.Stop();
Utils.UploadUserFile(Utils.GetUserId()
+
"
.jpg
"
, focusRectangle.imageScroll, focusRectangle.FocusRect,
//
定制UserFile的PropertyChanged 属性,如BytesUploaded,Percentage,IsDeleted
new
System.ComponentModel.PropertyChangedEventHandler(FileRowControl_PropertyChanged));
}
///
<summary>
///
上传文件进度属性事件
///
</summary>
///
<param name="sender"></param>
///
<param name="e"></param>
void
FileRowControl_PropertyChanged(
object
sender, System.ComponentModel.PropertyChangedEventArgs e)
{
UserFile userFile
=
sender
as
UserFile;
if
(e.PropertyName
==
"
Percentage
"
)
{
Percentage.Value
=
userFile.Percentage;
Percentage.Visibility
=
Percentage.Value
==
100
?
Visibility.Collapsed : Visibility.Visible;
}
//
当前文件上传完毕
if
(userFile.State
==
Constants.FileStates.Finished)
{
CWViewUploadedImage cw
=
new
CWViewUploadedImage();
cw.Closed
+=
(o, eventArgs)
=>
{
if
(cw.DialogResult
==
true
)
//
确定并就隐藏当前sl应用窗口
NavPage.javaScriptableObject.OnCloseAvatar(
null
);
//
调用js端注册事件
//
Utils.ShowMessageBox("op: 确定并就隐藏当前sl应用窗口");
};
cw.LargeImageWidth.Text
=
focusRectangle.FocusRect.Width.ToString();
cw.LargeImageHeight.Text
=
focusRectangle.FocusRect.Height.ToString().ToString();
cw.Show();
captureSource.Start();
}
}
///
<summary>
///
返回上一页
///
</summary>
///
<param name="sender"></param>
///
<param name="e"></param>
private
void
goBack_Click(
object
sender, RoutedEventArgs e)
{
this
.NavigationService.GoBack();
}
#region
高级模式事件代码
///
<summary>
///
高级模式事件代码
///
</summary>
///
<param name="sender"></param>
///
<param name="e"></param>
private
void
BtnAdvanceMode_Click(
object
sender, RoutedEventArgs e)
{
captureSource.Stop();
Utils.UploadUserFile(Utils.GetUserId()
+
"
.jpg
"
, focusRectangle.imageScroll, focusRectangle.FocusRect,
(o, eventArgs)
=>
//
定制UserFile的PropertyChanged 属性,如BytesUploaded,Percentage,IsDeleted
{
UserFile userFile
=
o
as
UserFile;
if
(eventArgs.PropertyName
==
"
Percentage
"
)
{
Percentage.Value
=
userFile.Percentage;
Percentage.Visibility
=
Percentage.Value
==
100
?
Visibility.Collapsed : Visibility.Visible;
}
//
当前文件上传完毕
if
(userFile.State
==
Constants.FileStates.Finished)
this
.NavigationService.Navigate(
new
Uri(
string
.Format(
"
/AdvanceMode?focusWidth={0}&focusHeight={1}&fileName={2}
"
,
focusRectangle.FocusRect.Width,
focusRectangle.FocusRect.Height,
userFile.FileName),
UriKind.Relative));
});
}
#endregion
}
下面是涂鸦功能中的工具栏XMAL和实现代码,如下图:
InkMenu.xaml:
<
Canvas x:Name
=
"
LayoutRoot
"
Background
=
"
AliceBlue
"
>
<!--
InkPresenter Start
-->
<
StackPanel Margin
=
"
0,0,8,0
"
Canvas.Top
=
"
5
"
>
<
TextBlock FontSize
=
"
12
"
Name
=
"
stroke
"
>
边框色:
</
TextBlock
>
<
Slider Name
=
"
inkStrokeSlider
"
Minimum
=
"
0
"
Maximum
=
"
1
"
Width
=
"
100
"
Height
=
"
20
"
HorizontalAlignment
=
"
Left
"
Orientation
=
"
Horizontal
"
ValueChanged
=
"
inkStrokeSlider_ValueChanged
"
>
<
Slider.Background
>
<
LinearGradientBrush StartPoint
=
"
0,0
"
EndPoint
=
"
1,0
"
>
<
GradientStop Color
=
"
#FF000000
"
Offset
=
"
0
"
/>
<
GradientStop Color
=
"
#FFFF0000
"
Offset
=
"
0.143
"
/>
<
GradientStop Color
=
"
#FF00FF00
"
Offset
=
"
0.286
"
/>
<
GradientStop Color
=
"
#FF0000FF
"
Offset
=
"
0.429
"
/>
<
GradientStop Color
=
"
#FF00FFFF
"
Offset
=
"
0.571
"
/>
<
GradientStop Color
=
"
#FFFF00FF
"
Offset
=
"
0.714
"
/>
<
GradientStop Color
=
"
#FFFFFF00
"
Offset
=
"
0.857
"
/>
<
GradientStop Color
=
"
#FFFFFFFF
"
Offset
=
"
1
"
/>
</
LinearGradientBrush
>
</
Slider.Background
>
</
Slider
>
<
TextBlock FontSize
=
"
12
"
>
填充色:
</
TextBlock
>
<
Slider Name
=
"
inkFillSlider
"
Minimum
=
"
0
"
Maximum
=
"
1
"
Width
=
"
100
"
Height
=
"
20
"
HorizontalAlignment
=
"
Left
"
Orientation
=
"
Horizontal
"
ValueChanged
=
"
inkFillSlider_ValueChanged
"
>
<
Slider.Background
>
<
LinearGradientBrush StartPoint
=
"
0,0
"
EndPoint
=
"
1,0
"
>
<
GradientStop Color
=
"
#FF000000
"
Offset
=
"
0
"
/>
<
GradientStop Color
=
"
#FFFF0000
"
Offset
=
"
0.143
"
/>
<
GradientStop Color
=
"
#FF00FF00
"
Offset
=
"
0.286
"
/>
<
GradientStop Color
=
"
#FF0000FF
"
Offset
=
"
0.429
"
/>
<
GradientStop Color
=
"
#FF00FFFF
"
Offset
=
"
0.571
"
/>
<
GradientStop Color
=
"
#FFFF00FF
"
Offset
=
"
0.714
"
/>
<
GradientStop Color
=
"
#FFFFFF00
"
Offset
=
"
0.857
"
/>
<
GradientStop Color
=
"
#FFFFFFFF
"
Offset
=
"
1
"
/>
</
LinearGradientBrush
>
</
Slider.Background
>
</
Slider
>
<
TextBlock FontSize
=
"
12
"
>
边框:
</
TextBlock
>
<
Slider Name
=
"
inkThicknessSlider
"
Minimum
=
"
0
"
Maximum
=
"
1
"
Width
=
"
100
"
Height
=
"
20
"
HorizontalAlignment
=
"
Left
"
Orientation
=
"
Horizontal
"
ValueChanged
=
"
inkThicknessSlider_ValueChanged
"
/>
<
TextBlock FontSize
=
"
12
"
>
透明:
</
TextBlock
>
<
Slider Name
=
"
inkTransparencySlider
"
Minimum
=
"
0
"
Maximum
=
"
1
"
Width
=
"
100
"
Height
=
"
20
"
HorizontalAlignment
=
"
Left
"
Orientation
=
"
Horizontal
"
ValueChanged
=
"
inkTransparencySlider_ValueChanged
"
/>
<
TextBlock Canvas.Left
=
"
10
"
Canvas.Top
=
"
200
"
FontSize
=
"
12
"
>
预览:
</
TextBlock
>
<
InkPresenter x:Name
=
"
inkPreview
"
Canvas.Top
=
"
215
"
Canvas.Left
=
"
15
"
Width
=
"
100
"
Height
=
"
35
"
>
<
InkPresenter.Background
>
<
LinearGradientBrush StartPoint
=
"
0,0
"
EndPoint
=
"
1,0
"
>
<
GradientStop Color
=
"
Gray
"
Offset
=
"
0
"
/>
<
GradientStop Color
=
"
Snow
"
Offset
=
"
1
"
/>
</
LinearGradientBrush
>
</
InkPresenter.Background
>
<
InkPresenter.Strokes
>
<
StrokeCollection
>
<
Stroke
>
<
Stroke.DrawingAttributes
>
<
DrawingAttributes Color
=
"
Black
"
OutlineColor
=
"
Black
"
Height
=
"
5
"
Width
=
"
5
"
/>
</
Stroke.DrawingAttributes
>
<
Stroke.StylusPoints
>
<
StylusPointCollection
>
<
StylusPoint X
=
"
6.365068435668945
"
Y
=
"
13.124124526977539
"
/>
<
StylusPoint X
=
"
6.365068435668945
"
Y
=
"
13.124124526977539
"
/>
<
StylusPoint X
=
"
6.414070129394531
"
Y
=
"
13.76108169555664
"
/>
<
StylusPoint X
=
"
6.414070129394531
"
Y
=
"
13.76108169555664
"
/>
<
StylusPoint X
=
"
7.002099990844727
"
Y
=
"
14.153057098388671
"
/>
<
StylusPoint X
=
"
7.590129852294922
"
Y
=
"
14.104059219360351
"
/>
<
StylusPoint X
=
"
8.423171997070312
"
Y
=
"
13.859075546264648
"
/>
<
StylusPoint X
=
"
9.501224517822265
"
Y
=
"
13.46710205078125
"
/>
<
StylusPoint X
=
"
10.922296524047851
"
Y
=
"
12.830144882202148
"
/>
<
StylusPoint X
=
"
12.58837890625
"
Y
=
"
12.046195983886718
"
/>
<
StylusPoint X
=
"
14.401470184326171
"
Y
=
"
11.017265319824218
"
/>
<
StylusPoint X
=
"
16.41057014465332
"
Y
=
"
10.037330627441406
"
/>
<
StylusPoint X
=
"
18.41967010498047
"
Y
=
"
8.910406112670898
"
/>
<
StylusPoint X
=
"
20.526775360107422
"
Y
=
"
7.73448371887207
"
/>
<
StylusPoint X
=
"
22.437870025634765
"
Y
=
"
6.70555305480957
"
/>
<
StylusPoint X
=
"
24.299964904785156
"
Y
=
"
5.725618362426758
"
/>
<
StylusPoint X
=
"
25.770038604736328
"
Y
=
"
4.941671371459961
"
/>
<
StylusPoint X
=
"
25.770038604736328
"
Y
=
"
4.941671371459961
"
/>
<
StylusPoint X
=
"
27.19110870361328
"
Y
=
"
4.206720352172852
"
/>
<
StylusPoint X
=
"
28.171157836914062
"
Y
=
"
3.7167530059814453
"
/>
<
StylusPoint X
=
"
29.102203369140625
"
Y
=
"
3.2757816314697265
"
/>
<
StylusPoint X
=
"
29.690235137939453
"
Y
=
"
2.981801986694336
"
/>
<
StylusPoint X
=
"
29.690235137939453
"
Y
=
"
2.981801986694336
"
/>
<
StylusPoint X
=
"
30.278263092041015
"
Y
=
"
2.736818313598633
"
/>
<
StylusPoint X
=
"
30.278263092041015
"
Y
=
"
2.736818313598633
"
/>
<
StylusPoint X
=
"
30.278263092041015
"
Y
=
"
2.736818313598633
"
/>
<
StylusPoint X
=
"
30.033252716064453
"
Y
=
"
3.324777603149414
"
/>
<
StylusPoint X
=
"
29.837242126464843
"
Y
=
"
3.765748977661133
"
/>
<
StylusPoint X
=
"
29.298213958740234
"
Y
=
"
4.59869384765625
"
/>
<
StylusPoint X
=
"
28.75918960571289
"
Y
=
"
5.67662239074707
"
/>
<
StylusPoint X
=
"
27.975147247314453
"
Y
=
"
7.195520401000977
"
/>
<
StylusPoint X
=
"
27.2401123046875
"
Y
=
"
8.861410140991211
"
/>
<
StylusPoint X
=
"
26.35806655883789
"
Y
=
"
10.821279525756836
"
/>
<
StylusPoint X
=
"
25.5250244140625
"
Y
=
"
12.830144882202148
"
/>
<
StylusPoint X
=
"
24.789989471435547
"
Y
=
"
14.790014266967773
"
/>
<
StylusPoint X
=
"
24.201961517333984
"
Y
=
"
16.65188980102539
"
/>
<
StylusPoint X
=
"
23.858943939208984
"
Y
=
"
18.317779541015625
"
/>
<
StylusPoint X
=
"
23.809940338134765
"
Y
=
"
19.689685821533203
"
/>
<
StylusPoint X
=
"
24.103954315185547
"
Y
=
"
20.522632598876953
"
/>
<
StylusPoint X
=
"
24.740985870361328
"
Y
=
"
20.91460418701172
"
/>
<
StylusPoint X
=
"
25.770038604736328
"
Y
=
"
20.91460418701172
"
/>
<
StylusPoint X
=
"
27.28911590576172
"
Y
=
"
20.375640869140625
"
/>
<
StylusPoint X
=
"
29.200210571289062
"
Y
=
"
19.395706176757812
"
/>
<
StylusPoint X
=
"
29.200210571289062
"
Y
=
"
19.395706176757812
"
/>
<
StylusPoint X
=
"
31.356319427490234
"
Y
=
"
18.072795867919922
"
/>
<
StylusPoint X
=
"
33.70843505859375
"
Y
=
"
16.455902099609375
"
/>
<
StylusPoint X
=
"
36.20756149291992
"
Y
=
"
14.594026565551757
"
/>
<
StylusPoint X
=
"
38.75568771362305
"
Y
=
"
12.683155059814453
"
/>
<
StylusPoint X
=
"
41.15680694580078
"
Y
=
"
10.772281646728515
"
/>
<
StylusPoint X
=
"
41.15680694580078
"
Y
=
"
10.772281646728515
"
/>
<
StylusPoint X
=
"
43.410919189453125
"
Y
=
"
8.910406112670898
"
/>
<
StylusPoint X
=
"
45.273014068603516
"
Y
=
"
7.391508102416992
"
/>
<
StylusPoint X
=
"
46.74308776855469
"
Y
=
"
6.117591857910156
"
/>
<
StylusPoint X
=
"
47.82114028930664
"
Y
=
"
5.186655044555664
"
/>
<
StylusPoint X
=
"
48.55617904663086
"
Y
=
"
4.696687698364258
"
/>
<
StylusPoint X
=
"
48.55617904663086
"
Y
=
"
4.696687698364258
"
/>
<
StylusPoint X
=
"
48.55617904663086
"
Y
=
"
4.696687698364258
"
/>
<
StylusPoint X
=
"
48.55617904663086
"
Y
=
"
5.725618362426758
"
/>
<
StylusPoint X
=
"
47.91914749145508
"
Y
=
"
6.999532699584961
"
/>
<
StylusPoint X
=
"
47.08610534667969
"
Y
=
"
8.46943473815918
"
/>
<
StylusPoint X
=
"
46.05705261230469
"
Y
=
"
10.33131217956543
"
/>
<
StylusPoint X
=
"
44.979000091552734
"
Y
=
"
12.340177536010742
"
/>
<
StylusPoint X
=
"
44.979000091552734
"
Y
=
"
12.340177536010742
"
/>
<
StylusPoint X
=
"
43.85194396972656
"
Y
=
"
14.398040771484375
"
/>
<
StylusPoint X
=
"
42.82289123535156
"
Y
=
"
16.406906127929687
"
/>
<
StylusPoint X
=
"
42.82289123535156
"
Y
=
"
16.406906127929687
"
/>
<
StylusPoint X
=
"
41.94084548950195
"
Y
=
"
18.219783782958984
"
/>
<
StylusPoint X
=
"
41.30381393432617
"
Y
=
"
19.88567352294922
"
/>
<
StylusPoint X
=
"
41.30381393432617
"
Y
=
"
19.88567352294922
"
/>
<
StylusPoint X
=
"
40.91179656982422
"
Y
=
"
21.159587860107422
"
/>
<
StylusPoint X
=
"
40.86279296875
"
Y
=
"
22.139522552490234
"
/>
<
StylusPoint X
=
"
41.15680694580078
"
Y
=
"
22.62948989868164
"
/>
<
StylusPoint X
=
"
41.74483871459961
"
Y
=
"
22.72748565673828
"
/>
<
StylusPoint X
=
"
42.67588424682617
"
Y
=
"
22.33551025390625
"
/>
<
StylusPoint X
=
"
43.85194396972656
"
Y
=
"
21.60055923461914
"
/>
<
StylusPoint X
=
"
45.37101745605469
"
Y
=
"
20.620624542236328
"
/>
<
StylusPoint X
=
"
47.03710174560547
"
Y
=
"
19.297714233398437
"
/>
<
StylusPoint X
=
"
48.85019302368164
"
Y
=
"
17.82781219482422
"
/>
<
StylusPoint X
=
"
50.71228790283203
"
Y
=
"
16.161922454833984
"
/>
<
StylusPoint X
=
"
52.574378967285156
"
Y
=
"
14.54503059387207
"
/>
<
StylusPoint X
=
"
54.43647003173828
"
Y
=
"
12.928138732910156
"
/>
<
StylusPoint X
=
"
56.2005615234375
"
Y
=
"
11.605226516723632
"
/>
<
StylusPoint X
=
"
56.2005615234375
"
Y
=
"
11.605226516723632
"
/>
<
StylusPoint X
=
"
57.81764221191406
"
Y
=
"
10.380308151245117
"
/>
<
StylusPoint X
=
"
59.140708923339844
"
Y
=
"
9.449369430541992
"
/>
<
StylusPoint X
=
"
60.21875762939453
"
Y
=
"
8.763416290283203
"
/>
<
StylusPoint X
=
"
61.100807189941406
"
Y
=
"
8.371442794799804
"
/>
<
StylusPoint X
=
"
61.73783874511719
"
Y
=
"
8.371442794799804
"
/>
<
StylusPoint X
=
"
61.73783874511719
"
Y
=
"
8.371442794799804
"
/>
<
StylusPoint X
=
"
62.22785949707031
"
Y
=
"
9.498367309570312
"
/>
<
StylusPoint X
=
"
62.08085632324219
"
Y
=
"
10.62529182434082
"
/>
<
StylusPoint X
=
"
61.68883514404297
"
Y
=
"
12.242183685302734
"
/>
<
StylusPoint X
=
"
61.100807189941406
"
Y
=
"
14.251049041748046
"
/>
<
StylusPoint X
=
"
60.36576843261719
"
Y
=
"
16.602893829345703
"
/>
<
StylusPoint X
=
"
59.53273010253906
"
Y
=
"
19.15072250366211
"
/>
<
StylusPoint X
=
"
58.65068054199219
"
Y
=
"
21.74755096435547
"
/>
<
StylusPoint X
=
"
57.81764221191406
"
Y
=
"
24.246383666992187
"
/>
<
StylusPoint X
=
"
57.082603454589844
"
Y
=
"
26.69622039794922
"
/>
<
StylusPoint X
=
"
56.5435791015625
"
Y
=
"
28.75408172607422
"
/>
<
StylusPoint X
=
"
56.29856872558594
"
Y
=
"
30.419971466064453
"
/>
<
StylusPoint X
=
"
56.347564697265625
"
Y
=
"
31.497901916503906
"
/>
<
StylusPoint X
=
"
56.78858947753906
"
Y
=
"
31.93886947631836
"
/>
<
StylusPoint X
=
"
57.5726318359375
"
Y
=
"
31.791881561279297
"
/>
<
StylusPoint X
=
"
58.797691345214844
"
Y
=
"
31.20391845703125
"
/>
<
StylusPoint X
=
"
60.36576843261719
"
Y
=
"
30.17498779296875
"
/>
<
StylusPoint X
=
"
62.42387390136719
"
Y
=
"
28.70508575439453
"
/>
<
StylusPoint X
=
"
64.62898254394531
"
Y
=
"
27.039196014404297
"
/>
<
StylusPoint X
=
"
66.9811019897461
"
Y
=
"
25.079326629638672
"
/>
<
StylusPoint X
=
"
69.43122100830078
"
Y
=
"
23.119457244873047
"
/>
<
StylusPoint X
=
"
71.83234405517578
"
Y
=
"
21.257583618164062
"
/>
<
StylusPoint X
=
"
74.18445587158203
"
Y
=
"
19.54269790649414
"
/>
<
StylusPoint X
=
"
76.38957214355469
"
Y
=
"
18.072795867919922
"
/>
<
StylusPoint X
=
"
78.34967041015625
"
Y
=
"
16.847877502441406
"
/>
<
StylusPoint X
=
"
78.34967041015625
"
Y
=
"
16.847877502441406
"
/>
<
StylusPoint X
=
"
79.96675109863281
"
Y
=
"
15.916938781738281
"
/>
<
StylusPoint X
=
"
81.33881378173828
"
Y
=
"
15.27998161315918
"
/>
<
StylusPoint X
=
"
82.36786651611328
"
Y
=
"
14.986000061035156
"
/>
<
StylusPoint X
=
"
83.15190887451172
"
Y
=
"
15.083993911743164
"
/>
<
StylusPoint X
=
"
83.64192962646484
"
Y
=
"
15.57396125793457
"
/>
<
StylusPoint X
=
"
83.7889404296875
"
Y
=
"
16.504899978637695
"
/>
<
StylusPoint X
=
"
83.49492645263672
"
Y
=
"
17.77881622314453
"
/>
<
StylusPoint X
=
"
83.00489807128906
"
Y
=
"
19.4447021484375
"
/>
<
StylusPoint X
=
"
82.31886291503906
"
Y
=
"
21.208587646484375
"
/>
<
StylusPoint X
=
"
81.53482818603515
"
Y
=
"
23.16845703125
"
/>
<
StylusPoint X
=
"
80.75078582763672
"
Y
=
"
25.030330657958984
"
/>
<
StylusPoint X
=
"
79.96675109863281
"
Y
=
"
26.843212127685547
"
/>
</
StylusPointCollection
>
</
Stroke.StylusPoints
>
</
Stroke
>
</
StrokeCollection
>
</
InkPresenter.Strokes
>
</
InkPresenter
>
<
CheckBox Name
=
"
Erase
"
Content
=
"
橡皮擦
"
ToolTipService.ToolTip
=
"
选中后可擦除指定画笔
"
/>
<!--
InkPresenter End
-->
</
StackPanel
>
</
Canvas
>
InkMenu.xaml.cs:
public
partial
class
InkMenu : UserControl
{
public
InkMenu()
{
InitializeComponent();
this
.Loaded
+=
new
RoutedEventHandler(InkMenu_Loaded);
}
void
InkMenu_Loaded(
object
sender, RoutedEventArgs e)
{
inkAttributes
=
inkPreview.Strokes[
0
].DrawingAttributes;
inkAttributes.Color
=
GetColor(inkFillSlider.Value);
inkAttributes.OutlineColor
=
GetColor(inkStrokeSlider.Value);
inkAttributes.Width
=
inkAttributes.Height
=
inkThicknessSlider.Value
*
10d;
}
#region
橡皮擦点击事件
///
<summary>
///
橡皮擦点击事件
///
</summary>
public
event
RoutedEventHandler Click
{
add
{
Erase.Click
+=
value;
}
remove
{
Erase.Click
-=
value;
}
}
#endregion
#region
获取颜色值
public
DrawingAttributes inkAttributes;
void
inkStrokeSlider_ValueChanged(
object
sender, EventArgs e)
{
byte
alpha
=
inkAttributes.OutlineColor.A;
inkAttributes.Color
=
GetColor(inkStrokeSlider.Value, alpha);
}
void
inkFillSlider_ValueChanged(
object
sender, EventArgs e)
{
byte
alpha
=
inkAttributes.Color.A;
inkAttributes.Color
=
GetColor(inkFillSlider.Value, alpha);
}
void
inkThicknessSlider_ValueChanged(
object
sender, EventArgs e)
{
inkAttributes.Width
=
inkThicknessSlider.Value
*
10d;
inkAttributes.Height
=
inkThicknessSlider.Value
*
10d;
}
void
inkTransparencySlider_ValueChanged(
object
sender, EventArgs e)
{
Color color
=
inkAttributes.Color;
Color outlineColor
=
inkAttributes.OutlineColor;
inkAttributes.Color
=
Color.FromArgb((
byte
)Math.Floor(256d
*
(1d
-
inkTransparencySlider.Value)), color.R, color.G, color.B);
inkAttributes.OutlineColor
=
Color.FromArgb((
byte
)Math.Floor(256d
*
(1d
-
inkTransparencySlider.Value)), outlineColor.R, outlineColor.G, outlineColor.B);
}
///
<summary>
///
获取颜色值
///
</summary>
///
<returns></returns>
public
Color GetColor(
double
value)
{
return
this
.GetColor(value,
255
);
}
///
<summary>
///
将滑动条值(Value)转换为ARGB 颜色值并返回
///
</summary>
///
<param name="alpha">
alpha通道,该值介于0到255
</param>
///
<returns>
ARGB 颜色值
</returns>
private
Color GetColor(
double
value,
byte
alpha)
{
Color color;
//
将滑动条的值转换为 ARGB 颜色值
if
(value
<
0.143d
)
{
color
=
Color.FromArgb(alpha, (
byte
)Math.Floor((value
*
256d)
/
0.143d
),
0
,
0
);
}
else
if
(value
<
0.286d
)
{
color
=
Color.FromArgb(alpha, (
byte
)Math.Floor(256d
*
(
0.286d
-
value)
/
0.143d
), (
byte
)Math.Floor(256d
*
(value
-
0.143d
)
/
0.143d
),
0
);
}
else
if
(value
<
0.429
)
{
color
=
Color.FromArgb(alpha,
0
, (
byte
)Math.Floor(256d
*
(
0.429d
-
value)
/
0.143d
), (
byte
)Math.Floor(256d
*
(value
-
0.286d
)
/
0.143d
));
}
else
if
(value
<
0.571
)
{
color
=
Color.FromArgb(alpha,
0
, (
byte
)Math.Floor(256d
*
(value
-
0.429d
)
/
0.143d
),
255
);
}
else
if
(value
<
0.714
)
{
color
=
Color.FromArgb(alpha, (
byte
)Math.Floor(256d
*
(value
-
0.571d
)
/
0.143d
), (
byte
)Math.Floor(256d
*
(
0.714d
-
value)
/
0.143d
),
255
);
}
else
if
(value
<
0.857
)
{
color
=
Color.FromArgb(alpha,
255
, (
byte
)Math.Floor(256d
*
(value
-
0.714d
)
/
0.143d
), (
byte
)Math.Floor(256d
*
(
0.857d
-
value)
/
0.143d
));
}
else
{
color
=
Color.FromArgb(alpha,
255
,
255
, (
byte
)Math.Floor(256d
*
(value
-
0.857d
)
/
0.143d
));
}
return
color;
}
#endregion
}
另外涂鸭的底层实现代码位于AdvanceMode.xaml.cs中:
#region
Ink 事件代码
///
<summary>
///
Ink 事件代码
///
</summary>
public
enum
InkEditingMode
{
None,
Ink,
Erase
}
///
<summary>
///
InkEditingMode模式,默认为Ink
///
</summary>
private
InkEditingMode editingMode
=
InkEditingMode.Ink;
private
Stroke inkStroke
=
null
;
private
StylusPointCollection erasePoints
=
null
;
void
onInkPresenterDown(
object
sender, MouseButtonEventArgs e)
{
if
(editingMode
==
InkEditingMode.None)
return
;
(sender
as
FrameworkElement).CaptureMouse();
StylusPointCollection stylusPoints
=
e.StylusDevice.GetStylusPoints(InkCanvas);
if
(editingMode
==
InkEditingMode.Erase)
{
erasePoints
=
new
StylusPointCollection();
erasePoints.Add(stylusPoints);
}
else
if
(editingMode
==
InkEditingMode.Ink)
{
inkStroke
=
new
Stroke();
inkStroke.StylusPoints.Add(stylusPoints);
inkStroke.DrawingAttributes
=
new
DrawingAttributes();
inkStroke.DrawingAttributes.Color
=
inkMenu.inkAttributes.Color;
inkStroke.DrawingAttributes.OutlineColor
=
inkMenu.inkAttributes.OutlineColor;
inkStroke.DrawingAttributes.Width
=
inkMenu.inkAttributes.Width;
inkStroke.DrawingAttributes.Height
=
inkMenu.inkAttributes.Height;
InkCanvas.Strokes.Add(inkStroke);
}
}
void
SetEditingMode()
{
if
(EditInkMode.IsChecked
==
true
)
{
if
(inkMenu.Erase.IsChecked
==
false
)
editingMode
=
InkEditingMode.Ink;
else
editingMode
=
InkEditingMode.Erase;
}
else
editingMode
=
InkEditingMode.None;
}
void
onInkPresenterMove(
object
sender, MouseEventArgs e)
{
SetEditingMode();
if
(editingMode
==
InkEditingMode.None)
return
;
StylusPointCollection stylusPoints
=
e.StylusDevice.GetStylusPoints(InkCanvas);
if
(editingMode
==
InkEditingMode.Erase)
{
if
(erasePoints
!=
null
)
{
//
hittest and erase
erasePoints.Add(stylusPoints);
StrokeCollection hitStrokes
=
InkCanvas.Strokes.HitTest(erasePoints);
for
(
int
i
=
0
; i
<
hitStrokes.Count; i
++
)
{
InkCanvas.Strokes.Remove(hitStrokes[i]);
}
}
}
else
if
(editingMode
==
InkEditingMode.Ink)
{
if
(inkStroke
!=
null
)
{
inkStroke.StylusPoints.Add(stylusPoints);
}
}
}
void
onInkPresenterEnter(
object
sender, MouseButtonEventArgs e)
{
if
(EditInkMode.IsChecked
==
true
)
{
if
(inkMenu.Erase.IsChecked
==
false
)
editingMode
=
InkEditingMode.Ink;
else
editingMode
=
InkEditingMode.Erase;
}
else
editingMode
=
InkEditingMode.None;
erasePoints
=
null
;
inkStroke
=
null
;
}
void
onInkPresenterUp(
object
sender, MouseButtonEventArgs e)
{
if
(editingMode
==
InkEditingMode.None)
return
;
if
(inkStroke
!=
null
)
{
inkStroke.StylusPoints.Add(e.StylusDevice.GetStylusPoints(InkCanvas));
}
(sender
as
FrameworkElement).ReleaseMouseCapture();
erasePoints
=
null
;
inkStroke
=
null
;
}
private
void
EditInkMode_Click(
object
sender, RoutedEventArgs e)
{
if
(EditInkMode.IsChecked
==
true
)
{
inkMenu.Visibility
=
System.Windows.Visibility.Visible;
if
(inkMenu.Erase.IsChecked
==
false
)
editingMode
=
InkEditingMode.Ink;
else
editingMode
=
InkEditingMode.Erase;
}
else
{
inkMenu.Visibility
=
System.Windows.Visibility.Collapsed;
editingMode
=
InkEditingMode.None;
}
}
private
void
Erase_Click(
object
sender, RoutedEventArgs e)
{
inkMenu.Visibility
=
System.Windows.Visibility.Visible;
if
(inkMenu.Erase.IsChecked
==
false
)
editingMode
=
InkEditingMode.Ink;
else
editingMode
=
InkEditingMode.Erase;
}
#endregion
当然就目前产品代码的结构而言还不够优化,特别是重复的代码段还有一些,不过不影响大家的最终使用,鉴于目前本人的经历和时间有限,所以就把它开源出来,大家如果感兴趣可以在其基础上加入更新的功能来完善它,呵呵。
好了,今天的内容就先到这里了, 源码下载链接,请点击这里
。
相关链接:
目前为止功能最全的基于silverlight4(beta)的摄像头应用
基于silverlight4(beta)的摄像头应用(Beta2)发布
原文链接: http://www.cnblogs.com/daizhj/archive/2010/08/31/1813437.html
作者: daizhj, 代震军
Tags: silverlight,webcam
网址: http://daizhj.cnblogs.com/
(Popup),打印功能
(PrintDocument),导航功能
,摄像头
,图片上传等。当然目前这个产品已在我们的官方产品Discuz!NT3.1中使用,今天开源的仅是本应用的源码。
下面链接中是产品的运行截图:
http://www.cnblogs.com/daizhj/archive/2010/02/26/1674389.html
好了,接下来介绍一下产品的源码分布:
其中:
ChildWindows/
CWMessageBox.xaml:显示窗口信息控件,用于显示系统提示的各种消息
CWViewUploadedImage.xaml:显示用于上传头像或文件之后的显示结果(包括大中小三种尺寸)
Controls/
FocusRectangle.xaml: 焦点选择区域控件及相应用户拖动效果
ImageButton.xaml:图片控件
InkMenu.xaml:ink涂鸦工具栏控件
Cursors/
CustomCursors.xaml: 定制鼠标图标控件, 用于当鼠标进入FocusRectangle区域后显示定制的十字箭头
Shader/
三个silverlight滤镜
Images/
项目中使用的图标
Utils/
相关工具类
Constants.cs,Converter.cs,UserFile.cs,FileCollection.cs, FileUploader.cs 图片上传代码
Utils.cs 常用函数封装工具类
AdvanceMode.xaml:高级模式的编辑窗口
ImageBrowser.xaml:图片浏览和编辑上传窗口
NavPage.xaml:导航窗口
WebCam.xaml:摄像头功能和上传窗口
好的,产品布局就介绍到这里了,下面是对于之前朋友感兴趣的一些功能的代码介绍。
首先就是焦点选择框(矩形)的实现原理和相应代码,位于FocusRectangle.xaml和FocusRectangle.xaml.cs 原理就
是首先绘制8个小矩形,作为用户进行鼠标操作的入口(均定制了鼠标点击操作代码),然后将这8个小矩形分布在一个大矩形的四角和两两节点间的中心位置,当
然也加入鼠标的拖动和“上下左右扩展”代码,明确了实现方式之后,就看一下源码来加深一下理解了:
XAML:
<
Canvas x:Name
=
"
LayoutRoot
"
>
<
Canvas Name
=
"
ViewportHost
"
Height
=
"
270
"
Width
=
"
270
"
Background
=
"
Gray
"
>
<
ScrollViewer Canvas.ZIndex
=
"
0
"
Name
=
"
imageScroll
"
BorderThickness
=
"
0
"
Background
=
"
Transparent
"
Width
=
"
270
"
Height
=
"
270
"
VerticalScrollBarVisibility
=
"
Hidden
"
HorizontalScrollBarVisibility
=
"
Hidden
"
>
<
Rectangle Name
=
"
Viewport
"
Width
=
"
270
"
Height
=
"
270
"
Canvas.ZIndex
=
"
100
"
>
<
Rectangle.Fill
>
<
ImageBrush
>
<
ImageBrush.ImageSource
>
<
BitmapImage x:Name
=
"
selectedImage
"
UriSource
=
"
../Images/main.jpg
"
/>
</
ImageBrush.ImageSource
>
</
ImageBrush
>
</
Rectangle.Fill
>
</
Rectangle
>
</
ScrollViewer
>
<!--<
TextBlock x:Name
=
"
msgBox
"
Width
=
"
269
"
Text
=
"
000
"
Foreground
=
"
Red
"
Height
=
"
100
"
Canvas.ZIndex
=
"
10000
"
/>-->
<
local:CustomCursors x:Name
=
"
customCursors
"
Visibility
=
"
Collapsed
"
></
local:CustomCursors
>
<
Rectangle Name
=
"
FocusRect
"
Canvas.Left
=
"
5
"
Canvas.Top
=
"
5
"
Fill
=
"
Transparent
"
Opacity
=
"
1
"
Stroke
=
"
White
"
StrokeThickness
=
"
1
"
/>
</
Canvas
>
</
Canvas
>
XAML文件中包括一个ScrollViewer用于实现图片的缩放效果,CustomCursors用于鼠标移入焦点区域时显示焦点图标而不是鼠标沙漏。
下面则是FocusRectangle.xaml.cs代码,包括8个小矩形的枚举标识:
#region
方形中八个点的相对位置
///
<summary>
///
方形中八个点的相对位置
///
</summary>
enum
HitDownSquare
{
HDS_NONE
=
0
,
///
<summary>
///
顶
///
</summary>
HDS_TOP
=
1
,
///
<summary>
///
右
///
</summary>
HDS_RIGHT
=
2
,
///
<summary>
///
底
///
</summary>
HDS_BOTTOM
=
3
,
///
<summary>
///
左
///
</summary>
HDS_LEFT
=
4
,
///
<summary>
///
左上
///
</summary>
HDS_TOPLEFT
=
5
,
///
<summary>
///
右上
///
</summary>
HDS_TOPRIGHT
=
6
,
///
<summary>
///
左下
///
</summary>
HDS_BOTTOMLEFT
=
7
,
///
<summary>
///
右下
///
</summary>
HDS_BOTTOMRIGHT
=
8
}
#endregion
主要的控件类实体,实现各种相关鼠标操作事件和图形绘制事件代码(详见注释):
public
partial
class
FocusRectangle : UserControl
{
#region
属性设置
///
<summary>
///
8个允许调整控件大小的小正方形
///
</summary>
Rectangle[] SmallRect
=
new
Rectangle[
8
];
///
<summary>
///
8个小正方形的大小
///
</summary>
Size Square
=
new
Size(
6
,
6
);
///
<summary>
///
上一次鼠标点击的位置
///
</summary>
Point prevLeftClick;
///
<summary>
///
8个小正方形的填充色
///
</summary>
Color color
=
Colors.White;
///
<summary>
///
标识鼠标左键已被按下并且已开始移动
///
</summary>
bool
trackingMouseMove
=
false
;
///
<summary>
///
当前鼠标点击位置信息
///
</summary>
HitDownSquare CurrHitPlace
=
new
HitDownSquare();
#endregion
public
FocusRectangle()
{
InitializeComponent();
this
.Loaded
+=
new
RoutedEventHandler(FocusRectangle_Loaded);
}
#region
初始化相应元素信息
///
<summary>
///
初始化相应元素信息
///
</summary>
///
<param name="sender"></param>
///
<param name="e"></param>
void
FocusRectangle_Loaded(
object
sender, RoutedEventArgs e)
{
Viewport.MinHeight
=
Viewport.MinWidth
=
16
;
Viewport.SetValue(Canvas.TopProperty, (
double
)ViewportHost.GetValue(Canvas.TopProperty)
+
(ViewportHost.Height
-
Viewport.Height)
/
2
);
Viewport.SetValue(Canvas.LeftProperty, (
double
)ViewportHost.GetValue(Canvas.LeftProperty)
+
(ViewportHost.Width
-
Viewport.Width)
/
2
);
//
初始设置FocusRect
FocusRect.Width
=
FocusRect.Height
=
100
;
FocusRect.MaxWidth
=
ViewportHost.Width;
FocusRect.MaxHeight
=
ViewportHost.Height;
FocusRect.MinHeight
=
FocusRect.MinWidth
=
8
;
FocusRect.SetValue(Canvas.TopProperty, (
double
)ViewportHost.GetValue(Canvas.TopProperty)
+
(ViewportHost.Height
-
FocusRect.Height)
/
2
);
FocusRect.SetValue(Canvas.LeftProperty, (
double
)ViewportHost.GetValue(Canvas.LeftProperty)
+
(ViewportHost.Width
-
FocusRect.Width)
/
2
);
#region
8个小正方形位置
//
左上
SmallRect[
0
]
=
new
Rectangle() { Name
=
"
SmallRect0
"
, Width
=
Square.Width, Height
=
Square.Height, Fill
=
new
SolidColorBrush(color) };
//
上中间
SmallRect[
4
]
=
new
Rectangle() { Name
=
"
SmallRect4
"
, Width
=
Square.Width, Height
=
Square.Height, Fill
=
new
SolidColorBrush(color) };
//
右上
SmallRect[
1
]
=
new
Rectangle() { Name
=
"
SmallRect1
"
, Width
=
Square.Width, Height
=
Square.Height, Fill
=
new
SolidColorBrush(color) };
//
左下
SmallRect[
2
]
=
new
Rectangle() { Name
=
"
SmallRect2
"
, Width
=
Square.Width, Height
=
Square.Height, Fill
=
new
SolidColorBrush(color) };
//
下中间
SmallRect[
5
]
=
new
Rectangle() { Name
=
"
SmallRect5
"
, Width
=
Square.Width, Height
=
Square.Height, Fill
=
new
SolidColorBrush(color) };
//
右下
SmallRect[
3
]
=
new
Rectangle() { Name
=
"
SmallRect3
"
, Width
=
Square.Width, Height
=
Square.Height, Fill
=
new
SolidColorBrush(color) };
//
左中间
SmallRect[
6
]
=
new
Rectangle() { Name
=
"
SmallRect6
"
, Width
=
Square.Width, Height
=
Square.Height, Fill
=
new
SolidColorBrush(color) };
//
右中间
SmallRect[
7
]
=
new
Rectangle() { Name
=
"
SmallRect7
"
, Width
=
Square.Width, Height
=
Square.Height, Fill
=
new
SolidColorBrush(color) };
SetRectangles();
#endregion
#region
事件绑定
foreach
(Rectangle smallRectangle
in
SmallRect)
{
smallRectangle.Fill
=
new
SolidColorBrush(color);
smallRectangle.MouseMove
+=
new
MouseEventHandler(smallRectangle_MouseMove);
smallRectangle.MouseLeftButtonUp
+=
new
MouseButtonEventHandler(smallRectangle_MouseLeftButtonUp);
smallRectangle.MouseLeftButtonDown
+=
new
MouseButtonEventHandler(smallRectangle_MouseLeftButtonDown);
smallRectangle.MouseEnter
+=
new
MouseEventHandler(smallRectangle_MouseEnter);
LayoutRoot.Children.Add(smallRectangle);
}
FocusRect.MouseMove
+=
new
MouseEventHandler(FocusRect_MouseMove);
FocusRect.MouseLeftButtonDown
+=
new
MouseButtonEventHandler(FocusRect_MouseLeftButtonDown);
FocusRect.MouseLeftButtonUp
+=
new
MouseButtonEventHandler(FocusRect_MouseLeftButtonUp);
FocusRect.MouseEnter
+=
new
MouseEventHandler(FocusRect_MouseEnter);
FocusRect.MouseLeave
+=
new
MouseEventHandler(FocusRect_MouseLeave);
#endregion
}
#endregion
#region
FocusRect鼠标事件
void
FocusRect_MouseLeave(
object
sender, MouseEventArgs e)
{
customCursors.Visibility
=
System.Windows.Visibility.Collapsed;
}
void
FocusRect_MouseEnter(
object
sender, MouseEventArgs e)
{
FrameworkElement element
=
sender
as
FrameworkElement;
element.Cursor
=
Cursors.None;
customCursors.Visibility
=
System.Windows.Visibility.Visible;
customCursors.SetPostion(e.GetPosition(LayoutRoot));
}
void
FocusRect_MouseLeftButtonUp(
object
sender, MouseButtonEventArgs e)
{
FrameworkElement element
=
sender
as
FrameworkElement;
trackingMouseMove
=
false
;
element.ReleaseMouseCapture();
prevLeftClick.X
=
prevLeftClick.Y
=
0
;
element.Cursor
=
Cursors.None;
if
(Viewport.Width
<
FocusRect.Width)
FocusRect.Width
=
Viewport.Width;
if
(Viewport.Height
<
FocusRect.Height)
FocusRect.Height
=
Viewport.Height;
AssureFocusRectMoveInZone(element.Name);
SetRectangles();
}
void
FocusRect_MouseLeftButtonDown(
object
sender, MouseButtonEventArgs e)
{
FrameworkElement element
=
sender
as
FrameworkElement;
prevLeftClick
=
e.GetPosition(element);
trackingMouseMove
=
true
;
if
(
null
!=
element)
{
element.CaptureMouse();
element.Cursor
=
Cursors.None;
}
}
///
<summary>
///
计算并设置Scroll的偏移量
///
</summary>
///
<param name="offSetX">
鼠标X轴移动的偏移量
</param>
///
<param name="offSetY">
鼠标Y轴移动的偏移量
</param>
void
ComputeScrollOffSet(
double
offSetX,
double
offSetY)
{
double
FocusRectTop
=
(
double
)FocusRect.GetValue(Canvas.TopProperty);
double
FocusRectLeft
=
(
double
)FocusRect.GetValue(Canvas.LeftProperty);
double
ViewportHostTop
=
(
double
)ViewportHost.GetValue(Canvas.TopProperty);
double
ViewportHostLeft
=
(
double
)ViewportHost.GetValue(Canvas.LeftProperty);
//
msgBox.Text = "FocusRect.Height" + FocusRect.Height + " ViewportHost.Height" + ViewportHost.Height;
if
(offSetY
>
0
&&
(FocusRect.Height
+
8
)
<
ViewportHost.Height
&&
(ViewportHostTop
+
ViewportHost.Height)
>
(FocusRectTop
+
FocusRect.Height))
//
鼠标向下且未出ViewportHost区域时
imageScroll.ScrollToVerticalOffset(imageScroll.VerticalOffset
+
(offSetY
/
2
)
*
(Viewport.Height
/
(ViewportHost.Height
-
FocusRectTop
-
FocusRect.Height)));
if
(offSetY
<
0
&&
(FocusRect.Height
+
8
)
<
ViewportHost.Height
&&
ViewportHostTop
<
FocusRectTop)
//
鼠标向上且未出ViewportHost区域时
imageScroll.ScrollToVerticalOffset(imageScroll.VerticalOffset
+
(offSetY
/
2
)
*
((Viewport.Height
/
FocusRectTop)));
if
(offSetX
>
0
&&
(FocusRect.Width
+
8
)
<
ViewportHost.Width
&&
(ViewportHostLeft
+
ViewportHost.Width)
>
(FocusRectLeft
+
FocusRect.Width))
//
鼠标向右且未出ViewportHost区域时
imageScroll.ScrollToHorizontalOffset(imageScroll.HorizontalOffset
+
(offSetX
/
2
)
*
(Viewport.Width
/
(ViewportHost.Width
-
FocusRectLeft
-
FocusRect.Width)));
if
(offSetX
<
0
&&
(FocusRect.Width
+
8
)
<
ViewportHost.Width
&&
ViewportHostLeft
<
FocusRectLeft)
//
鼠标向左且未出ViewportHost区域时
imageScroll.ScrollToHorizontalOffset(imageScroll.HorizontalOffset
+
(offSetX
/
2
)
*
((Viewport.Width
/
FocusRectLeft)));
//
msgBox.Text = imageScroll.HorizontalOffset.ToString();
}
///
<summary>
///
FocusRect鼠标移动事件
///
</summary>
///
<param name="sender"></param>
///
<param name="e"></param>
void
FocusRect_MouseMove(
object
sender, MouseEventArgs e)
{
FrameworkElement element
=
sender
as
FrameworkElement;
if
(element
!=
null
)
element.Cursor
=
Cursors.None;
if
(trackingMouseMove)
{
double
offSetX
=
e.GetPosition(element).X
-
prevLeftClick.X;
double
offSetY
=
e.GetPosition(element).Y
-
prevLeftClick.Y;
if
(((
double
)element.GetValue(Canvas.TopProperty)
+
offSetY)
>=
4
&&
(((
double
)FocusRect.GetValue(Canvas.TopProperty)
+
FocusRect.Height)
+
offSetY
+
3
)
<=
ViewportHost.Height)
element.SetValue(Canvas.TopProperty, (
double
)element.GetValue(Canvas.TopProperty)
+
offSetY);
if
(((
double
)element.GetValue(Canvas.LeftProperty)
+
offSetX)
>=
4
&&
(((
double
)FocusRect.GetValue(Canvas.LeftProperty)
+
FocusRect.Width)
+
offSetX
+
3
)
<=
ViewportHost.Width)
element.SetValue(Canvas.LeftProperty, (
double
)element.GetValue(Canvas.LeftProperty)
+
offSetX);
ComputeScrollOffSet(offSetX, offSetY);
SetRectangles();
}
customCursors.SetPostion(e.GetPosition(LayoutRoot));
}
#endregion
#region
确保FocusRect在Viewport中进行移动和缩放
///
<summary>
///
确保FocusRect在Viewport中进行缩放
///
</summary>
public
void
AssureFocusRectZoomInZone(
double
zoom,
double
mininum)
{
double
ViewPortTop
=
(
double
)Viewport.GetValue(Canvas.TopProperty);
double
ViewPortLeft
=
(
double
)Viewport.GetValue(Canvas.LeftProperty);
double
FocusRectTop
=
(
double
)FocusRect.GetValue(Canvas.TopProperty);
double
FocusRectLeft
=
(
double
)FocusRect.GetValue(Canvas.LeftProperty);
if
(zoom
==
mininum)
{
FocusRect.SetValue(Canvas.LeftProperty, ViewPortLeft);
FocusRect.Width
=
Viewport.Width;
}
else
{
//
确保顶部不越界
if
(ViewPortTop
>
FocusRectTop)
FocusRect.SetValue(Canvas.TopProperty, ViewPortTop);
//
确保左侧不越界
if
(ViewPortLeft
>
FocusRectLeft)
FocusRect.SetValue(Canvas.LeftProperty, ViewPortLeft);
//
判断x是否右侧越界
if
((Viewport.Width
+
ViewPortLeft)
<
(FocusRect.Width
+
FocusRectLeft))
{
//
如果已越界,但左侧未越界
if
(Viewport.Width
>
FocusRect.Width)
FocusRect.SetValue(Canvas.LeftProperty, ViewPortLeft
+
Viewport.Width
-
FocusRect.Width);
else
FocusRect.Width
=
Viewport.Width;
}
//
判断是否底部越界
if
((Viewport.Height
+
ViewPortTop)
<
(FocusRect.Height
+
FocusRectTop))
{
//
如果已越界,但顶部未越界
if
(Viewport.Height
>
FocusRect.Height)
FocusRect.SetValue(Canvas.TopProperty, ViewPortTop
+
Viewport.Height
-
FocusRect.Height);
else
FocusRect.Height
=
Viewport.Height;
}
}
SetRectangles();
}
///
<summary>
///
FocusRect是否在Viewport中,如不在,则确保其不超出Viewport区域
///
</summary>
///
<returns></returns>
bool
AssureFocusRectMoveInZone(
string
elementName)
{
bool
result
=
true
;
//
try
//
{
double
ViewPortTop
=
(
double
)Viewport.GetValue(Canvas.TopProperty);
double
ViewPortLeft
=
(
double
)Viewport.GetValue(Canvas.LeftProperty);
double
FocusRectTop
=
(
double
)FocusRect.GetValue(Canvas.TopProperty);
double
FocusRectLeft
=
(
double
)FocusRect.GetValue(Canvas.LeftProperty);
if
(Viewport.Height
>
ViewportHost.Height)
//
已使用放大功能,向上拖动
{
if
(
0
>
FocusRectTop)
{
FocusRect.SetValue(Canvas.TopProperty, (
double
)ViewportHost.GetValue(Canvas.TopProperty)
+
4
);
result
=
false
;
}
}
else
{
if
(ViewPortTop
>
FocusRectTop)
{
FocusRect.SetValue(Canvas.TopProperty, ViewPortTop);
result
=
false
;
}
}
if
(Viewport.Width
>=
ViewportHost.Width)
//
已使用放大功能,向左拖动
{
if
(
0
>
FocusRectLeft)
{
FocusRect.SetValue(Canvas.LeftProperty, (
double
)ViewportHost.GetValue(Canvas.LeftProperty)
+
4
);
result
=
false
;
}
}
else
{
if
(ViewPortLeft
>
FocusRectLeft)
{
FocusRect.SetValue(Canvas.LeftProperty, ViewPortLeft);
result
=
false
;
}
}
if
(Viewport.Width
>=
ViewportHost.Width)
//
已使用放大功能,向右拖动
{
if
((ViewportHost.Width)
<
(FocusRect.Width
+
FocusRectLeft))
{
if
(elementName
==
"
FocusRect
"
)
FocusRect.SetValue(Canvas.LeftProperty, ViewportHost.Width
-
FocusRect.Width
-
4
);
else
{
FocusRect.Width
=
ViewportHost.Width
-
FocusRectLeft
-
4
;
}
result
=
false
;
}
}
else
{
if
((Viewport.Width
+
ViewPortLeft)
<
(FocusRect.Width
+
FocusRectLeft))
{
if
(elementName
==
"
FocusRect
"
)
FocusRect.SetValue(Canvas.LeftProperty, ViewPortLeft
+
Viewport.Width
-
FocusRect.Width);
else
FocusRect.Width
=
ViewPortLeft
+
Viewport.Width
-
FocusRectLeft;
result
=
false
;
}
}
if
(Viewport.Height
>
ViewportHost.Height)
//
已使用放大功能,向下拖动
{
if
((ViewportHost.Height)
<
(FocusRect.Height
+
FocusRectTop))
{
if
(elementName
==
"
FocusRect
"
)
FocusRect.SetValue(Canvas.TopProperty, ViewportHost.Height
-
FocusRect.Height
-
4
);
else
FocusRect.Height
=
ViewportHost.Height
-
FocusRectTop
-
4
;
result
=
false
;
}
}
else
{
if
((Viewport.Height
+
ViewPortTop)
<
(FocusRect.Height
+
FocusRectTop))
{
if
(elementName
==
"
FocusRect
"
)
FocusRect.SetValue(Canvas.TopProperty, ViewPortTop
+
Viewport.Height
-
FocusRect.Height);
else
FocusRect.Height
=
ViewPortTop
+
Viewport.Height
-
FocusRectTop;
result
=
false
;
}
}
//
}
//
catch
//
{
//
result = false;
//
}
return
result;
}
#endregion
#region
smallRectangle 鼠标事件
void
smallRectangle_MouseLeftButtonUp(
object
sender, MouseButtonEventArgs e)
{
FrameworkElement element
=
sender
as
FrameworkElement;
trackingMouseMove
=
false
;
element.ReleaseMouseCapture();
prevLeftClick.X
=
prevLeftClick.Y
=
0
;
element.Cursor
=
null
;
if
(Viewport.Width
<
FocusRect.Width)
FocusRect.Width
=
Viewport.Width;
if
(Viewport.Height
<
FocusRect.Height)
FocusRect.Height
=
Viewport.Height;
AssureFocusRectMoveInZone(element.Name);
SetRectangles();
}
///
<summary>
///
鼠标按下事件
///
</summary>
///
<param name="sender"></param>
///
<param name="e"></param>
void
smallRectangle_MouseLeftButtonDown(
object
sender, MouseButtonEventArgs e)
{
FrameworkElement element
=
sender
as
FrameworkElement;
prevLeftClick
=
e.GetPosition(element);
trackingMouseMove
=
true
;
if
(
null
!=
element)
{
element.CaptureMouse();
element.Cursor
=
Cursors.Hand;
}
}
///
<summary>
///
SmallRect[]鼠标移动事件
///
</summary>
///
<param name="sender"></param>
///
<param name="e"></param>
void
smallRectangle_MouseMove(
object
sender, MouseEventArgs e)
{
if
(trackingMouseMove)
{
FrameworkElement element
=
sender
as
FrameworkElement;
double
offSetY
=
e.GetPosition(element).Y
-
prevLeftClick.Y;
double
offSetX
=
e.GetPosition(element).X
-
prevLeftClick.X;
if
(AssureFocusRectMoveInZone(element.Name))
{
switch
(
this
.CurrHitPlace)
{
case
HitDownSquare.HDS_TOP:
if
((FocusRect.Height
-
offSetY)
>
4
)
{
FocusRect.Height
=
FocusRect.Height
-
offSetY;
if
(FocusRect.Height
>
4
)
FocusRect.SetValue(Canvas.TopProperty, (
double
)FocusRect.GetValue(Canvas.TopProperty)
+
offSetY);
}
break
;
case
HitDownSquare.HDS_TOPLEFT:
if
((FocusRect.Height
-
offSetY)
>
4
)
{
FocusRect.Height
=
FocusRect.Height
-
offSetY;
if
(FocusRect.Height
>
4
)
FocusRect.SetValue(Canvas.TopProperty, (
double
)FocusRect.GetValue(Canvas.TopProperty)
+
offSetY);
}
if
((FocusRect.Width
-
offSetX)
>
4
)
{
FocusRect.Width
=
FocusRect.Width
-
offSetX;
if
(FocusRect.Width
>
4
)
FocusRect.SetValue(Canvas.LeftProperty, (
double
)FocusRect.GetValue(Canvas.LeftProperty)
+
offSetX);
}
break
;
case
HitDownSquare.HDS_TOPRIGHT:
if
((FocusRect.Height
-
offSetY)
>
4
)
{
FocusRect.Height
=
FocusRect.Height
-
offSetY;
if
(FocusRect.Height
>
4
)
FocusRect.SetValue(Canvas.TopProperty, (
double
)FocusRect.GetValue(Canvas.TopProperty)
+
offSetY);
}
if
((FocusRect.Width
+
offSetX)
>
4
)
FocusRect.Width
=
FocusRect.Width
+
offSetX;
break
;
case
HitDownSquare.HDS_RIGHT:
if
((FocusRect.Width
+
offSetX)
>
4
)
FocusRect.Width
=
FocusRect.Width
+
offSetX;
break
;
case
HitDownSquare.HDS_BOTTOM:
if
((FocusRect.Height
+
offSetY)
>
4
)
FocusRect.Height
=
FocusRect.Height
+
offSetY;
break
;
case
HitDownSquare.HDS_BOTTOMLEFT:
if
((FocusRect.Height
+
offSetY)
>
4
)
FocusRect.Height
=
FocusRect.Height
+
offSetY;
if
((FocusRect.Width
-
offSetX)
>
4
)
{
FocusRect.Width
=
FocusRect.Width
-
offSetX;
if
(FocusRect.Width
>
4
)
FocusRect.SetValue(Canvas.LeftProperty, (
double
)FocusRect.GetValue(Canvas.LeftProperty)
+
offSetX);
}
break
;
case
HitDownSquare.HDS_BOTTOMRIGHT:
if
((FocusRect.Height
+
offSetY)
>
4
)
FocusRect.Height
=
FocusRect.Height
+
offSetY;
if
((FocusRect.Width
+
offSetX)
>
4
)
FocusRect.Width
=
FocusRect.Width
+
offSetX;
break
;
case
HitDownSquare.HDS_LEFT:
if
((FocusRect.Width
-
offSetX)
>
4
)
{
FocusRect.Width
=
FocusRect.Width
-
offSetX;
if
(FocusRect.Width
>
4
)
FocusRect.SetValue(Canvas.LeftProperty, (
double
)FocusRect.GetValue(Canvas.LeftProperty)
+
offSetX);
}
break
;
case
HitDownSquare.HDS_NONE:
FocusRect.SetValue(Canvas.LeftProperty, (
double
)FocusRect.GetValue(Canvas.LeftProperty)
+
offSetX);
FocusRect.SetValue(Canvas.TopProperty, (
double
)FocusRect.GetValue(Canvas.TopProperty)
+
offSetY);
break
;
}
}
SetRectangles();
}
}
#endregion
#region
设置8个小正方形位置
///
<summary>
///
设置8个小正方形位置
///
</summary>
public
void
SetRectangles()
{
//
msgBox.Text = "FocusRect height: " + FocusRect.Height + " Width:" + FocusRect.Width + " Top:" + FocusRect.GetValue(Canvas.TopProperty) + " Left:" + FocusRect.GetValue(Canvas.LeftProperty);
//
左上
SmallRect[
0
].SetValue(Canvas.LeftProperty, (
double
)FocusRect.GetValue(Canvas.LeftProperty)
-
Square.Width
/
2
);
SmallRect[
0
].SetValue(Canvas.TopProperty, (
double
)FocusRect.GetValue(Canvas.TopProperty)
-
Square.Height
/
2
);
//
上中间
SmallRect[
4
].SetValue(Canvas.LeftProperty, (
double
)FocusRect.GetValue(Canvas.LeftProperty)
+
(FocusRect.Width
-
Square.Width)
/
2
);
SmallRect[
4
].SetValue(Canvas.TopProperty, (
double
)FocusRect.GetValue(Canvas.TopProperty)
-
Square.Height
/
2
);
//
右上
SmallRect[
1
].SetValue(Canvas.LeftProperty, (
double
)FocusRect.GetValue(Canvas.LeftProperty)
+
FocusRect.Width
-
Square.Width
/
2
);
SmallRect[
1
].SetValue(Canvas.TopProperty, (
double
)FocusRect.GetValue(Canvas.TopProperty)
-
Square.Height
/
2
);
//
左下
SmallRect[
2
].SetValue(Canvas.LeftProperty, (
double
)FocusRect.GetValue(Canvas.LeftProperty)
-
Square.Width
/
2
);
SmallRect[
2
].SetValue(Canvas.TopProperty, (
double
)FocusRect.GetValue(Canvas.TopProperty)
+
FocusRect.Height
-
Square.Height
/
2
);
//
下中间
SmallRect[
5
].SetValue(Canvas.LeftProperty, (
double
)FocusRect.GetValue(Canvas.LeftProperty)
+
(FocusRect.Width
-
Square.Width)
/
2
);
SmallRect[
5
].SetValue(Canvas.TopProperty, (
double
)FocusRect.GetValue(Canvas.TopProperty)
+
FocusRect.Height
-
Square.Height
/
2
);
//
右下
SmallRect[
3
].SetValue(Canvas.LeftProperty, (
double
)FocusRect.GetValue(Canvas.LeftProperty)
+
FocusRect.Width
-
Square.Height
/
2
);
SmallRect[
3
].SetValue(Canvas.TopProperty, (
double
)FocusRect.GetValue(Canvas.TopProperty)
+
FocusRect.Height
-
Square.Height
/
2
);
//
左中间
SmallRect[
6
].SetValue(Canvas.LeftProperty, (
double
)FocusRect.GetValue(Canvas.LeftProperty)
-
Square.Width
/
2
);
SmallRect[
6
].SetValue(Canvas.TopProperty, (
double
)FocusRect.GetValue(Canvas.TopProperty)
+
(FocusRect.Height
-
Square.Height)
/
2
);
//
右中间
SmallRect[
7
].SetValue(Canvas.LeftProperty, (
double
)FocusRect.GetValue(Canvas.LeftProperty)
+
FocusRect.Width
-
Square.Width
/
2
);
SmallRect[
7
].SetValue(Canvas.TopProperty, (
double
)FocusRect.GetValue(Canvas.TopProperty)
+
(FocusRect.Height
-
Square.Height)
/
2
);
}
#endregion
#region
设置鼠标Cursor和相应位置CurrHitPlace
void
smallRectangle_MouseEnter(
object
sender, MouseEventArgs e)
{
FrameworkElement element
=
sender
as
FrameworkElement;
Hit_Test(element, e.GetPosition(
null
));
}
///
<summary>
///
设置鼠标Cursor和相应位置CurrHitPlace
///
</summary>
///
<param name="element"></param>
///
<param name="point"></param>
///
<returns></returns>
public
bool
Hit_Test(FrameworkElement element, Point point)
{
switch
(element.Name)
{
case
"
SmallRect0
"
:
{
element.Cursor
=
Cursors.Hand;
//
.SizeNWSE;
CurrHitPlace
=
HitDownSquare.HDS_TOPLEFT;
break
;
}
case
"
SmallRect3
"
:
{
element.Cursor
=
Cursors.Hand;
//
.SizeNWSE;
CurrHitPlace
=
HitDownSquare.HDS_BOTTOMRIGHT;
break
;
}
case
"
SmallRect1
"
:
{
element.Cursor
=
Cursors.Hand;
//
.SizeNESW;
CurrHitPlace
=
HitDownSquare.HDS_TOPRIGHT;
break
;
}
case
"
SmallRect2
"
:
{
element.Cursor
=
Cursors.Hand;
//
.SizeNESW;
CurrHitPlace
=
HitDownSquare.HDS_BOTTOMLEFT;
break
;
}
case
"
SmallRect4
"
:
{
element.Cursor
=
Cursors.SizeNS;
CurrHitPlace
=
HitDownSquare.HDS_TOP;
break
;
}
case
"
SmallRect5
"
:
{
element.Cursor
=
Cursors.SizeNS;
CurrHitPlace
=
HitDownSquare.HDS_BOTTOM;
break
;
}
case
"
SmallRect6
"
:
{
element.Cursor
=
Cursors.SizeWE;
CurrHitPlace
=
HitDownSquare.HDS_LEFT;
break
;
}
case
"
SmallRect7
"
:
{
element.Cursor
=
Cursors.SizeWE;
CurrHitPlace
=
HitDownSquare.HDS_RIGHT;
break
;
}
default
:
{
FocusRect.Cursor
=
Cursors.Arrow;
CurrHitPlace
=
HitDownSquare.HDS_NONE;
break
;
}
}
return
true
;
}
#endregion
#region
滑动条事件处理代码
///
<summary>
///
滑动条事件处理代码
///
</summary>
///
<param name="sender"></param>
///
<param name="e"></param>
public
void
ViewportSlider_ValueChanged(
object
sender, RoutedPropertyChangedEventArgs
<
double
>
e)
{
Slider ZoomInOut
=
sender
as
Slider;
if
(ZoomInOut.Value
>=
ZoomInOut.Minimum
&&
imageRatio
*
ZoomInOut.Value
>=
ZoomInOut.Minimum)
{
Viewport.Width
=
ZoomInOut.Value;
Viewport.Height
=
imageRatio
*
ZoomInOut.Value;
Viewport.SetValue(Canvas.TopProperty, (
double
)ViewportHost.GetValue(Canvas.TopProperty)
+
(ViewportHost.Width
-
Viewport.Height)
/
2
);
Viewport.SetValue(Canvas.LeftProperty, (
double
)ViewportHost.GetValue(Canvas.LeftProperty)
+
(ViewportHost.Width
-
Viewport.Width)
/
2
);
AssureFocusRectZoomInZone(ZoomInOut.Value, ZoomInOut.Minimum);
}
}
#endregion
#region
加载图片流信息并设置宽高比例
///
<summary>
///
图片的高宽比
///
</summary>
private
double
imageRatio
=
1
;
///
<summary>
///
加载图片文件信息
///
</summary>
///
<param name="fileStream"></param>
public
void
LoadImageStream(FileStream fileStream, Slider zoomInOut)
{
double
width
=
ViewportHost.Width, height
=
ViewportHost.Height;
//
hack:获取相应的图片高宽信息
BitmapImage bitmapImage
=
new
BitmapImage();
bitmapImage.SetSource(fileStream);
zoomInOut.Maximum
=
bitmapImage.PixelWidth;
#region
用获取的图片高宽初始化Viewport,FocusRect区域和以slider
if
(bitmapImage.PixelWidth
<
bitmapImage.PixelHeight)
//
当图片宽小于高时
{
if
(bitmapImage.PixelWidth
>
width)
//
当图片宽度超过可视区域的宽度时
{
height
=
((
double
)width
/
bitmapImage.PixelWidth)
*
bitmapImage.PixelHeight;
//
zoomInOut.Value = (double)width / bitmapImage.PixelWidth;
}
else
//
未超过时则使用图片的高宽初始化显示区域
{
width
=
bitmapImage.PixelWidth;
height
=
bitmapImage.PixelHeight;
}
}
else
//
当图片高小于宽时
{
if
(bitmapImage.PixelHeight
>
height)
//
当图片高度超过可视区域的高度时
{
width
=
((
double
)height
/
bitmapImage.PixelHeight)
*
bitmapImage.PixelWidth;
//
zoomInOut.Value = (double)height / bitmapImage.PixelHeight;
}
else
//
未超过时则使用图片的高宽初始化显示区域
{
width
=
bitmapImage.PixelWidth;
height
=
bitmapImage.PixelHeight;
}
}
Viewport.Width
=
zoomInOut.Value
=
width;
Viewport.Height
=
height;
Viewport.SetValue(Canvas.TopProperty, (
double
)ViewportHost.GetValue(Canvas.TopProperty)
+
(ViewportHost.Height
-
Viewport.Height)
/
2
);
Viewport.SetValue(Canvas.LeftProperty, (
double
)ViewportHost.GetValue(Canvas.LeftProperty)
+
(ViewportHost.Width
-
Viewport.Width)
/
2
);
FocusRect.Width
=
width
>=
100
?
100
: width;
FocusRect.Height
=
height
>=
100
?
100
: height;
FocusRect.SetValue(Canvas.TopProperty, (
double
)ViewportHost.GetValue(Canvas.TopProperty)
+
(ViewportHost.Height
-
FocusRect.Height)
/
2
);
FocusRect.SetValue(Canvas.LeftProperty, (
double
)ViewportHost.GetValue(Canvas.LeftProperty)
+
(ViewportHost.Width
-
FocusRect.Width)
/
2
);
zoomInOut.Minimum
=
16
;
zoomInOut.ValueChanged
+=
new
RoutedPropertyChangedEventHandler
<
double
>
(ViewportSlider_ValueChanged);
imageRatio
=
(
double
)bitmapImage.PixelHeight
/
bitmapImage.PixelWidth;
SetRectangles();
#endregion
selectedImage.SetSource(fileStream);
}
#endregion
}
下面是鼠标右键菜单代码(位于ChildWindows/CWViewUploadedImage.xaml),采取动态加载控件方式来加载菜单项并绑定相应事件(如打印):
///
<summary>
///
初始化右键菜单
///
</summary>
void
InitPopMenu()
{
Border border
=
new
Border()
{
BorderBrush
=
new
SolidColorBrush(Color.FromArgb(
255
,
167
,
171
,
176
)),
CornerRadius
=
new
CornerRadius(
2
),
BorderThickness
=
new
Thickness(
1
),
Background
=
new
SolidColorBrush(Colors.White),
Effect
=
new
DropShadowEffect() { BlurRadius
=
3
, Color
=
Color.FromArgb(
255
,
230
,
227
,
236
) }
};
StackPanel stackPanel
=
new
StackPanel() { Orientation
=
Orientation.Vertical };
stackPanel.Children.Insert(
0
, AddMenuItem(
"
打印头像
"
,
"
images/print.png
"
, PrintButton_Click));
stackPanel.Children.Insert(
1
, AddMenuItem(
"
保存到本地
"
,
"
images/save.png
"
, DownLoadAvatar_Click));
border.Child
=
stackPanel;
popMenu.Child
=
border;
}
下面就是菜单项的样式绑定代码:
///
<summary>
///
加载菜单项
///
</summary>
///
<param name="menuName">
菜单名称
</param>
///
<param name="imageUrl">
图片
</param>
///
<param name="eventHandler">
处理事件
</param>
///
<returns></returns>
Grid AddMenuItem(
string
menuName,
string
imageUrl, RoutedEventHandler eventHandler)
{
Grid grid
=
new
Grid();
//
{ Margin = new Thickness(1) };
grid.ColumnDefinitions.Add(
new
ColumnDefinition() { Width
=
new
GridLength(
25
) });
grid.ColumnDefinitions.Add(
new
ColumnDefinition() { Width
=
new
GridLength(
80
) });
grid.Children.Add(
new
Rectangle() { Fill
=
new
SolidColorBrush(Color.FromArgb(
255
,
233
,
238
,
238
)) });
grid.Children.Add(
new
Rectangle() { Fill
=
new
SolidColorBrush(Color.FromArgb(
255
,
226
,
228
,
231
)), HorizontalAlignment
=
HorizontalAlignment.Right, Width
=
1
});
Button roButton
=
new
Button()
{
Height
=
22
,
Margin
=
new
Thickness(
0
,
0
,
0
,
0
),
HorizontalAlignment
=
HorizontalAlignment.Stretch,
VerticalAlignment
=
VerticalAlignment.Top,
HorizontalContentAlignment
=
HorizontalAlignment.Left,
Style
=
Application.Current.Resources[
"
ContextMenuButton
"
]
as
Style
};
roButton.Click
+=
eventHandler;
Grid.SetColumnSpan(roButton,
2
);
StackPanel sp
=
new
StackPanel() { Orientation
=
Orientation.Horizontal };
Image roImage
=
new
Image() { HorizontalAlignment
=
HorizontalAlignment.Left, Width
=
16
, Height
=
16
, Margin
=
new
Thickness(
1
,
0
,
0
,
0
) };
roImage.Source
=
new
BitmapImage(
new
Uri(
"
/HaoRan.WebCam;component/
"
+
imageUrl, UriKind.RelativeOrAbsolute));
sp.Children.Add(roImage);
sp.Children.Add(
new
TextBlock() { HorizontalAlignment
=
HorizontalAlignment.Left, Margin
=
new
Thickness(
16
,
0
,
0
,
0
), Text
=
menuName });
roButton.Content
=
sp;
grid.Children.Add(roButton);
return
grid;
}
接下来就是用户选择下载或打印的实现代码(里面的JpegHelper类是一个将WriteableBitmap转为jpeg图片的辅助类):
///
<summary>
///
保存到本地
///
</summary>
private
void
DownLoadAvatar_Click(
object
sender, RoutedEventArgs e)
{
if
(saveFileDlg.ShowDialog().Value)
{
using
(Stream dstStream
=
saveFileDlg.OpenFile())
{
try
{
Image image;
double
Size
=
FocusWidth
>
FocusHeight
?
FocusWidth : FocusHeight;
//
hack:将高宽转为size,这样就可以将ui元素中的内容保存到本地了
if
(popMenu.Tag.ToString()
==
"
LargeImageScrollViewer
"
)
image
=
new
Image() { Width
=
Size, Height
=
Size, Source
=
LargeImage.Source };
else
if
(popMenu.Tag.ToString()
==
"
MediumImageScrollViewer
"
)
image
=
new
Image() { Width
=
Size
*
0.8
, Height
=
Size
*
0.8
, Source
=
MediumImage.Source };
else
image
=
new
Image() { Width
=
Size
*
0.6
, Height
=
Size
*
0.6
, Source
=
SmallImage.Source };
WriteableBitmap bmp
=
new
WriteableBitmap(image,
null
);
JpegHelper.EncodeJpeg(bmp, dstStream);
}
catch
(Exception ex)
{
Utils.ShowMessageBox(
"
Error saving snapshot
"
, ex.Message);
}
}
}
}
下面是打印代码:
#region
打印代码
///
<summary>
///
点击打印按钮事件
///
</summary>
///
<param name="sender"></param>
///
<param name="e"></param>
private
void
PrintButton_Click(
object
sender, RoutedEventArgs e)
{
PrintDocument doc
=
new
PrintDocument() {};
//
doc.StartPrint += new EventHandler<StartPrintEventArgs>(doc_StartPrint);
doc.EndPrint
+=
OnEndPrint;
doc.PrintPage
+=
new
EventHandler
<
PrintPageEventArgs
>
(doc_PrintPage);
doc.Print(
"
打印头像
"
);
}
///
<summary>
///
打印处理代码
///
</summary>
///
<param name="sender"></param>
///
<param name="e"></param>
void
doc_PrintPage(
object
sender, PrintPageEventArgs e)
{
PrintImage.Height
=
FocusHeight;
PrintImage.Width
=
FocusWidth;
if
(popMenu.Tag.ToString()
==
"
MediumImageScrollViewer
"
)
{
PrintImage.Height
*=
0.8
;
PrintImage.Width
*=
0.8
;
}
else
if
(popMenu.Tag.ToString()
==
"
SmallImageScrollViewer
"
)
{
PrintImage.Height
*=
0.6
;
PrintImage.Width
*=
0.6
;
}
ImageInf.Text
=
"
头像类型:
"
+
popMenu.Tag.ToString().Replace(
"
ScrollViewer
"
,
""
)
+
"
宽:
"
+
PrintImage.Width
+
"
px 高:
"
+
PrintImage.Height
+
"
px
"
;
AppInf.Text
=
"
Product Details: HaoRan.WebCam Beta2
"
;
PrintArea.Width
=
e.PrintableArea.Width;
PrintArea.Height
=
e.PrintableArea.Height;
e.PageVisual
=
PrintArea;
//
指定是否再次调用另一个页
e.HasMorePages
=
false
;
}
Action
<
Exception
>
completedCallback
=
(ex)
=>
{
if
(ex
!=
null
)
{
Utils.ShowMessageBox(
"
打印错误
"
, ex.Message);
}
};
///
<summary>
///
打印结束事件
///
</summary>
///
<param name="sender"></param>
///
<param name="e"></param>
void
OnEndPrint(
object
sender, EndPrintEventArgs e)
{
if
(completedCallback
!=
null
)
{
completedCallback(e.Error);
}
}
void
pd_PrintPage(
object
sender, PrintPageEventArgs e)
{
throw
new
NotImplementedException();
}
#endregion
下面是使用Silverlight4摄像头的代码(WebCam.xaml.cs):
///
<summary>
///
WebCam页
///
</summary>
public
partial
class
WebCam : Page
{
///
<summary>
///
初始化视频捕捉设备
///
</summary>
private
CaptureSource captureSource
=
new
CaptureSource()
{
VideoCaptureDevice
=
CaptureDeviceConfiguration.GetDefaultVideoCaptureDevice(),
AudioCaptureDevice
=
CaptureDeviceConfiguration.GetDefaultAudioCaptureDevice()
};
///
<summary>
///
保存文件对话框
///
</summary>
private
SaveFileDialog saveFileDlg
=
new
SaveFileDialog
{
DefaultExt
=
"
.jpg
"
,
Filter
=
"
JPEG Images (*jpeg *.jpg)|*.jpeg;*.jpg
"
,
};
public
WebCam()
{
InitializeComponent();
this
.Loaded
+=
new
RoutedEventHandler(WebCam_Loaded);
}
void
WebCam_Loaded(
object
sender, RoutedEventArgs e)
{
BtnUploadImage.IsEnabled
=
BtnAdvanceMode.IsEnabled
=
false
;
BtnCapture.IsEnabled
=
goBack.IsEnabled
=
CaptureDeviceConfiguration.GetDefaultVideoCaptureDevice()
!=
null
;
}
protected
override
void
OnNavigatedTo(NavigationEventArgs e)
{}
///
<summary>
///
捕捉图像信息
///
</summary>
///
<param name="sender"></param>
///
<param name="e"></param>
private
void
BtnCapture_Click(
object
sender, RoutedEventArgs e)
{
try
{
//
开始捕捉
if
(captureSource.State
!=
CaptureState.Started)
{
captureSource.Stop();
//
创建 video brush 并填充到 rectangle
VideoBrush vidBrush
=
new
VideoBrush();
vidBrush.Stretch
=
Stretch.UniformToFill;
vidBrush.SetSource(captureSource);
focusRectangle.Viewport.Fill
=
vidBrush;
//
询问是否接入
if
(CaptureDeviceConfiguration.AllowedDeviceAccess
||
CaptureDeviceConfiguration.RequestDeviceAccess())
{
focusRectangle.Viewport.MaxHeight
=
focusRectangle.Viewport.MaxWidth
=
ZoomInOut.Maximum
=
400
;
ZoomInOut.Value
=
270
;
ZoomInOut.Minimum
=
16
;
ZoomInOut.ValueChanged
+=
new
RoutedPropertyChangedEventHandler
<
double
>
(focusRectangle.ViewportSlider_ValueChanged);
captureSource.Start();
BtnCapture.Text
=
"
打开摄像头
"
;
BtnUploadImage.IsEnabled
=
BtnAdvanceMode.IsEnabled
=
true
;
}
}
else
{
captureSource.Stop();
BtnCapture.Text
=
"
关闭摄像头
"
;
BtnUploadImage.IsEnabled
=
BtnAdvanceMode.IsEnabled
=
false
;
}
}
catch
(Exception ex)
{
Utils.ShowMessageBox(
"
Error using webcam
"
, ex.Message);
}
}
///
<summary>
///
上传头像
///
</summary>
///
<param name="sender"></param>
///
<param name="e"></param>
private
void
BtnUploadImage_Click(
object
sender, RoutedEventArgs e)
{
captureSource.Stop();
Utils.UploadUserFile(Utils.GetUserId()
+
"
.jpg
"
, focusRectangle.imageScroll, focusRectangle.FocusRect,
//
定制UserFile的PropertyChanged 属性,如BytesUploaded,Percentage,IsDeleted
new
System.ComponentModel.PropertyChangedEventHandler(FileRowControl_PropertyChanged));
}
///
<summary>
///
上传文件进度属性事件
///
</summary>
///
<param name="sender"></param>
///
<param name="e"></param>
void
FileRowControl_PropertyChanged(
object
sender, System.ComponentModel.PropertyChangedEventArgs e)
{
UserFile userFile
=
sender
as
UserFile;
if
(e.PropertyName
==
"
Percentage
"
)
{
Percentage.Value
=
userFile.Percentage;
Percentage.Visibility
=
Percentage.Value
==
100
?
Visibility.Collapsed : Visibility.Visible;
}
//
当前文件上传完毕
if
(userFile.State
==
Constants.FileStates.Finished)
{
CWViewUploadedImage cw
=
new
CWViewUploadedImage();
cw.Closed
+=
(o, eventArgs)
=>
{
if
(cw.DialogResult
==
true
)
//
确定并就隐藏当前sl应用窗口
NavPage.javaScriptableObject.OnCloseAvatar(
null
);
//
调用js端注册事件
//
Utils.ShowMessageBox("op: 确定并就隐藏当前sl应用窗口");
};
cw.LargeImageWidth.Text
=
focusRectangle.FocusRect.Width.ToString();
cw.LargeImageHeight.Text
=
focusRectangle.FocusRect.Height.ToString().ToString();
cw.Show();
captureSource.Start();
}
}
///
<summary>
///
返回上一页
///
</summary>
///
<param name="sender"></param>
///
<param name="e"></param>
private
void
goBack_Click(
object
sender, RoutedEventArgs e)
{
this
.NavigationService.GoBack();
}
#region
高级模式事件代码
///
<summary>
///
高级模式事件代码
///
</summary>
///
<param name="sender"></param>
///
<param name="e"></param>
private
void
BtnAdvanceMode_Click(
object
sender, RoutedEventArgs e)
{
captureSource.Stop();
Utils.UploadUserFile(Utils.GetUserId()
+
"
.jpg
"
, focusRectangle.imageScroll, focusRectangle.FocusRect,
(o, eventArgs)
=>
//
定制UserFile的PropertyChanged 属性,如BytesUploaded,Percentage,IsDeleted
{
UserFile userFile
=
o
as
UserFile;
if
(eventArgs.PropertyName
==
"
Percentage
"
)
{
Percentage.Value
=
userFile.Percentage;
Percentage.Visibility
=
Percentage.Value
==
100
?
Visibility.Collapsed : Visibility.Visible;
}
//
当前文件上传完毕
if
(userFile.State
==
Constants.FileStates.Finished)
this
.NavigationService.Navigate(
new
Uri(
string
.Format(
"
/AdvanceMode?focusWidth={0}&focusHeight={1}&fileName={2}
"
,
focusRectangle.FocusRect.Width,
focusRectangle.FocusRect.Height,
userFile.FileName),
UriKind.Relative));
});
}
#endregion
}
下面是涂鸦功能中的工具栏XMAL和实现代码,如下图:
InkMenu.xaml:
<
Canvas x:Name
=
"
LayoutRoot
"
Background
=
"
AliceBlue
"
>
<!--
InkPresenter Start
-->
<
StackPanel Margin
=
"
0,0,8,0
"
Canvas.Top
=
"
5
"
>
<
TextBlock FontSize
=
"
12
"
Name
=
"
stroke
"
>
边框色:
</
TextBlock
>
<
Slider Name
=
"
inkStrokeSlider
"
Minimum
=
"
0
"
Maximum
=
"
1
"
Width
=
"
100
"
Height
=
"
20
"
HorizontalAlignment
=
"
Left
"
Orientation
=
"
Horizontal
"
ValueChanged
=
"
inkStrokeSlider_ValueChanged
"
>
<
Slider.Background
>
<
LinearGradientBrush StartPoint
=
"
0,0
"
EndPoint
=
"
1,0
"
>
<
GradientStop Color
=
"
#FF000000
"
Offset
=
"
0
"
/>
<
GradientStop Color
=
"
#FFFF0000
"
Offset
=
"
0.143
"
/>
<
GradientStop Color
=
"
#FF00FF00
"
Offset
=
"
0.286
"
/>
<
GradientStop Color
=
"
#FF0000FF
"
Offset
=
"
0.429
"
/>
<
GradientStop Color
=
"
#FF00FFFF
"
Offset
=
"
0.571
"
/>
<
GradientStop Color
=
"
#FFFF00FF
"
Offset
=
"
0.714
"
/>
<
GradientStop Color
=
"
#FFFFFF00
"
Offset
=
"
0.857
"
/>
<
GradientStop Color
=
"
#FFFFFFFF
"
Offset
=
"
1
"
/>
</
LinearGradientBrush
>
</
Slider.Background
>
</
Slider
>
<
TextBlock FontSize
=
"
12
"
>
填充色:
</
TextBlock
>
<
Slider Name
=
"
inkFillSlider
"
Minimum
=
"
0
"
Maximum
=
"
1
"
Width
=
"
100
"
Height
=
"
20
"
HorizontalAlignment
=
"
Left
"
Orientation
=
"
Horizontal
"
ValueChanged
=
"
inkFillSlider_ValueChanged
"
>
<
Slider.Background
>
<
LinearGradientBrush StartPoint
=
"
0,0
"
EndPoint
=
"
1,0
"
>
<
GradientStop Color
=
"
#FF000000
"
Offset
=
"
0
"
/>
<
GradientStop Color
=
"
#FFFF0000
"
Offset
=
"
0.143
"
/>
<
GradientStop Color
=
"
#FF00FF00
"
Offset
=
"
0.286
"
/>
<
GradientStop Color
=
"
#FF0000FF
"
Offset
=
"
0.429
"
/>
<
GradientStop Color
=
"
#FF00FFFF
"
Offset
=
"
0.571
"
/>
<
GradientStop Color
=
"
#FFFF00FF
"
Offset
=
"
0.714
"
/>
<
GradientStop Color
=
"
#FFFFFF00
"
Offset
=
"
0.857
"
/>
<
GradientStop Color
=
"
#FFFFFFFF
"
Offset
=
"
1
"
/>
</
LinearGradientBrush
>
</
Slider.Background
>
</
Slider
>
<
TextBlock FontSize
=
"
12
"
>
边框:
</
TextBlock
>
<
Slider Name
=
"
inkThicknessSlider
"
Minimum
=
"
0
"
Maximum
=
"
1
"
Width
=
"
100
"
Height
=
"
20
"
HorizontalAlignment
=
"
Left
"
Orientation
=
"
Horizontal
"
ValueChanged
=
"
inkThicknessSlider_ValueChanged
"
/>
<
TextBlock FontSize
=
"
12
"
>
透明:
</
TextBlock
>
<
Slider Name
=
"
inkTransparencySlider
"
Minimum
=
"
0
"
Maximum
=
"
1
"
Width
=
"
100
"
Height
=
"
20
"
HorizontalAlignment
=
"
Left
"
Orientation
=
"
Horizontal
"
ValueChanged
=
"
inkTransparencySlider_ValueChanged
"
/>
<
TextBlock Canvas.Left
=
"
10
"
Canvas.Top
=
"
200
"
FontSize
=
"
12
"
>
预览:
</
TextBlock
>
<
InkPresenter x:Name
=
"
inkPreview
"
Canvas.Top
=
"
215
"
Canvas.Left
=
"
15
"
Width
=
"
100
"
Height
=
"
35
"
>
<
InkPresenter.Background
>
<
LinearGradientBrush StartPoint
=
"
0,0
"
EndPoint
=
"
1,0
"
>
<
GradientStop Color
=
"
Gray
"
Offset
=
"
0
"
/>
<
GradientStop Color
=
"
Snow
"
Offset
=
"
1
"
/>
</
LinearGradientBrush
>
</
InkPresenter.Background
>
<
InkPresenter.Strokes
>
<
StrokeCollection
>
<
Stroke
>
<
Stroke.DrawingAttributes
>
<
DrawingAttributes Color
=
"
Black
"
OutlineColor
=
"
Black
"
Height
=
"
5
"
Width
=
"
5
"
/>
</
Stroke.DrawingAttributes
>
<
Stroke.StylusPoints
>
<
StylusPointCollection
>
<
StylusPoint X
=
"
6.365068435668945
"
Y
=
"
13.124124526977539
"
/>
<
StylusPoint X
=
"
6.365068435668945
"
Y
=
"
13.124124526977539
"
/>
<
StylusPoint X
=
"
6.414070129394531
"
Y
=
"
13.76108169555664
"
/>
<
StylusPoint X
=
"
6.414070129394531
"
Y
=
"
13.76108169555664
"
/>
<
StylusPoint X
=
"
7.002099990844727
"
Y
=
"
14.153057098388671
"
/>
<
StylusPoint X
=
"
7.590129852294922
"
Y
=
"
14.104059219360351
"
/>
<
StylusPoint X
=
"
8.423171997070312
"
Y
=
"
13.859075546264648
"
/>
<
StylusPoint X
=
"
9.501224517822265
"
Y
=
"
13.46710205078125
"
/>
<
StylusPoint X
=
"
10.922296524047851
"
Y
=
"
12.830144882202148
"
/>
<
StylusPoint X
=
"
12.58837890625
"
Y
=
"
12.046195983886718
"
/>
<
StylusPoint X
=
"
14.401470184326171
"
Y
=
"
11.017265319824218
"
/>
<
StylusPoint X
=
"
16.41057014465332
"
Y
=
"
10.037330627441406
"
/>
<
StylusPoint X
=
"
18.41967010498047
"
Y
=
"
8.910406112670898
"
/>
<
StylusPoint X
=
"
20.526775360107422
"
Y
=
"
7.73448371887207
"
/>
<
StylusPoint X
=
"
22.437870025634765
"
Y
=
"
6.70555305480957
"
/>
<
StylusPoint X
=
"
24.299964904785156
"
Y
=
"
5.725618362426758
"
/>
<
StylusPoint X
=
"
25.770038604736328
"
Y
=
"
4.941671371459961
"
/>
<
StylusPoint X
=
"
25.770038604736328
"
Y
=
"
4.941671371459961
"
/>
<
StylusPoint X
=
"
27.19110870361328
"
Y
=
"
4.206720352172852
"
/>
<
StylusPoint X
=
"
28.171157836914062
"
Y
=
"
3.7167530059814453
"
/>
<
StylusPoint X
=
"
29.102203369140625
"
Y
=
"
3.2757816314697265
"
/>
<
StylusPoint X
=
"
29.690235137939453
"
Y
=
"
2.981801986694336
"
/>
<
StylusPoint X
=
"
29.690235137939453
"
Y
=
"
2.981801986694336
"
/>
<
StylusPoint X
=
"
30.278263092041015
"
Y
=
"
2.736818313598633
"
/>
<
StylusPoint X
=
"
30.278263092041015
"
Y
=
"
2.736818313598633
"
/>
<
StylusPoint X
=
"
30.278263092041015
"
Y
=
"
2.736818313598633
"
/>
<
StylusPoint X
=
"
30.033252716064453
"
Y
=
"
3.324777603149414
"
/>
<
StylusPoint X
=
"
29.837242126464843
"
Y
=
"
3.765748977661133
"
/>
<
StylusPoint X
=
"
29.298213958740234
"
Y
=
"
4.59869384765625
"
/>
<
StylusPoint X
=
"
28.75918960571289
"
Y
=
"
5.67662239074707
"
/>
<
StylusPoint X
=
"
27.975147247314453
"
Y
=
"
7.195520401000977
"
/>
<
StylusPoint X
=
"
27.2401123046875
"
Y
=
"
8.861410140991211
"
/>
<
StylusPoint X
=
"
26.35806655883789
"
Y
=
"
10.821279525756836
"
/>
<
StylusPoint X
=
"
25.5250244140625
"
Y
=
"
12.830144882202148
"
/>
<
StylusPoint X
=
"
24.789989471435547
"
Y
=
"
14.790014266967773
"
/>
<
StylusPoint X
=
"
24.201961517333984
"
Y
=
"
16.65188980102539
"
/>
<
StylusPoint X
=
"
23.858943939208984
"
Y
=
"
18.317779541015625
"
/>
<
StylusPoint X
=
"
23.809940338134765
"
Y
=
"
19.689685821533203
"
/>
<
StylusPoint X
=
"
24.103954315185547
"
Y
=
"
20.522632598876953
"
/>
<
StylusPoint X
=
"
24.740985870361328
"
Y
=
"
20.91460418701172
"
/>
<
StylusPoint X
=
"
25.770038604736328
"
Y
=
"
20.91460418701172
"
/>
<
StylusPoint X
=
"
27.28911590576172
"
Y
=
"
20.375640869140625
"
/>
<
StylusPoint X
=
"
29.200210571289062
"
Y
=
"
19.395706176757812
"
/>
<
StylusPoint X
=
"
29.200210571289062
"
Y
=
"
19.395706176757812
"
/>
<
StylusPoint X
=
"
31.356319427490234
"
Y
=
"
18.072795867919922
"
/>
<
StylusPoint X
=
"
33.70843505859375
"
Y
=
"
16.455902099609375
"
/>
<
StylusPoint X
=
"
36.20756149291992
"
Y
=
"
14.594026565551757
"
/>
<
StylusPoint X
=
"
38.75568771362305
"
Y
=
"
12.683155059814453
"
/>
<
StylusPoint X
=
"
41.15680694580078
"
Y
=
"
10.772281646728515
"
/>
<
StylusPoint X
=
"
41.15680694580078
"
Y
=
"
10.772281646728515
"
/>
<
StylusPoint X
=
"
43.410919189453125
"
Y
=
"
8.910406112670898
"
/>
<
StylusPoint X
=
"
45.273014068603516
"
Y
=
"
7.391508102416992
"
/>
<
StylusPoint X
=
"
46.74308776855469
"
Y
=
"
6.117591857910156
"
/>
<
StylusPoint X
=
"
47.82114028930664
"
Y
=
"
5.186655044555664
"
/>
<
StylusPoint X
=
"
48.55617904663086
"
Y
=
"
4.696687698364258
"
/>
<
StylusPoint X
=
"
48.55617904663086
"
Y
=
"
4.696687698364258
"
/>
<
StylusPoint X
=
"
48.55617904663086
"
Y
=
"
4.696687698364258
"
/>
<
StylusPoint X
=
"
48.55617904663086
"
Y
=
"
5.725618362426758
"
/>
<
StylusPoint X
=
"
47.91914749145508
"
Y
=
"
6.999532699584961
"
/>
<
StylusPoint X
=
"
47.08610534667969
"
Y
=
"
8.46943473815918
"
/>
<
StylusPoint X
=
"
46.05705261230469
"
Y
=
"
10.33131217956543
"
/>
<
StylusPoint X
=
"
44.979000091552734
"
Y
=
"
12.340177536010742
"
/>
<
StylusPoint X
=
"
44.979000091552734
"
Y
=
"
12.340177536010742
"
/>
<
StylusPoint X
=
"
43.85194396972656
"
Y
=
"
14.398040771484375
"
/>
<
StylusPoint X
=
"
42.82289123535156
"
Y
=
"
16.406906127929687
"
/>
<
StylusPoint X
=
"
42.82289123535156
"
Y
=
"
16.406906127929687
"
/>
<
StylusPoint X
=
"
41.94084548950195
"
Y
=
"
18.219783782958984
"
/>
<
StylusPoint X
=
"
41.30381393432617
"
Y
=
"
19.88567352294922
"
/>
<
StylusPoint X
=
"
41.30381393432617
"
Y
=
"
19.88567352294922
"
/>
<
StylusPoint X
=
"
40.91179656982422
"
Y
=
"
21.159587860107422
"
/>
<
StylusPoint X
=
"
40.86279296875
"
Y
=
"
22.139522552490234
"
/>
<
StylusPoint X
=
"
41.15680694580078
"
Y
=
"
22.62948989868164
"
/>
<
StylusPoint X
=
"
41.74483871459961
"
Y
=
"
22.72748565673828
"
/>
<
StylusPoint X
=
"
42.67588424682617
"
Y
=
"
22.33551025390625
"
/>
<
StylusPoint X
=
"
43.85194396972656
"
Y
=
"
21.60055923461914
"
/>
<
StylusPoint X
=
"
45.37101745605469
"
Y
=
"
20.620624542236328
"
/>
<
StylusPoint X
=
"
47.03710174560547
"
Y
=
"
19.297714233398437
"
/>
<
StylusPoint X
=
"
48.85019302368164
"
Y
=
"
17.82781219482422
"
/>
<
StylusPoint X
=
"
50.71228790283203
"
Y
=
"
16.161922454833984
"
/>
<
StylusPoint X
=
"
52.574378967285156
"
Y
=
"
14.54503059387207
"
/>
<
StylusPoint X
=
"
54.43647003173828
"
Y
=
"
12.928138732910156
"
/>
<
StylusPoint X
=
"
56.2005615234375
"
Y
=
"
11.605226516723632
"
/>
<
StylusPoint X
=
"
56.2005615234375
"
Y
=
"
11.605226516723632
"
/>
<
StylusPoint X
=
"
57.81764221191406
"
Y
=
"
10.380308151245117
"
/>
<
StylusPoint X
=
"
59.140708923339844
"
Y
=
"
9.449369430541992
"
/>
<
StylusPoint X
=
"
60.21875762939453
"
Y
=
"
8.763416290283203
"
/>
<
StylusPoint X
=
"
61.100807189941406
"
Y
=
"
8.371442794799804
"
/>
<
StylusPoint X
=
"
61.73783874511719
"
Y
=
"
8.371442794799804
"
/>
<
StylusPoint X
=
"
61.73783874511719
"
Y
=
"
8.371442794799804
"
/>
<
StylusPoint X
=
"
62.22785949707031
"
Y
=
"
9.498367309570312
"
/>
<
StylusPoint X
=
"
62.08085632324219
"
Y
=
"
10.62529182434082
"
/>
<
StylusPoint X
=
"
61.68883514404297
"
Y
=
"
12.242183685302734
"
/>
<
StylusPoint X
=
"
61.100807189941406
"
Y
=
"
14.251049041748046
"
/>
<
StylusPoint X
=
"
60.36576843261719
"
Y
=
"
16.602893829345703
"
/>
<
StylusPoint X
=
"
59.53273010253906
"
Y
=
"
19.15072250366211
"
/>
<
StylusPoint X
=
"
58.65068054199219
"
Y
=
"
21.74755096435547
"
/>
<
StylusPoint X
=
"
57.81764221191406
"
Y
=
"
24.246383666992187
"
/>
<
StylusPoint X
=
"
57.082603454589844
"
Y
=
"
26.69622039794922
"
/>
<
StylusPoint X
=
"
56.5435791015625
"
Y
=
"
28.75408172607422
"
/>
<
StylusPoint X
=
"
56.29856872558594
"
Y
=
"
30.419971466064453
"
/>
<
StylusPoint X
=
"
56.347564697265625
"
Y
=
"
31.497901916503906
"
/>
<
StylusPoint X
=
"
56.78858947753906
"
Y
=
"
31.93886947631836
"
/>
<
StylusPoint X
=
"
57.5726318359375
"
Y
=
"
31.791881561279297
"
/>
<
StylusPoint X
=
"
58.797691345214844
"
Y
=
"
31.20391845703125
"
/>
<
StylusPoint X
=
"
60.36576843261719
"
Y
=
"
30.17498779296875
"
/>
<
StylusPoint X
=
"
62.42387390136719
"
Y
=
"
28.70508575439453
"
/>
<
StylusPoint X
=
"
64.62898254394531
"
Y
=
"
27.039196014404297
"
/>
<
StylusPoint X
=
"
66.9811019897461
"
Y
=
"
25.079326629638672
"
/>
<
StylusPoint X
=
"
69.43122100830078
"
Y
=
"
23.119457244873047
"
/>
<
StylusPoint X
=
"
71.83234405517578
"
Y
=
"
21.257583618164062
"
/>
<
StylusPoint X
=
"
74.18445587158203
"
Y
=
"
19.54269790649414
"
/>
<
StylusPoint X
=
"
76.38957214355469
"
Y
=
"
18.072795867919922
"
/>
<
StylusPoint X
=
"
78.34967041015625
"
Y
=
"
16.847877502441406
"
/>
<
StylusPoint X
=
"
78.34967041015625
"
Y
=
"
16.847877502441406
"
/>
<
StylusPoint X
=
"
79.96675109863281
"
Y
=
"
15.916938781738281
"
/>
<
StylusPoint X
=
"
81.33881378173828
"
Y
=
"
15.27998161315918
"
/>
<
StylusPoint X
=
"
82.36786651611328
"
Y
=
"
14.986000061035156
"
/>
<
StylusPoint X
=
"
83.15190887451172
"
Y
=
"
15.083993911743164
"
/>
<
StylusPoint X
=
"
83.64192962646484
"
Y
=
"
15.57396125793457
"
/>
<
StylusPoint X
=
"
83.7889404296875
"
Y
=
"
16.504899978637695
"
/>
<
StylusPoint X
=
"
83.49492645263672
"
Y
=
"
17.77881622314453
"
/>
<
StylusPoint X
=
"
83.00489807128906
"
Y
=
"
19.4447021484375
"
/>
<
StylusPoint X
=
"
82.31886291503906
"
Y
=
"
21.208587646484375
"
/>
<
StylusPoint X
=
"
81.53482818603515
"
Y
=
"
23.16845703125
"
/>
<
StylusPoint X
=
"
80.75078582763672
"
Y
=
"
25.030330657958984
"
/>
<
StylusPoint X
=
"
79.96675109863281
"
Y
=
"
26.843212127685547
"
/>
</
StylusPointCollection
>
</
Stroke.StylusPoints
>
</
Stroke
>
</
StrokeCollection
>
</
InkPresenter.Strokes
>
</
InkPresenter
>
<
CheckBox Name
=
"
Erase
"
Content
=
"
橡皮擦
"
ToolTipService.ToolTip
=
"
选中后可擦除指定画笔
"
/>
<!--
InkPresenter End
-->
</
StackPanel
>
</
Canvas
>
InkMenu.xaml.cs:
public
partial
class
InkMenu : UserControl
{
public
InkMenu()
{
InitializeComponent();
this
.Loaded
+=
new
RoutedEventHandler(InkMenu_Loaded);
}
void
InkMenu_Loaded(
object
sender, RoutedEventArgs e)
{
inkAttributes
=
inkPreview.Strokes[
0
].DrawingAttributes;
inkAttributes.Color
=
GetColor(inkFillSlider.Value);
inkAttributes.OutlineColor
=
GetColor(inkStrokeSlider.Value);
inkAttributes.Width
=
inkAttributes.Height
=
inkThicknessSlider.Value
*
10d;
}
#region
橡皮擦点击事件
///
<summary>
///
橡皮擦点击事件
///
</summary>
public
event
RoutedEventHandler Click
{
add
{
Erase.Click
+=
value;
}
remove
{
Erase.Click
-=
value;
}
}
#endregion
#region
获取颜色值
public
DrawingAttributes inkAttributes;
void
inkStrokeSlider_ValueChanged(
object
sender, EventArgs e)
{
byte
alpha
=
inkAttributes.OutlineColor.A;
inkAttributes.Color
=
GetColor(inkStrokeSlider.Value, alpha);
}
void
inkFillSlider_ValueChanged(
object
sender, EventArgs e)
{
byte
alpha
=
inkAttributes.Color.A;
inkAttributes.Color
=
GetColor(inkFillSlider.Value, alpha);
}
void
inkThicknessSlider_ValueChanged(
object
sender, EventArgs e)
{
inkAttributes.Width
=
inkThicknessSlider.Value
*
10d;
inkAttributes.Height
=
inkThicknessSlider.Value
*
10d;
}
void
inkTransparencySlider_ValueChanged(
object
sender, EventArgs e)
{
Color color
=
inkAttributes.Color;
Color outlineColor
=
inkAttributes.OutlineColor;
inkAttributes.Color
=
Color.FromArgb((
byte
)Math.Floor(256d
*
(1d
-
inkTransparencySlider.Value)), color.R, color.G, color.B);
inkAttributes.OutlineColor
=
Color.FromArgb((
byte
)Math.Floor(256d
*
(1d
-
inkTransparencySlider.Value)), outlineColor.R, outlineColor.G, outlineColor.B);
}
///
<summary>
///
获取颜色值
///
</summary>
///
<returns></returns>
public
Color GetColor(
double
value)
{
return
this
.GetColor(value,
255
);
}
///
<summary>
///
将滑动条值(Value)转换为ARGB 颜色值并返回
///
</summary>
///
<param name="alpha">
alpha通道,该值介于0到255
</param>
///
<returns>
ARGB 颜色值
</returns>
private
Color GetColor(
double
value,
byte
alpha)
{
Color color;
//
将滑动条的值转换为 ARGB 颜色值
if
(value
<
0.143d
)
{
color
=
Color.FromArgb(alpha, (
byte
)Math.Floor((value
*
256d)
/
0.143d
),
0
,
0
);
}
else
if
(value
<
0.286d
)
{
color
=
Color.FromArgb(alpha, (
byte
)Math.Floor(256d
*
(
0.286d
-
value)
/
0.143d
), (
byte
)Math.Floor(256d
*
(value
-
0.143d
)
/
0.143d
),
0
);
}
else
if
(value
<
0.429
)
{
color
=
Color.FromArgb(alpha,
0
, (
byte
)Math.Floor(256d
*
(
0.429d
-
value)
/
0.143d
), (
byte
)Math.Floor(256d
*
(value
-
0.286d
)
/
0.143d
));
}
else
if
(value
<
0.571
)
{
color
=
Color.FromArgb(alpha,
0
, (
byte
)Math.Floor(256d
*
(value
-
0.429d
)
/
0.143d
),
255
);
}
else
if
(value
<
0.714
)
{
color
=
Color.FromArgb(alpha, (
byte
)Math.Floor(256d
*
(value
-
0.571d
)
/
0.143d
), (
byte
)Math.Floor(256d
*
(
0.714d
-
value)
/
0.143d
),
255
);
}
else
if
(value
<
0.857
)
{
color
=
Color.FromArgb(alpha,
255
, (
byte
)Math.Floor(256d
*
(value
-
0.714d
)
/
0.143d
), (
byte
)Math.Floor(256d
*
(
0.857d
-
value)
/
0.143d
));
}
else
{
color
=
Color.FromArgb(alpha,
255
,
255
, (
byte
)Math.Floor(256d
*
(value
-
0.857d
)
/
0.143d
));
}
return
color;
}
#endregion
}
另外涂鸭的底层实现代码位于AdvanceMode.xaml.cs中:
#region
Ink 事件代码
///
<summary>
///
Ink 事件代码
///
</summary>
public
enum
InkEditingMode
{
None,
Ink,
Erase
}
///
<summary>
///
InkEditingMode模式,默认为Ink
///
</summary>
private
InkEditingMode editingMode
=
InkEditingMode.Ink;
private
Stroke inkStroke
=
null
;
private
StylusPointCollection erasePoints
=
null
;
void
onInkPresenterDown(
object
sender, MouseButtonEventArgs e)
{
if
(editingMode
==
InkEditingMode.None)
return
;
(sender
as
FrameworkElement).CaptureMouse();
StylusPointCollection stylusPoints
=
e.StylusDevice.GetStylusPoints(InkCanvas);
if
(editingMode
==
InkEditingMode.Erase)
{
erasePoints
=
new
StylusPointCollection();
erasePoints.Add(stylusPoints);
}
else
if
(editingMode
==
InkEditingMode.Ink)
{
inkStroke
=
new
Stroke();
inkStroke.StylusPoints.Add(stylusPoints);
inkStroke.DrawingAttributes
=
new
DrawingAttributes();
inkStroke.DrawingAttributes.Color
=
inkMenu.inkAttributes.Color;
inkStroke.DrawingAttributes.OutlineColor
=
inkMenu.inkAttributes.OutlineColor;
inkStroke.DrawingAttributes.Width
=
inkMenu.inkAttributes.Width;
inkStroke.DrawingAttributes.Height
=
inkMenu.inkAttributes.Height;
InkCanvas.Strokes.Add(inkStroke);
}
}
void
SetEditingMode()
{
if
(EditInkMode.IsChecked
==
true
)
{
if
(inkMenu.Erase.IsChecked
==
false
)
editingMode
=
InkEditingMode.Ink;
else
editingMode
=
InkEditingMode.Erase;
}
else
editingMode
=
InkEditingMode.None;
}
void
onInkPresenterMove(
object
sender, MouseEventArgs e)
{
SetEditingMode();
if
(editingMode
==
InkEditingMode.None)
return
;
StylusPointCollection stylusPoints
=
e.StylusDevice.GetStylusPoints(InkCanvas);
if
(editingMode
==
InkEditingMode.Erase)
{
if
(erasePoints
!=
null
)
{
//
hittest and erase
erasePoints.Add(stylusPoints);
StrokeCollection hitStrokes
=
InkCanvas.Strokes.HitTest(erasePoints);
for
(
int
i
=
0
; i
<
hitStrokes.Count; i
++
)
{
InkCanvas.Strokes.Remove(hitStrokes[i]);
}
}
}
else
if
(editingMode
==
InkEditingMode.Ink)
{
if
(inkStroke
!=
null
)
{
inkStroke.StylusPoints.Add(stylusPoints);
}
}
}
void
onInkPresenterEnter(
object
sender, MouseButtonEventArgs e)
{
if
(EditInkMode.IsChecked
==
true
)
{
if
(inkMenu.Erase.IsChecked
==
false
)
editingMode
=
InkEditingMode.Ink;
else
editingMode
=
InkEditingMode.Erase;
}
else
editingMode
=
InkEditingMode.None;
erasePoints
=
null
;
inkStroke
=
null
;
}
void
onInkPresenterUp(
object
sender, MouseButtonEventArgs e)
{
if
(editingMode
==
InkEditingMode.None)
return
;
if
(inkStroke
!=
null
)
{
inkStroke.StylusPoints.Add(e.StylusDevice.GetStylusPoints(InkCanvas));
}
(sender
as
FrameworkElement).ReleaseMouseCapture();
erasePoints
=
null
;
inkStroke
=
null
;
}
private
void
EditInkMode_Click(
object
sender, RoutedEventArgs e)
{
if
(EditInkMode.IsChecked
==
true
)
{
inkMenu.Visibility
=
System.Windows.Visibility.Visible;
if
(inkMenu.Erase.IsChecked
==
false
)
editingMode
=
InkEditingMode.Ink;
else
editingMode
=
InkEditingMode.Erase;
}
else
{
inkMenu.Visibility
=
System.Windows.Visibility.Collapsed;
editingMode
=
InkEditingMode.None;
}
}
private
void
Erase_Click(
object
sender, RoutedEventArgs e)
{
inkMenu.Visibility
=
System.Windows.Visibility.Visible;
if
(inkMenu.Erase.IsChecked
==
false
)
editingMode
=
InkEditingMode.Ink;
else
editingMode
=
InkEditingMode.Erase;
}
#endregion
当然就目前产品代码的结构而言还不够优化,特别是重复的代码段还有一些,不过不影响大家的最终使用,鉴于目前本人的经历和时间有限,所以就把它开源出来,大家如果感兴趣可以在其基础上加入更新的功能来完善它,呵呵。
好了,今天的内容就先到这里了, 源码下载链接,请点击这里
。
相关链接:
目前为止功能最全的基于silverlight4(beta)的摄像头应用
基于silverlight4(beta)的摄像头应用(Beta2)发布
原文链接: http://www.cnblogs.com/daizhj/archive/2010/08/31/1813437.html
作者: daizhj, 代震军
Tags: silverlight,webcam
网址: http://daizhj.cnblogs.com/
相关文章推荐
- 基于silverlight4(beta)的摄像头应用(Beta2)发布
- 基于silverlight4(beta)的摄像头应用(Beta2)发布
- 基于silverlight4(beta)的摄像头应用(Beta2)发布
- 基于silverlight4(beta)的摄像头应用(Beta2)发布
- 目前为止功能最全的基于silverlight4(beta)的摄像头应用
- 目前为止功能最全的基于silverlight4(beta)的摄像头应用
- 目前为止功能最全的基于silverlight4(beta)的摄像头应用
- 基于Bmob的Android即时通讯应用源码
- Android应用源码基于安卓的个人隐私监控项目
- Android应用源码基于vitamio的网络电视直播源码
- 【双旦献礼】Portal-Basic Java Web 应用开发框架 v3.0.1 正式发布(源码、示例及文档)
- 基于三层架构的MVC模式应用示例源码
- 基于S3C2440的USB摄像头应用简单实现之摄像头初始化(三)
- 放大招了!基于Bmob的Android即时通讯应用源码[升级版]
- 基于ZedBoard的Webcam设计(一):USB摄像头(V4L2接口)的图片采集
- 源码-基于V4L2的UVC摄像头捕获并用framebuffer显示的示例程序
- 基于ios开发点餐系统应用(附带源码)
- 基于ZedBoard的Webcam设计(一):USB摄像头(V4L2接口)的图片采集
- 基于JSPatch的iOS应用线上Bug的即时修复方案,附源码.
- 基于S3C2440的USB摄像头应用简单实现之LCD初始化(二)