Silverlight4支持打印大头贴
Silverlight 4提供了许多的新特性,如摄像头、打印等。这里我就用Silverlight 4做了一个在线照大头贴的小东西。
先放效果图:
项目结构如下图所示:
template目录里存放的是一些简单的遮罩模板,这些模板都实现了IFillBrushable接口。
主界面(Page.xaml)的主要代码如下:
1 |
<Grid x:Name="LayoutRoot"><br> <Grid x:Name="grdRender" Width="180" Height="180" Margin="10,10,200,100" ShowGridLines="False"><br> </Grid><br><br> <Button Content="保存" Height="23" HorizontalAlignment="Left" Margin="12,251,0,0" x:Name="btnSave" VerticalAlignment="Top" Width="75" Click="btnSave_Click" /><br> <Button Content="捕获" Height="23" HorizontalAlignment="Left" Margin="12,214,0,0" x:Name="btnCapture" VerticalAlignment="Top" Width="75" Click="btnCapture_Click" /><br> <Button Content="导入" Height="23" HorizontalAlignment="Left" Margin="104,214,0,0" x:Name="btnImport" VerticalAlignment="Top" Width="75" Click="btnImport_Click" /><br> <Button Content="打印" Height="23" HorizontalAlignment="Left" Margin="104,251,0,0" x:Name="btnPrint" VerticalAlignment="Top" Width="75" Click="btnPrint_Click" /><br> <ListBox Height="200" HorizontalAlignment="Left" Margin="228,10,0,0" Name="lstTemplate" VerticalAlignment="Top" Width="110" SelectionChanged="lstTemplate_SelectionChanged" ><br> </ListBox><br> <Grid.Background><br> <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"><br> <GradientStop Color="#FF524040" Offset="0" /><br> <GradientStop Color="#FFD8BCBC" Offset="1" /><br> <GradientStop Color="#FF3E3A3A" Offset="0.26" /><br> </LinearGradientBrush><br> </Grid.Background><br> </Grid> |
效果如下:
后台代码:
1 |
public partial class Page : UserControl<br>{<br><br> UserControl render = null;<br> public Page()<br> {<br> InitializeComponent();<br> //Load事件<br> this.Loaded += (sender, e) =><br> {<br> //加载默认的遮罩模板<br> render = new starTemp() { Margin = new Thickness(0), FillBrush = new SolidColorBrush(Color.FromArgb(255, 255, 0, 0)) };<br> grdRender.Children.Add(render);<br><br> //绑定模板数据到ListBox<br> BindTemplateControl();<br> };<br> }<br><br> private void btnSave_Click(object sender, RoutedEventArgs e)<br> {<br> //创建WriteableBitmap<br> WriteableBitmap wb = new WriteableBitmap(grdRender, null);<br><br> SaveFileDialog sfd = new SaveFileDialog();<br> sfd.ShowDialog();<br> if (!string.IsNullOrEmpty(sfd.SafeFileName.Trim()))<br> {<br> using (Stream stream = sfd.OpenFile())<br> {<br> // 将WriteableBitmap数据写入到Stream<br> SaveBitmap(wb, stream);<br> //关闭保存流<br> stream.Close();<br> }<br> }<br> }<br><br> /// <summary><br> /// 将WriteableBitmap数据写入到Stream<br> /// </summary><br> /// <param name="bitmap"></param><br> /// <param name="fs"></param><br> private void SaveBitmap(WriteableBitmap bitmap, Stream fs)<br> {<br> int pixelWidth = bitmap.PixelWidth;<br> int pixelHeight = bitmap.PixelHeight;<br> int num3 = 3;<br> byte[][,] bufferArray = new byte[num3][,];<br> for (int i = 0; i < num3; i++)<br> {<br> bufferArray[i] = new byte[pixelWidth, pixelHeight];<br> }<br> for (int j = 0; j < pixelHeight; j++)<br> {<br> for (int k = 0; k < pixelWidth; k++)<br> {<br> int num7 = bitmap.Pixels[(pixelWidth * j) + k];<br> bufferArray[0][k, j] = (byte)(num7 >> 0x10);<br> bufferArray[1][k, j] = (byte)(num7 >> 8);<br> bufferArray[2][k, j] = (byte)num7;<br> }<br> }<br> ColorModel model2 = new ColorModel()<br> {<br> colorspace = ColorSpace.RGB<br> };<br> ColorModel model = model2;<br> FluxJpeg.Core.Image image = new FluxJpeg.Core.Image(model, bufferArray);<br> MemoryStream stream = new MemoryStream();<br> new JpegEncoder(image, 100, stream).Encode();<br> stream.Seek(0L, SeekOrigin.Begin);<br> byte[] buffer = new byte[stream.Length];<br> long num8 = stream.Read(buffer, 0, (int)stream.Length);<br> fs.Write(buffer, 0, buffer.Length);<br> }<br><br> private void OnStart()<br> {<br> //实例化CaptureSource<br> CaptureSource source = new CaptureSource();<br> //是否请允许访问设备<br> bool blnAllowedDeviceAccess = CaptureDeviceConfiguration.AllowedDeviceAccess;<br> //请求设备,返回是否成功<br> bool blnRequestDeviceAccess = CaptureDeviceConfiguration.RequestDeviceAccess();<br> //禁止访问设备则返回<br> if (blnAllowedDeviceAccess<br> || !blnRequestDeviceAccess)<br> return;<br><br> //设置捕获的视频设备<br> source.VideoCaptureDevice = CaptureDeviceConfiguration.GetDefaultVideoCaptureDevice();<br> //新建一个VideoBrush<br> VideoBrush videoBrush = new VideoBrush();<br> //设置VideoBrush的数据源<br> videoBrush.SetSource(source);<br> //设置grdRender的背景为videoBrush<br> grdRender.Background = videoBrush;<br> //捕获<br> source.Start();<br> }<br><br> private void btnCapture_Click(object sender, RoutedEventArgs e)<br> {<br> OnStart();<br> }<br><br> /// <summary><br> /// 导入遮罩图片<br> /// </summary><br> /// <param name="sender"></param><br> /// <param name="e"></param><br> private void btnImport_Click_Click(object sender, RoutedEventArgs e)<br> {<br> OpenFileDialog ofd = new OpenFileDialog();<br> ofd.ShowDialog();<br> if (ofd.File != null)<br> {<br> //创建ImageBrush<br> ImageBrush ib = new ImageBrush();<br> //打开的图片文件的流<br> Stream stream = ofd.File.OpenRead();<br> var bmp = new BitmapImage();<br> //填充到BitmapImage中<br> bmp.SetSource(stream);<br> ib.ImageSource = bmp;<br> //设置为遮罩控件的FillBursh<br> (render as IFillBrushable).FillBrush = ib;<br> }<br> }<br><br> private void btnPrint_Click(object sender, RoutedEventArgs e)<br> {<br> //创建打印文档对象<br> PrintDocument pd = new PrintDocument();<br> //设置文档标题<br> pd.SetValue(PrintDocument.DocumentNameProperty, "大头贴");<br> //设置打印区,为render对象<br> pd.PrintPage += (ppsender, ppe) => { ppe.PageVisual = render; };<br> pd.Print();<br> }<br><br> private void BindTemplateControl()<br> {<br> //获取当前程序集<br> var assembly = Assembly.GetExecutingAssembly();<br> //根据Namespace取类型<br> Type[] types = assembly.GetTypes().Where(p => p.Namespace == "SilverlightApplication1.template").ToArray();<br> //设置lstTemplate的数据源为上面类型的名称集合<br> lstTemplate.ItemsSource = from mod in types select mod.Name;<br> lstTemplate.UpdateLayout();<br> }<br><br> /// <summary><br> /// ListBox选择项改变<br> /// </summary><br> /// <param name="sender"></param><br> /// <param name="e"></param><br> private void lstTemplate_SelectionChanged(object sender, SelectionChangedEventArgs e)<br> {<br> //先清楚grdRender的子控件,即遮罩控件 <br> grdRender.Children.Clear();<br> //分所当前选择的第一项改变<br> switch (e.AddedItems[0].ToString())<br> {<br> case "hart":<br> render = new hartTemp() { Margin = new Thickness(0), FillBrush = new SolidColorBrush(Color.FromArgb(255, 255, 0, 0)) };<br> grdRender.Children.Add(render);<br> break;<br> case "Star":<br> render = new starTemp() { Margin = new Thickness(0), FillBrush = new SolidColorBrush(Color.FromArgb(255, 255, 0, 0)) };<br> grdRender.Children.Add(render);<br> break;<br> }<br> }<br>} |
遮罩模板接口:
1 |
/// <summary><br>/// 遮罩控件层接口<br>/// </summary><br>public interface IFillBrushable<br>{<br> /// <summary><br> /// 遮挡区的填充画笔<br> /// </summary><br> Brush FillBrush<br> { get; set; }<br>} |
然后就是遮罩模板控件,如心形遮罩控件的Xaml如下:
1 |
<Grid x:Name="LayoutRoot" Background="#00FF0000" ><br> <Path x:Name="pathMask" Stretch="UniformToFill" Stroke="Black" StrokeThickness="0" HorizontalAlignment="Left" VerticalAlignment="Top" UseLayoutRounding="False" Data="M130,10.504693 C110.25,10.755516 90.5,21.039251 90.5,41.105072 C90.5,0.97377241 10.5,0.9732672 10.500001,41.105072 C10.5,81.236885 90.5,161.50002 90.5,161.50002 C90.5,161.50002 169.5,80.233429 169.5,40.10178 C169.5,20.035959 149.75,10.253871 130,10.504693 z M0.5,0.5 L179.5,0.5 L179.5,171.5 L0.5,171.5 z"><br> </Path><br> </Grid> |
后台代码如下(一定要实现IFillBrushable接口):
1 |
public partial class hartTemp : UserControl, IFillBrushable<br>{<br> #region 是实现FillBrush属性<br><br> public static DependencyProperty FillBrushProperty;<br><br> public Brush FillBrush<br> {<br> get<br> { return base.GetValue(FillBrushProperty) as Brush; }<br> set<br> { base.SetValue(FillBrushProperty, value); }<br> }<br><br> static void OnFillBrushChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)<br> {<br> (sender as hartTemp).OnFillBrushChanged(e);<br> }<br><br> void OnFillBrushChanged(DependencyPropertyChangedEventArgs e)<br> {<br> pathMask.Fill = e.NewValue as Brush;<br> }<br> #endregion<br><br> public hartTemp()<br> {<br> FillBrushProperty = DependencyProperty.Register("FillBrush",<br> typeof(Brush),<br> typeof(hartTemp),<br> new PropertyMetadata(new SolidColorBrush(Color.FromArgb(255, 255, 0, 0)), new PropertyChangedCallback(hartTemp.OnFillBrushChanged)));<br> InitializeComponent();<br> }<br>} |
其它的内容可以下载附件中的源码。
注意:开发调试环境为Vs2010 B2版 ,Silverlight 4。由于没有摄像头所以我这里用了个虚拟摄像头放的是视频。
源码下载:http://de.xunbin.com/attachment.php?fid=1