当前位置: 首页 > news >正文

Silverlight 4实现在线大头贴程序,支持打印

Silverlight 4提供了许多的新特性,如摄像头、打印等。这里我就用Silverlight 4做了一个在线照大头贴的小东西。

先放效果图:

效果1.jpg效果2.jpg效果3.jpg效果4.jpg

项目结构如下图所示:

项目结构.jpg

template目录里存放的是一些简单的遮罩模板,这些模板都实现了IFillBrushable接口。

主界面(Page.xaml)的主要代码如下:

<Grid x:Name="LayoutRoot">
        <Grid x:Name="grdRender" Width="180" Height="180" Margin="10,10,200,100" ShowGridLines="False">
        </Grid>

        <Button Content="保存" Height="23" HorizontalAlignment="Left" Margin="12,251,0,0" x:Name="btnSave" VerticalAlignment="Top" Width="75" Click="btnSave_Click" />
        <Button Content="捕获" Height="23" HorizontalAlignment="Left" Margin="12,214,0,0" x:Name="btnCapture" VerticalAlignment="Top" Width="75" Click="btnCapture_Click" />
        <Button Content="导入" Height="23" HorizontalAlignment="Left" Margin="104,214,0,0" x:Name="btnImport" VerticalAlignment="Top" Width="75" Click="btnImport_Click" />
        <Button Content="打印" Height="23" HorizontalAlignment="Left" Margin="104,251,0,0" x:Name="btnPrint" VerticalAlignment="Top" Width="75" Click="btnPrint_Click" />
        <ListBox Height="200" HorizontalAlignment="Left" Margin="228,10,0,0" Name="lstTemplate" VerticalAlignment="Top" Width="110" SelectionChanged="lstTemplate_SelectionChanged" >
        </ListBox>
        <Grid.Background>
            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                <GradientStop Color="#FF524040" Offset="0" />
                <GradientStop Color="#FFD8BCBC" Offset="1" />
                <GradientStop Color="#FF3E3A3A" Offset="0.26" />
            </LinearGradientBrush>
        </Grid.Background>
    </Grid>

效果如下:

主界面设计图.jpg

后台代码:

public partial class Page : UserControl
{

    UserControl render = null;
    public Page()
    {
        InitializeComponent();
        //Load事件
        this.Loaded += (sender, e) =>
            {
                //加载默认的遮罩模板
                render = new starTemp() { Margin = new Thickness(0), FillBrush = new SolidColorBrush(Color.FromArgb(255, 255, 0, 0)) };
                grdRender.Children.Add(render);

                //绑定模板数据到ListBox
                BindTemplateControl();
            };
    }

    private void btnSave_Click(object sender, RoutedEventArgs e)
    {
        //创建WriteableBitmap
        WriteableBitmap wb = new WriteableBitmap(grdRender, null);

        SaveFileDialog sfd = new SaveFileDialog();
        sfd.ShowDialog();
        if (!string.IsNullOrEmpty(sfd.SafeFileName.Trim()))
        {
            using (Stream stream = sfd.OpenFile())
            {
                // 将WriteableBitmap数据写入到Stream
                SaveBitmap(wb, stream);
                //关闭保存流
                stream.Close();
            }
        }
    }

    /// <summary>
    /// 将WriteableBitmap数据写入到Stream
    /// </summary>
    /// <param name="bitmap"></param>
    /// <param name="fs"></param>
    private void SaveBitmap(WriteableBitmap bitmap, Stream fs)
    {
        int pixelWidth = bitmap.PixelWidth;
        int pixelHeight = bitmap.PixelHeight;
        int num3 = 3;
        byte[][,] bufferArray = new byte[num3][,];
        for (int i = 0; i < num3; i++)
        {
            bufferArray[i] = new byte[pixelWidth, pixelHeight];
        }
        for (int j = 0; j < pixelHeight; j++)
        {
            for (int k = 0; k < pixelWidth; k++)
            {
                int num7 = bitmap.Pixels[(pixelWidth * j) + k];
                bufferArray[0][k, j] = (byte)(num7 >> 0x10);
                bufferArray[1][k, j] = (byte)(num7 >> 8);
                bufferArray[2][k, j] = (byte)num7;
            }
        }
        ColorModel model2 = new ColorModel()
        {
            colorspace = ColorSpace.RGB
        };
        ColorModel model = model2;
        FluxJpeg.Core.Image image = new FluxJpeg.Core.Image(model, bufferArray);
        MemoryStream stream = new MemoryStream();
        new JpegEncoder(image, 100, stream).Encode();
        stream.Seek(0L, SeekOrigin.Begin);
        byte[] buffer = new byte[stream.Length];
        long num8 = stream.Read(buffer, 0, (int)stream.Length);
        fs.Write(buffer, 0, buffer.Length);
    }

