win8种启用摄像有拍照并保存图片到本地

来源:互联网 发布:cf总出现网络异常 编辑:程序博客网 时间:2024/06/02 18:08

win8中启用摄像头拍照并保存图片到本地,网上很少原创的东西,到处都是黏贴复制,根本没有比较系统的说法。最后还是自己重新梳理思路才搞定的。

直接附上代码,注视写的非常详细。

前台xaml代码:一个Image控件,显示通过摄像头拍摄的照片;一个按钮,负责启动摄像头;一个AppBar,负责保存图片

<Page.TopAppBar>        <AppBar>            <Button Name="btnSave" Click="btnSave_Click_1" Style="{StaticResource SaveAppBarButtonStyle}"/>        </AppBar>    </Page.TopAppBar>        <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">        <Image x:Name="CapturedPhoto"  MaxWidth="392" Stretch="Uniform" />        <Button Content="启动摄像头" HorizontalAlignment="Left" Margin="378,37,0,0" VerticalAlignment="Top" Click="Button_Click_1"/>    </Grid>


后台c#代码:

首先声明一个全局StorageFile类型变量,指向的是通过摄像有拍摄的照片

StorageFile file = null;

在“启动摄像头”的单击事件中,启动摄像头,拍摄照片,显示照片

     /*CameraCaptureUI类负责启动摄像头,并捕获照摄像头拍摄的照片             要想启动摄像头,需打开Package.appxmanifest文件,切换到“功能”界面,             勾选网络摄像机和麦克风*/            CameraCaptureUI dialog = new CameraCaptureUI();            Size aspectRatio = new Size(16, 9);            /*设定摄像头拍摄照片的高宽比,拍照完成之后就能看到效果,可以通过修改高宽比             来查看不同的效果*/            dialog.PhotoSettings.CroppedAspectRatio = aspectRatio;            /*CaptureFileAsync方法负责启动摄像有并拍摄照片或拍摄影片,其返回值为拍摄的照片或拍摄的影片.             CameraCaptureUIMode是个枚举,设置拍摄的是照片还是影片*/            file = await dialog.CaptureFileAsync(CameraCaptureUIMode.Photo);            if (file != null)            {                /*BitmapImage类是ImageSource类的子类,用来将图片填充到Image控件中*/                BitmapImage bitmapImage = new BitmapImage();                /*使用OpenAsync打开拍摄的照片,返回流filestream*/                using (IRandomAccessStream fileStream = await file.OpenAsync(FileAccessMode.Read))                {                    //设置bitmapImage的图片源为拍摄的照片                    bitmapImage.SetSource(fileStream);                }                //将照片显示到图片控件中                CapturedPhoto.Source = bitmapImage;            }

保存按钮的单击事件代码

     //实例化文件选取器            FileSavePicker picker = new FileSavePicker();            //设置图片保存的类型            picker.FileTypeChoices.Add("image file", new List<string>() { ".jpg",".png" });            /*返回文件选取器返回的新建的文件:调用PickSaveFileAsync方法后会在制定的位置            创建制定名称制定格式的文件*/            StorageFile storageFile = await picker.PickSaveFileAsync();            //打开通过摄像头拍摄的照片,并返回流,以流的形式读取文件            var StreamRandom = await file.OpenAsync(FileAccessMode.Read);            //将拍摄的照片以流的方式读取到缓冲区            IBuffer buffer = RandomAccessStreamToBuffer(StreamRandom);            //将缓冲区的内容(拍摄的照片)写入到新建的文件中            await FileIO.WriteBufferAsync(storageFile, buffer);

RandomAccessStreamToBuffer方法

private IBuffer RandomAccessStreamToBuffer(IRandomAccessStream randomstream)        {            Stream stream = WindowsRuntimeStreamExtensions.AsStreamForRead(randomstream.GetInputStreamAt(0));            MemoryStream memoryStream = new MemoryStream();            if (stream != null)            {                byte[] bytes = ConvertStreamTobyte(stream);                if (bytes != null)                {                    var binaryWriter = new BinaryWriter(memoryStream);                    binaryWriter.Write(bytes);                }            }            IBuffer buffer = WindowsRuntimeBufferExtensions.GetWindowsRuntimeBuffer(memoryStream, 0, (int)memoryStream.Length);            return buffer;        }

ConvertStreamTobyte方法

public static byte[] ConvertStreamTobyte(Stream input)        {            byte[] buffer = new byte[16 * 1024];            using (MemoryStream ms = new MemoryStream())            {                int read;                while ((read = input.Read(buffer, 0, buffer.Length)) > 0)                {                    ms.Write(buffer, 0, read);                }                return ms.ToArray();            }        }



最后,为了看得更清楚,附上完整的源代码

 //声明变量,指向有摄像有拍摄的照片或影片        StorageFile file = null;        public MainPage()        {            this.InitializeComponent();        }        /// <summary>        /// 在此页将要在 Frame 中显示时进行调用。        /// </summary>        /// <param name="e">描述如何访问此页的事件数据。Parameter        /// 属性通常用于配置页。</param>        protected override void OnNavigatedTo(NavigationEventArgs e)        {        }        //拍照        private async void Button_Click_1(object sender, RoutedEventArgs e)        {            /*CameraCaptureUI类负责启动摄像头,并捕获照摄像头拍摄的照片             要想启动摄像头,需打开Package.appxmanifest文件,切换到“功能”界面,             勾选网络摄像机和麦克风*/            CameraCaptureUI dialog = new CameraCaptureUI();            Size aspectRatio = new Size(16, 9);            /*设定摄像头拍摄照片的高宽比,拍照完成之后就能看到效果,可以通过修改高宽比             来查看不同的效果*/            dialog.PhotoSettings.CroppedAspectRatio = aspectRatio;            /*CaptureFileAsync方法负责启动摄像有并拍摄照片或拍摄影片,其返回值为拍摄的照片或拍摄的影片.             CameraCaptureUIMode是个枚举,设置拍摄的是照片还是影片*/            file = await dialog.CaptureFileAsync(CameraCaptureUIMode.Photo);            if (file != null)            {                /*BitmapImage类是ImageSource类的子类,用来将图片填充到Image控件中*/                BitmapImage bitmapImage = new BitmapImage();                /*使用OpenAsync打开拍摄的照片,返回流filestream*/                using (IRandomAccessStream fileStream = await file.OpenAsync(FileAccessMode.Read))                {                    //设置bitmapImage的图片源为拍摄的照片                    bitmapImage.SetSource(fileStream);                }                //将照片显示到图片控件中                CapturedPhoto.Source = bitmapImage;            }        }        //保存图片,为了显得正式些,使用了AppBar        private async void btnSave_Click_1(object sender, RoutedEventArgs e)        {            //实例化文件选取器            FileSavePicker picker = new FileSavePicker();            //设置图片保存的类型            picker.FileTypeChoices.Add("image file", new List<string>() { ".jpg",".png" });            /*返回文件选取器返回的新建的文件:调用PickSaveFileAsync方法后会在制定的位置            创建制定名称制定格式的文件*/            StorageFile storageFile = await picker.PickSaveFileAsync();            //打开通过摄像头拍摄的照片,并返回流,以流的形式读取文件            var StreamRandom = await file.OpenAsync(FileAccessMode.Read);            //将拍摄的照片以流的方式读取到缓冲区            IBuffer buffer = RandomAccessStreamToBuffer(StreamRandom);            //将缓冲区的内容(拍摄的照片)写入到新建的文件中            await FileIO.WriteBufferAsync(storageFile, buffer);        }        //将图片写入到缓冲区        private IBuffer RandomAccessStreamToBuffer(IRandomAccessStream randomstream)        {            Stream stream = WindowsRuntimeStreamExtensions.AsStreamForRead(randomstream.GetInputStreamAt(0));            MemoryStream memoryStream = new MemoryStream();            if (stream != null)            {                byte[] bytes = ConvertStreamTobyte(stream);                if (bytes != null)                {                    var binaryWriter = new BinaryWriter(memoryStream);                    binaryWriter.Write(bytes);                }            }            IBuffer buffer = WindowsRuntimeBufferExtensions.GetWindowsRuntimeBuffer(memoryStream, 0, (int)memoryStream.Length);            return buffer;        }        //将流转换成二进制        public static byte[] ConvertStreamTobyte(Stream input)        {            byte[] buffer = new byte[16 * 1024];            using (MemoryStream ms = new MemoryStream())            {                int read;                while ((read = input.Read(buffer, 0, buffer.Length)) > 0)                {                    ms.Write(buffer, 0, read);                }                return ms.ToArray();            }        }