这种应用现在已经比较常见了,比如论坛回贴中的手写功能 ,IM聊天中的个性化手写文字,个性签名等,在Silverlight中要实现该功能其实非常简单,只要一个InkPresenter控件即可
使用要点:
1.要合理设置裁剪区,否则手写时可能笔划会写到你不希望出现的地方.
2.处理好MouseLeftButtonDown,MouseMove,LostMouseCapture这三个事件.
演示代码:
前端Xaml部分:
by 菩提树下的杨过 http://yjmyzz.cnblogs.com/
<
UserControl
x:Class
="InkPresenterTest.Page"
xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d ="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc ="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable ="d" Background ="Black"
>
< Grid Background ="#FF0BB5A3" Width ="650" Height ="615" >
< Grid.RowDefinitions >
< RowDefinition Height ="25" ></ RowDefinition >
< RowDefinition Height ="30" ></ RowDefinition >
< RowDefinition ></ RowDefinition >
< RowDefinition Height ="30" ></ RowDefinition >
< RowDefinition Height ="150" ></ RowDefinition >
</ Grid.RowDefinitions >
< TextBlock x:Name ="txtTitle" Text ="InkPresenter 演 示" FontWeight ="Bold" Grid.Row ="0" HorizontalAlignment ="Center" Height ="20" VerticalAlignment ="Center" Foreground ="White" />
< StackPanel x:Name ="spToolBar" Grid.Row ="1" Orientation ="Horizontal" HorizontalAlignment ="Center" Height ="25" VerticalAlignment ="Center" >
< TextBlock Text ="笔划颜色:" VerticalAlignment ="Center" ></ TextBlock >
< ComboBox x:Name ="cboColor" Width ="65" VerticalAlignment ="Center" >
< ComboBox.ItemTemplate >
< DataTemplate >
< StackPanel Orientation ="Horizontal" >
< Rectangle Fill ="{Binding Color}" ToolTipService.ToolTip ="{Binding Name}" Width ="10" Height ="10" />
< TextBlock Text ="{Binding Name}" Margin ="2,0,0,0" Foreground ="{Binding Color}" ></ TextBlock >
</ StackPanel >
</ DataTemplate >
</ ComboBox.ItemTemplate >
</ ComboBox >
< TextBlock Text ="笔划外框颜色:" VerticalAlignment ="Center" Margin ="10,0,0,0" ></ TextBlock >
< ComboBox x:Name ="cboOutlineColor" Width ="65" VerticalAlignment ="Center" >
< ComboBox.ItemTemplate >
< DataTemplate >
< StackPanel Orientation ="Horizontal" >
< Rectangle Fill ="{Binding Color}" ToolTipService.ToolTip ="{Binding Name}" Width ="10" Height ="10" />
< TextBlock Text ="{Binding Name}" Margin ="2,0,0,0" Foreground ="{Binding Color}" ></ TextBlock >
</ StackPanel >
</ DataTemplate >
</ ComboBox.ItemTemplate >
</ ComboBox >
< TextBlock Text ="笔划宽度:" Margin ="10,0,0,0" VerticalAlignment ="Center" ></ TextBlock >
< ComboBox x:Name ="cboWidth" Width ="60" VerticalAlignment ="Center" Height ="20" >
< ComboBox.ItemTemplate >
< DataTemplate >
< Rectangle Fill ="Black" Width ="40" Height ="{Binding Size}" />
</ DataTemplate >
</ ComboBox.ItemTemplate >
</ ComboBox >
< TextBlock Text ="笔划高度:" Margin ="10,0,0,0" VerticalAlignment ="Center" ></ TextBlock >
< ComboBox x:Name ="cboHeight" Width ="60" VerticalAlignment ="Center" Height ="20" >
< ComboBox.ItemTemplate >
< DataTemplate >
< Rectangle Fill ="Black" Width ="40" Height ="{Binding Size}" />
</ DataTemplate >
</ ComboBox.ItemTemplate >
</ ComboBox >
< TextBlock Text ="透明度:" Margin ="10,0,0,0" VerticalAlignment ="Center" ></ TextBlock >
< ComboBox x:Name ="cboOpactiy" Width ="60" VerticalAlignment ="Center" SelectionChanged ="cboOpactiy_SelectionChanged" >
< ComboBox.ItemTemplate >
< DataTemplate >
< StackPanel Orientation ="Horizontal" >
< TextBlock Text ="{Binding Value}" Opacity ="{Binding Value}" ></ TextBlock >
</ StackPanel >
</ DataTemplate >
</ ComboBox.ItemTemplate >
</ ComboBox >
</ StackPanel >
< Canvas x:Name ="inkC" Grid.Row ="2" Height ="370" >
< Rectangle x:Name ="rectBg" Grid.Row ="2" Width ="650" Height ="370" Fill ="#FFECD85C" Margin ="0" StrokeThickness ="0" ></ Rectangle >
< Image Source ="image/background.png" Stretch ="UniformToFill" x:Name ="imgBg" ></ Image >
< InkPresenter x:Name ="ink" Height ="370" Width ="650" Grid.Row ="2"
Background ="Transparent" Opacity ="1"
MouseLeftButtonDown ="OnMouseLeftButtonDown"
MouseMove ="OnMouseMove"
LostMouseCapture ="OnLostMouseCapture" Margin ="0"
>
< InkPresenter.Clip >
< RectangleGeometry Rect ="0,0,650,370" ></ RectangleGeometry >
</ InkPresenter.Clip >
</ InkPresenter >
< TextBlock Text ="by 菩提树下的杨过" MouseLeftButtonDown ="TextBlock_MouseLeftButtonDown" Cursor ="Hand" Canvas.Left ="5" Canvas.Top ="5" Foreground ="LightGray" ></ TextBlock >
</ Canvas >
< StackPanel x:Name ="spBtn" Grid.Row ="3" Height ="30" Margin ="0" Orientation ="Horizontal" VerticalAlignment ="Center" HorizontalAlignment ="Center" >
< Button x:Name ="btnToogleBg" HorizontalAlignment ="Center" Width ="80" Content ="隐藏背景图" VerticalAlignment ="Center" Click ="btnToogleBg_Click" />
< Button x:Name ="btnToogleBgRect" HorizontalAlignment ="Center" Width ="80" Content ="隐藏背景色" VerticalAlignment ="Center" Click ="btnToogleBgRect_Click" Margin ="10,0,0,0" />
< Button x:Name ="btnSave" HorizontalAlignment ="Center" Width ="80" Content ="保存图片" VerticalAlignment ="Center" Margin ="10,0,0,0" Click ="btnSave_Click" />
< Button x:Name ="btnSaveLocal" HorizontalAlignment ="Center" Width ="90" Content ="保存图片到本地" VerticalAlignment ="Center" Margin ="10,0,0,0" Click ="btnSaveLocal_Click" />
< Button x:Name ="btnClear" HorizontalAlignment ="Center" Width ="80" Content ="清空画版" VerticalAlignment ="Center" Margin ="10,0,0,0" Click ="btnClear_Click" />
< Button x:Name ="btnClearSave" HorizontalAlignment ="Center" Width ="80" Content ="清空保存区" VerticalAlignment ="Center" Margin ="10,0,0,0" Click ="btnClearSave_Click" />
</ StackPanel >
< ScrollViewer x:Name ="ScreenshotViewer" Margin ="0" Grid.Row ="4" Background ="#FFFFFF99" HorizontalScrollBarVisibility ="Auto" VerticalScrollBarVisibility ="Hidden" >
< StackPanel x:Name ="thumbs" Orientation ="Horizontal" />
</ ScrollViewer >
</ Grid >
</ UserControl >
xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d ="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc ="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable ="d" Background ="Black"
>
< Grid Background ="#FF0BB5A3" Width ="650" Height ="615" >
< Grid.RowDefinitions >
< RowDefinition Height ="25" ></ RowDefinition >
< RowDefinition Height ="30" ></ RowDefinition >
< RowDefinition ></ RowDefinition >
< RowDefinition Height ="30" ></ RowDefinition >
< RowDefinition Height ="150" ></ RowDefinition >
</ Grid.RowDefinitions >
< TextBlock x:Name ="txtTitle" Text ="InkPresenter 演 示" FontWeight ="Bold" Grid.Row ="0" HorizontalAlignment ="Center" Height ="20" VerticalAlignment ="Center" Foreground ="White" />
< StackPanel x:Name ="spToolBar" Grid.Row ="1" Orientation ="Horizontal" HorizontalAlignment ="Center" Height ="25" VerticalAlignment ="Center" >
< TextBlock Text ="笔划颜色:" VerticalAlignment ="Center" ></ TextBlock >
< ComboBox x:Name ="cboColor" Width ="65" VerticalAlignment ="Center" >
< ComboBox.ItemTemplate >
< DataTemplate >
< StackPanel Orientation ="Horizontal" >
< Rectangle Fill ="{Binding Color}" ToolTipService.ToolTip ="{Binding Name}" Width ="10" Height ="10" />
< TextBlock Text ="{Binding Name}" Margin ="2,0,0,0" Foreground ="{Binding Color}" ></ TextBlock >
</ StackPanel >
</ DataTemplate >
</ ComboBox.ItemTemplate >
</ ComboBox >
< TextBlock Text ="笔划外框颜色:" VerticalAlignment ="Center" Margin ="10,0,0,0" ></ TextBlock >
< ComboBox x:Name ="cboOutlineColor" Width ="65" VerticalAlignment ="Center" >
< ComboBox.ItemTemplate >
< DataTemplate >
< StackPanel Orientation ="Horizontal" >
< Rectangle Fill ="{Binding Color}" ToolTipService.ToolTip ="{Binding Name}" Width ="10" Height ="10" />
< TextBlock Text ="{Binding Name}" Margin ="2,0,0,0" Foreground ="{Binding Color}" ></ TextBlock >
</ StackPanel >
</ DataTemplate >
</ ComboBox.ItemTemplate >
</ ComboBox >
< TextBlock Text ="笔划宽度:" Margin ="10,0,0,0" VerticalAlignment ="Center" ></ TextBlock >
< ComboBox x:Name ="cboWidth" Width ="60" VerticalAlignment ="Center" Height ="20" >
< ComboBox.ItemTemplate >
< DataTemplate >
< Rectangle Fill ="Black" Width ="40" Height ="{Binding Size}" />
</ DataTemplate >
</ ComboBox.ItemTemplate >
</ ComboBox >
< TextBlock Text ="笔划高度:" Margin ="10,0,0,0" VerticalAlignment ="Center" ></ TextBlock >
< ComboBox x:Name ="cboHeight" Width ="60" VerticalAlignment ="Center" Height ="20" >
< ComboBox.ItemTemplate >
< DataTemplate >
< Rectangle Fill ="Black" Width ="40" Height ="{Binding Size}" />
</ DataTemplate >
</ ComboBox.ItemTemplate >
</ ComboBox >
< TextBlock Text ="透明度:" Margin ="10,0,0,0" VerticalAlignment ="Center" ></ TextBlock >
< ComboBox x:Name ="cboOpactiy" Width ="60" VerticalAlignment ="Center" SelectionChanged ="cboOpactiy_SelectionChanged" >
< ComboBox.ItemTemplate >
< DataTemplate >
< StackPanel Orientation ="Horizontal" >
< TextBlock Text ="{Binding Value}" Opacity ="{Binding Value}" ></ TextBlock >
</ StackPanel >
</ DataTemplate >
</ ComboBox.ItemTemplate >
</ ComboBox >
</ StackPanel >
< Canvas x:Name ="inkC" Grid.Row ="2" Height ="370" >
< Rectangle x:Name ="rectBg" Grid.Row ="2" Width ="650" Height ="370" Fill ="#FFECD85C" Margin ="0" StrokeThickness ="0" ></ Rectangle >
< Image Source ="image/background.png" Stretch ="UniformToFill" x:Name ="imgBg" ></ Image >
< InkPresenter x:Name ="ink" Height ="370" Width ="650" Grid.Row ="2"
Background ="Transparent" Opacity ="1"
MouseLeftButtonDown ="OnMouseLeftButtonDown"
MouseMove ="OnMouseMove"
LostMouseCapture ="OnLostMouseCapture" Margin ="0"
>
< InkPresenter.Clip >
< RectangleGeometry Rect ="0,0,650,370" ></ RectangleGeometry >
</ InkPresenter.Clip >
</ InkPresenter >
< TextBlock Text ="by 菩提树下的杨过" MouseLeftButtonDown ="TextBlock_MouseLeftButtonDown" Cursor ="Hand" Canvas.Left ="5" Canvas.Top ="5" Foreground ="LightGray" ></ TextBlock >
</ Canvas >
< StackPanel x:Name ="spBtn" Grid.Row ="3" Height ="30" Margin ="0" Orientation ="Horizontal" VerticalAlignment ="Center" HorizontalAlignment ="Center" >
< Button x:Name ="btnToogleBg" HorizontalAlignment ="Center" Width ="80" Content ="隐藏背景图" VerticalAlignment ="Center" Click ="btnToogleBg_Click" />
< Button x:Name ="btnToogleBgRect" HorizontalAlignment ="Center" Width ="80" Content ="隐藏背景色" VerticalAlignment ="Center" Click ="btnToogleBgRect_Click" Margin ="10,0,0,0" />
< Button x:Name ="btnSave" HorizontalAlignment ="Center" Width ="80" Content ="保存图片" VerticalAlignment ="Center" Margin ="10,0,0,0" Click ="btnSave_Click" />
< Button x:Name ="btnSaveLocal" HorizontalAlignment ="Center" Width ="90" Content ="保存图片到本地" VerticalAlignment ="Center" Margin ="10,0,0,0" Click ="btnSaveLocal_Click" />
< Button x:Name ="btnClear" HorizontalAlignment ="Center" Width ="80" Content ="清空画版" VerticalAlignment ="Center" Margin ="10,0,0,0" Click ="btnClear_Click" />
< Button x:Name ="btnClearSave" HorizontalAlignment ="Center" Width ="80" Content ="清空保存区" VerticalAlignment ="Center" Margin ="10,0,0,0" Click ="btnClearSave_Click" />
</ StackPanel >
< ScrollViewer x:Name ="ScreenshotViewer" Margin ="0" Grid.Row ="4" Background ="#FFFFFF99" HorizontalScrollBarVisibility ="Auto" VerticalScrollBarVisibility ="Hidden" >
< StackPanel x:Name ="thumbs" Orientation ="Horizontal" />
</ ScrollViewer >
</ Grid >
</ UserControl >
后端代码:
by 菩提树下的杨过 http://yjmyzz.cnblogs.com/
using
System.Windows;
using System.Windows.Controls;
using System.Collections.Generic;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Windows.Browser;
using System.Windows.Media.Imaging;
using System.IO;
using FluxJpeg.Core;
namespace InkPresenterTest
{
public partial class Page : UserControl
{
Stroke _drawStroke;
List < FillColor > lstFillColor;
List < SizeData > lstSizeData;
List < OpacityData > lstOpacityData;
bool _isLoaded = false ;
public Page()
{
InitializeComponent();
// 初始化数据
lstFillColor = new List < FillColor > () {
new FillColor(){ Color = new SolidColorBrush(Colors.Black), Name = " 黑色 " },
new FillColor(){ Color = new SolidColorBrush(Colors.Red), Name = " 红色 " },
new FillColor(){ Color = new SolidColorBrush(Colors.Blue), Name = " 蓝色 " },
new FillColor(){ Color = new SolidColorBrush(Colors.Green),Name = " 绿色 " },
new FillColor(){ Color = new SolidColorBrush(Colors.Magenta), Name = " 洋红 " },
new FillColor(){ Color = new SolidColorBrush(Colors.Orange), Name = " 橙色 " },
};
lstSizeData = new List < SizeData > ()
{
new SizeData(){ Size = 1.0 },
new SizeData(){ Size = 3.0 },
new SizeData(){ Size = 5.0 },
new SizeData(){ Size = 7.0 },
new SizeData(){ Size = 9.0 },
new SizeData(){ Size = 11.0 },
new SizeData(){ Size = 13.0 },
new SizeData(){ Size = 15.0 }
};
lstOpacityData = new List < OpacityData > (){
new OpacityData(){ Value = 0.1 },
new OpacityData(){ Value = 0.2 },
new OpacityData(){ Value = 0.3 },
new OpacityData(){ Value = 0.4 },
new OpacityData(){ Value = 0.5 },
new OpacityData(){ Value = 0.6 },
new OpacityData(){ Value = 0.7 },
new OpacityData(){ Value = 0.8 },
new OpacityData(){ Value = 0.9 },
new OpacityData(){ Value = 1.0 }
};
this .Loaded += new RoutedEventHandler(Page_Loaded);
}
void Page_Loaded( object sender, RoutedEventArgs e)
{
this .cboColor.ItemsSource = lstFillColor;
this .cboColor.SelectedIndex = 0 ;
this .cboOutlineColor.ItemsSource = lstFillColor;
this .cboOutlineColor.SelectedIndex = 0 ;
this .cboWidth.ItemsSource = lstSizeData;
this .cboWidth.SelectedIndex = 0 ;
this .cboHeight.ItemsSource = lstSizeData;
this .cboHeight.SelectedIndex = 0 ;
this .cboOpactiy.ItemsSource = lstOpacityData;
this .cboOpactiy.SelectedIndex = 5 ;
_isLoaded = true ;
}
private void OnMouseLeftButtonDown( object sender, MouseEventArgs e)
{
ink.CaptureMouse();
StylusPointCollection MyStylusPointCollection = new StylusPointCollection();
MyStylusPointCollection.Add(e.StylusDevice.GetStylusPoints(ink));
_drawStroke = new Stroke(MyStylusPointCollection);
_drawStroke.DrawingAttributes.Color = (cboColor.SelectedItem as FillColor).Color.Color;
_drawStroke.DrawingAttributes.OutlineColor = ( this .cboOutlineColor.SelectedItem as FillColor).Color.Color;
_drawStroke.DrawingAttributes.Width = ( this .cboWidth.SelectedItem as SizeData).Size;
_drawStroke.DrawingAttributes.Height = ( this .cboHeight.SelectedItem as SizeData).Size;
// _drawStroke.SetValue(OpacityProperty, (this.cboOpactiy.SelectedItem as OpacityData).Value);
ink.Strokes.Add(_drawStroke);
ink.Opacity = (cboOpactiy.SelectedItem as OpacityData).Value;
}
private void OnMouseMove( object sender, MouseEventArgs e)
{
if (_drawStroke != null )
{
_drawStroke.StylusPoints.Add(e.StylusDevice.GetStylusPoints(ink));
}
}
private void OnLostMouseCapture( object sender, MouseEventArgs e)
{
_drawStroke = null ;
}
private void btnClear_Click( object sender, System.Windows.RoutedEventArgs e)
{
ink.Strokes.Clear();
}
private void cboOpactiy_SelectionChanged( object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
if (_isLoaded)
{
ink.Opacity = (cboOpactiy.SelectedItem as OpacityData).Value;
}
}
private void btnToogleBg_Click( object sender, RoutedEventArgs e)
{
Button btn = (sender as Button);
if (btn.Content.ToString() == " 隐藏背景图 " )
{
imgBg.Visibility = Visibility.Collapsed;
btn.Content = " 显示背景图 " ;
}
else
{
imgBg.Visibility = Visibility.Visible;
btn.Content = " 隐藏背景图 " ;
}
}
private void btnToogleBgRect_Click( object sender, RoutedEventArgs e)
{
Button btn = (sender as Button);
if (btn.Content.ToString() == " 隐藏背景色 " )
{
this .rectBg.Visibility = Visibility.Collapsed;
btn.Content = " 显示背景色 " ;
}
else
{
rectBg.Visibility = Visibility.Visible;
btn.Content = " 隐藏背景色 " ;
}
}
private void TextBlock_MouseLeftButtonDown( object sender, MouseButtonEventArgs e)
{
HtmlPage.Window.Navigate( new System.Uri( " http://yjmyzz.cnblogs.com/ " ), " _blank " );
}
private void btnSave_Click( object sender, RoutedEventArgs e)
{
// 创建一个WriteableBitmap并且把需要呈现位图的元素赋值给WriteableBitmap
WriteableBitmap wb = new WriteableBitmap(inkC, null );
// 创建一个Image元素来承载位图
System.Windows.Controls.Image image = new System.Windows.Controls.Image();
image.Height = 120 ;
image.Margin = new Thickness( 5 );
image.Source = wb;
// 将Image元素放入容器控件中
thumbs.Children.Add(image);
ScreenshotViewer.ScrollToHorizontalOffset(ScreenshotViewer.ExtentWidth);
}
private void btnClearSave_Click( object sender, RoutedEventArgs e)
{
thumbs.Children.Clear();
}
private void btnSaveLocal_Click( object sender, RoutedEventArgs e)
{
WriteableBitmap wb = new WriteableBitmap(inkC, null );
if (wb != null )
{
SaveFileDialog saveDlg = new SaveFileDialog();
saveDlg.Filter = " JPEG Files (*.jpeg)|*.jpeg " ;
saveDlg.DefaultExt = " .jpeg " ;
if (saveDlg.ShowDialog().Value)
{
using (Stream fs = saveDlg.OpenFile())
{
SaveToFile(wb, fs);
MessageBox.Show( string .Format( " 文件已经保存至“{0}” " ,saveDlg.SafeFileName));
}
}
}
}
private void SaveToFile(WriteableBitmap bitmap, Stream fs)
{
int width = bitmap.PixelWidth;
int height = bitmap.PixelHeight;
int bands = 3 ;
byte [][,] raster = new byte [bands][,];
for ( int i = 0 ; i < bands; i ++ )
{
raster[i] = new byte [width, height];
}
for ( int row = 0 ; row < height; row ++ )
{
for ( int column = 0 ; column < width; column ++ )
{
int pixel = bitmap.Pixels[width * row + column];
raster[ 0 ][column, row] = ( byte )(pixel >> 16 );
raster[ 1 ][column, row] = ( byte )(pixel >> 8 );
raster[ 2 ][column, row] = ( byte )pixel;
}
}
FluxJpeg.Core.ColorModel model = new FluxJpeg.Core.ColorModel { colorspace = FluxJpeg.Core.ColorSpace.RGB };
FluxJpeg.Core.Image img = new FluxJpeg.Core.Image(model, raster);
// Encode the Image as a JPEG
MemoryStream stream = new MemoryStream();
FluxJpeg.Core.Encoder.JpegEncoder encoder = new FluxJpeg.Core.Encoder.JpegEncoder(img, 100 , stream);
encoder.Encode();
// Back to the start
stream.Seek( 0 , SeekOrigin.Begin);
// Get teh Bytes and write them to the stream
byte [] binaryData = new byte [stream.Length];
long bytesRead = stream.Read(binaryData, 0 , ( int )stream.Length);
fs.Write(binaryData, 0 , binaryData.Length);
}
}
public class FillColor
{
public SolidColorBrush Color { set ; get ; }
public string Name { set ; get ; }
}
public class SizeData
{
public double Size { set ; get ; }
}
public class OpacityData
{
public double Value { set ; get ; }
}
}
using System.Windows.Controls;
using System.Collections.Generic;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Windows.Browser;
using System.Windows.Media.Imaging;
using System.IO;
using FluxJpeg.Core;
namespace InkPresenterTest
{
public partial class Page : UserControl
{
Stroke _drawStroke;
List < FillColor > lstFillColor;
List < SizeData > lstSizeData;
List < OpacityData > lstOpacityData;
bool _isLoaded = false ;
public Page()
{
InitializeComponent();
// 初始化数据
lstFillColor = new List < FillColor > () {
new FillColor(){ Color = new SolidColorBrush(Colors.Black), Name = " 黑色 " },
new FillColor(){ Color = new SolidColorBrush(Colors.Red), Name = " 红色 " },
new FillColor(){ Color = new SolidColorBrush(Colors.Blue), Name = " 蓝色 " },
new FillColor(){ Color = new SolidColorBrush(Colors.Green),Name = " 绿色 " },
new FillColor(){ Color = new SolidColorBrush(Colors.Magenta), Name = " 洋红 " },
new FillColor(){ Color = new SolidColorBrush(Colors.Orange), Name = " 橙色 " },
};
lstSizeData = new List < SizeData > ()
{
new SizeData(){ Size = 1.0 },
new SizeData(){ Size = 3.0 },
new SizeData(){ Size = 5.0 },
new SizeData(){ Size = 7.0 },
new SizeData(){ Size = 9.0 },
new SizeData(){ Size = 11.0 },
new SizeData(){ Size = 13.0 },
new SizeData(){ Size = 15.0 }
};
lstOpacityData = new List < OpacityData > (){
new OpacityData(){ Value = 0.1 },
new OpacityData(){ Value = 0.2 },
new OpacityData(){ Value = 0.3 },
new OpacityData(){ Value = 0.4 },
new OpacityData(){ Value = 0.5 },
new OpacityData(){ Value = 0.6 },
new OpacityData(){ Value = 0.7 },
new OpacityData(){ Value = 0.8 },
new OpacityData(){ Value = 0.9 },
new OpacityData(){ Value = 1.0 }
};
this .Loaded += new RoutedEventHandler(Page_Loaded);
}
void Page_Loaded( object sender, RoutedEventArgs e)
{
this .cboColor.ItemsSource = lstFillColor;
this .cboColor.SelectedIndex = 0 ;
this .cboOutlineColor.ItemsSource = lstFillColor;
this .cboOutlineColor.SelectedIndex = 0 ;
this .cboWidth.ItemsSource = lstSizeData;
this .cboWidth.SelectedIndex = 0 ;
this .cboHeight.ItemsSource = lstSizeData;
this .cboHeight.SelectedIndex = 0 ;
this .cboOpactiy.ItemsSource = lstOpacityData;
this .cboOpactiy.SelectedIndex = 5 ;
_isLoaded = true ;
}
private void OnMouseLeftButtonDown( object sender, MouseEventArgs e)
{
ink.CaptureMouse();
StylusPointCollection MyStylusPointCollection = new StylusPointCollection();
MyStylusPointCollection.Add(e.StylusDevice.GetStylusPoints(ink));
_drawStroke = new Stroke(MyStylusPointCollection);
_drawStroke.DrawingAttributes.Color = (cboColor.SelectedItem as FillColor).Color.Color;
_drawStroke.DrawingAttributes.OutlineColor = ( this .cboOutlineColor.SelectedItem as FillColor).Color.Color;
_drawStroke.DrawingAttributes.Width = ( this .cboWidth.SelectedItem as SizeData).Size;
_drawStroke.DrawingAttributes.Height = ( this .cboHeight.SelectedItem as SizeData).Size;
// _drawStroke.SetValue(OpacityProperty, (this.cboOpactiy.SelectedItem as OpacityData).Value);
ink.Strokes.Add(_drawStroke);
ink.Opacity = (cboOpactiy.SelectedItem as OpacityData).Value;
}
private void OnMouseMove( object sender, MouseEventArgs e)
{
if (_drawStroke != null )
{
_drawStroke.StylusPoints.Add(e.StylusDevice.GetStylusPoints(ink));
}
}
private void OnLostMouseCapture( object sender, MouseEventArgs e)
{
_drawStroke = null ;
}
private void btnClear_Click( object sender, System.Windows.RoutedEventArgs e)
{
ink.Strokes.Clear();
}
private void cboOpactiy_SelectionChanged( object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
if (_isLoaded)
{
ink.Opacity = (cboOpactiy.SelectedItem as OpacityData).Value;
}
}
private void btnToogleBg_Click( object sender, RoutedEventArgs e)
{
Button btn = (sender as Button);
if (btn.Content.ToString() == " 隐藏背景图 " )
{
imgBg.Visibility = Visibility.Collapsed;
btn.Content = " 显示背景图 " ;
}
else
{
imgBg.Visibility = Visibility.Visible;
btn.Content = " 隐藏背景图 " ;
}
}
private void btnToogleBgRect_Click( object sender, RoutedEventArgs e)
{
Button btn = (sender as Button);
if (btn.Content.ToString() == " 隐藏背景色 " )
{
this .rectBg.Visibility = Visibility.Collapsed;
btn.Content = " 显示背景色 " ;
}
else
{
rectBg.Visibility = Visibility.Visible;
btn.Content = " 隐藏背景色 " ;
}
}
private void TextBlock_MouseLeftButtonDown( object sender, MouseButtonEventArgs e)
{
HtmlPage.Window.Navigate( new System.Uri( " http://yjmyzz.cnblogs.com/ " ), " _blank " );
}
private void btnSave_Click( object sender, RoutedEventArgs e)
{
// 创建一个WriteableBitmap并且把需要呈现位图的元素赋值给WriteableBitmap
WriteableBitmap wb = new WriteableBitmap(inkC, null );
// 创建一个Image元素来承载位图
System.Windows.Controls.Image image = new System.Windows.Controls.Image();
image.Height = 120 ;
image.Margin = new Thickness( 5 );
image.Source = wb;
// 将Image元素放入容器控件中
thumbs.Children.Add(image);
ScreenshotViewer.ScrollToHorizontalOffset(ScreenshotViewer.ExtentWidth);
}
private void btnClearSave_Click( object sender, RoutedEventArgs e)
{
thumbs.Children.Clear();
}
private void btnSaveLocal_Click( object sender, RoutedEventArgs e)
{
WriteableBitmap wb = new WriteableBitmap(inkC, null );
if (wb != null )
{
SaveFileDialog saveDlg = new SaveFileDialog();
saveDlg.Filter = " JPEG Files (*.jpeg)|*.jpeg " ;
saveDlg.DefaultExt = " .jpeg " ;
if (saveDlg.ShowDialog().Value)
{
using (Stream fs = saveDlg.OpenFile())
{
SaveToFile(wb, fs);
MessageBox.Show( string .Format( " 文件已经保存至“{0}” " ,saveDlg.SafeFileName));
}
}
}
}
private void SaveToFile(WriteableBitmap bitmap, Stream fs)
{
int width = bitmap.PixelWidth;
int height = bitmap.PixelHeight;
int bands = 3 ;
byte [][,] raster = new byte [bands][,];
for ( int i = 0 ; i < bands; i ++ )
{
raster[i] = new byte [width, height];
}
for ( int row = 0 ; row < height; row ++ )
{
for ( int column = 0 ; column < width; column ++ )
{
int pixel = bitmap.Pixels[width * row + column];
raster[ 0 ][column, row] = ( byte )(pixel >> 16 );
raster[ 1 ][column, row] = ( byte )(pixel >> 8 );
raster[ 2 ][column, row] = ( byte )pixel;
}
}
FluxJpeg.Core.ColorModel model = new FluxJpeg.Core.ColorModel { colorspace = FluxJpeg.Core.ColorSpace.RGB };
FluxJpeg.Core.Image img = new FluxJpeg.Core.Image(model, raster);
// Encode the Image as a JPEG
MemoryStream stream = new MemoryStream();
FluxJpeg.Core.Encoder.JpegEncoder encoder = new FluxJpeg.Core.Encoder.JpegEncoder(img, 100 , stream);
encoder.Encode();
// Back to the start
stream.Seek( 0 , SeekOrigin.Begin);
// Get teh Bytes and write them to the stream
byte [] binaryData = new byte [stream.Length];
long bytesRead = stream.Read(binaryData, 0 , ( int )stream.Length);
fs.Write(binaryData, 0 , binaryData.Length);
}
}
public class FillColor
{
public SolidColorBrush Color { set ; get ; }
public string Name { set ; get ; }
}
public class SizeData
{
public double Size { set ; get ; }
}
public class OpacityData
{
public double Value { set ; get ; }
}
}
源代码下载地址: http://files.cnblogs.com/yjmyzz/InkPresenterTest.rar
对Flash感兴趣的朋友,做为对比,也可以看下Flash/Flex学习笔记(14):制作涂鸦板
转载请注明来自菩提树下的杨过 http://www.cnblogs.com/yjmyzz/archive/2010/01/14/1647636.html
注:里面用到了一个开源的组件FJCore