    private void OnStart()
    {
        //实例化CaptureSource
        CaptureSource source = new CaptureSource();
        //是否请允许访问设备
        bool blnAllowedDeviceAccess = CaptureDeviceConfiguration.AllowedDeviceAccess;
        //请求设备,返回是否成功
        bool blnRequestDeviceAccess = CaptureDeviceConfiguration.RequestDeviceAccess();
        //禁止访问设备则返回
        if (blnAllowedDeviceAccess
            || !blnRequestDeviceAccess)
            return;

        //设置捕获的视频设备
        source.VideoCaptureDevice = CaptureDeviceConfiguration.GetDefaultVideoCaptureDevice();
        //新建一个VideoBrush
        VideoBrush videoBrush = new VideoBrush();
        //设置VideoBrush的数据源
        videoBrush.SetSource(source);
        //设置grdRender的背景为videoBrush
        grdRender.Background = videoBrush;
        //捕获
        source.Start();
    }

    private void btnCapture_Click(object sender, RoutedEventArgs e)
    {
        OnStart();
    }

    /// <summary>
    /// 导入遮罩图片
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void btnImport_Click_Click(object sender, RoutedEventArgs e)
    {
        OpenFileDialog ofd = new OpenFileDialog();
        ofd.ShowDialog();
        if (ofd.File != null)
        {
            //创建ImageBrush
            ImageBrush ib = new ImageBrush();
            //打开的图片文件的流
            Stream stream = ofd.File.OpenRead();
            var bmp = new BitmapImage();
            //填充到BitmapImage中
            bmp.SetSource(stream);
            ib.ImageSource = bmp;
            //设置为遮罩控件的FillBursh
            (render as IFillBrushable).FillBrush = ib;
        }
    }

    private void btnPrint_Click(object sender, RoutedEventArgs e)
    {
        //创建打印文档对象
        PrintDocument pd = new PrintDocument();
        //设置文档标题
        pd.SetValue(PrintDocument.DocumentNameProperty, "大头贴");
        //设置打印区,为render对象
        pd.PrintPage += (ppsender, ppe) => { ppe.PageVisual = render; };
        pd.Print();
    }

    private void BindTemplateControl()
    {
        //获取当前程序集
        var assembly = Assembly.GetExecutingAssembly();
        //根据Namespace取类型
        Type[] types = assembly.GetTypes().Where(p => p.Namespace == "SilverlightApplication1.template").ToArray();
        //设置lstTemplate的数据源为上面类型的名称集合
        lstTemplate.ItemsSource = from mod in types select mod.Name;
        lstTemplate.UpdateLayout();
    }

    /// <summary>
    /// ListBox选择项改变
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void lstTemplate_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        //先清楚grdRender的子控件,即遮罩控件 
        grdRender.Children.Clear();
        //分所当前选择的第一项改变
        switch (e.AddedItems[0].ToString())
        {
            case "hart":
                render = new hartTemp() { Margin = new Thickness(0), FillBrush = new SolidColorBrush(Color.FromArgb(255, 255, 0, 0)) };
                grdRender.Children.Add(render);
                break;
            case "Star":
                render = new starTemp() { Margin = new Thickness(0), FillBrush = new SolidColorBrush(Color.FromArgb(255, 255, 0, 0)) };
                grdRender.Children.Add(render);
                break;
        }
    }
}

遮罩模板接口:

 

/// <summary>
/// 遮罩控件层接口
/// </summary>
public interface IFillBrushable
{
    /// <summary>
    /// 遮挡区的填充画笔
    /// </summary>
    Brush FillBrush
    { get; set; }
}

然后就是遮罩模板控件,如心形遮罩控件的Xaml如下:

 

    <Grid x:Name="LayoutRoot" Background="#00FF0000" >
    	<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">
        </Path>
    </Grid>

 

后台代码如下(一定要实现IFillBrushable接口):

public partial class hartTemp : UserControl, IFillBrushable
{
    #region 是实现FillBrush属性

    public static DependencyProperty FillBrushProperty;

    public Brush FillBrush
    {
        get
        { return base.GetValue(FillBrushProperty) as Brush; }
        set
        { base.SetValue(FillBrushProperty, value); }
    }

    static void OnFillBrushChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
    {
        (sender as hartTemp).OnFillBrushChanged(e);
    }

    void OnFillBrushChanged(DependencyPropertyChangedEventArgs e)
    {
        pathMask.Fill = e.NewValue as Brush;
    }
    #endregion

    public hartTemp()
    {
        FillBrushProperty = DependencyProperty.Register("FillBrush",
                                       typeof(Brush),
                                       typeof(hartTemp),
                                       new PropertyMetadata(new SolidColorBrush(Color.FromArgb(255, 255, 0, 0)), new PropertyChangedCallback(hartTemp.OnFillBrushChanged)));
        InitializeComponent();
    }
}

 

 

其它的内容可以下载附件中的源码。

注意:开发调试环境为Vs2010 B2版 ,Silverlight 4。由于没有摄像头所以我这里用了个虚拟摄像头放的是视频。

源码下载:附件:CaptureTest.rar

转载于:https://www.cnblogs.com/desmend/archive/2009/12/18/1643810.html

相关文章:

  • 业务系统--业务架构转化成为IT应用的中间桥梁
  • 用来代替SQLSERVERAGENT的VBS脚本。
  • Windows Server 2003 DHCP 服务
  • [莓讯]blackberry潘多拉更新至1.1.3版本
  • Hadoop技术论坛
  • Delphi中怎样监视POP3信箱?
  • ubuntu的第三方站点remastersys无法访问
  • 业务系统设计之二:系统主控设计(上)
  • ROS 全自动算号器 1.1下载
  • 女性排毒养颜美容的14个技巧 - 健康程序员,至尚生活!
  • 汇编语言学习笔记-接收鼠标消息
  • IE新0day漏洞(979352)(又称极光零日漏洞)***将扩散
  • 苹果高清HD编辑系统
  • 支持firefox 3.6的onenote插件
  • 家长早放手,孩子早当家
  • Angular 响应式表单之下拉框
  • canvas 高仿 Apple Watch 表盘
  • Consul Config 使用Git做版本控制的实现
  • iOS小技巧之UIImagePickerController实现头像选择
  • Python学习笔记 字符串拼接
  • SpiderData 2019年2月25日 DApp数据排行榜
  • V4L2视频输入框架概述
  • webpack4 一点通
  • 得到一个数组中任意X个元素的所有组合 即C(n,m)
  • 关于Java中分层中遇到的一些问题
  • 基于Android乐音识别(2)
  • 基于游标的分页接口实现
  • 区块链技术特点之去中心化特性
  • 设计模式走一遍---观察者模式
  • 深入浅出Node.js
  • 实习面试笔记
  • 使用 @font-face
  • 算法之不定期更新(一)(2018-04-12)
  • 详解NodeJs流之一
  • 用jquery写贪吃蛇
  • ​力扣解法汇总1802. 有界数组中指定下标处的最大值
  • #162 (Div. 2)
  • #周末课堂# 【Linux + JVM + Mysql高级性能优化班】(火热报名中~~~)
  • (day 12)JavaScript学习笔记(数组3)
  • (Matlab)基于蝙蝠算法实现电力系统经济调度
  • (Redis使用系列) Springboot 在redis中使用BloomFilter布隆过滤器机制 六
  • (SpringBoot)第二章:Spring创建和使用
  • (附源码)spring boot北京冬奥会志愿者报名系统 毕业设计 150947
  • (完整代码)R语言中利用SVM-RFE机器学习算法筛选关键因子
  • (学习日记)2024.04.04:UCOSIII第三十二节:计数信号量实验
  • (转)C#开发微信门户及应用(1)--开始使用微信接口
  • (最全解法)输入一个整数,输出该数二进制表示中1的个数。
  • (最优化理论与方法)第二章最优化所需基础知识-第三节:重要凸集举例
  • .bat文件调用java类的main方法
  • .net core 依赖注入的基本用发
  • .net Stream篇(六)
  • .net 写了一个支持重试、熔断和超时策略的 HttpClient 实例池
  • .net 逐行读取大文本文件_如何使用 Java 灵活读取 Excel 内容 ?
  • .NET国产化改造探索(一)、VMware安装银河麒麟
  • .net用HTML开发怎么调试,如何使用ASP.NET MVC在调试中查看控制器生成的html?