與眾不同 windows phone (42) - 8.0 相機和照片: 通過 PhotoCaptureDevice 捕獲照片


[源碼下載]


與眾不同 windows phone (42) - 8.0 相機和照片: 通過 PhotoCaptureDevice 捕獲照片



作者:webabcd


介紹
與眾不同 windows phone 8.0 之 相機和照片

  • 通過 PhotoCaptureDevice 捕獲照片



示例
演示 PhotoCaptureDevice(wp8)的應用
CameraAndPhoto/PhotoCaptureDeviceDemo.xaml

<phone:PhoneApplicationPage
    x:Class="Demo.CameraAndPhoto.PhotoCaptureDeviceDemo"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    FontFamily="{StaticResource PhoneFontFamilyNormal}"
    FontSize="{StaticResource PhoneFontSizeNormal}"
    Foreground="{StaticResource PhoneForegroundBrush}"
    SupportedOrientations="Portrait" Orientation="Portrait"
    mc:Ignorable="d"
    shell:SystemTray.IsVisible="True">

    <Grid x:Name="LayoutRoot" Background="Transparent">
        <StackPanel>
            
            <StackPanel Orientation="Horizontal">
                <Canvas Width="240" Height="180" RenderTransformOrigin="0.5 0.5">
                    <Canvas.Background>
                        <VideoBrush x:Name="videoBrush" />
                    </Canvas.Background>
                    <Canvas.RenderTransform>
                        <RotateTransform x:Name="rt" />
                    </Canvas.RenderTransform>
                </Canvas>
                <Image Name="imgPreview" Width="240" Height="180" />
            </StackPanel>

            <StackPanel Orientation="Horizontal" Margin="0 50 0 0">
                <Button Name="btnCapture" Content="照相"  Click="btnCapture_Click" />
                <Button Name="btnFocus" Content="自動對焦" Click="btnFocus_Click" />
            </StackPanel>

            <TextBlock x:Name="lblMsg" TextWrapping="Wrap" Margin="0 10 0 0" />
            
        </StackPanel>
    </Grid>

</phone:PhoneApplicationPage>


CameraAndPhoto/PhotoCaptureDeviceDemo.xaml.cs

/*
 * 演示 PhotoCaptureDevice(wp8)的應用
 * 
 * 關於 PhotoCamera(wp7)的應用參見
 * http://www.cnblogs.com/webabcd/archive/2012/08/13/2635698.html
 * http://www.cnblogs.com/webabcd/archive/2012/08/15/2639428.html
 * 
 * 
 * 注:
 * 需要在 manifest 中增加配置 <Capability Name="ID_CAP_ISV_CAMERA" /> <Capability Name="ID_CAP_MEDIALIB_PHOTO" />
 */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using Microsoft.Phone.Controls;
using Windows.Phone.Media.Capture;
using Microsoft.Devices;
using System.IO;
using Microsoft.Xna.Framework.Media;
using Microsoft.Phone;

namespace Demo.CameraAndPhoto
{
    public partial class PhotoCaptureDeviceDemo : PhoneApplicationPage
    {
        private PhotoCaptureDevice _captureDevice;

        public PhotoCaptureDeviceDemo()
        {
            InitializeComponent();

            this.Loaded += PhotoCaptureDeviceDemo_Loaded;
        }

        private async void PhotoCaptureDeviceDemo_Loaded(object sender, RoutedEventArgs e)
        {
            // 一些概述類的說明
            Summary();

            // 是否有后置攝像頭
            if (PhotoCaptureDevice.AvailableSensorLocations.Contains(CameraSensorLocation.Back))
            {
                // 獲取后置攝像頭照相時的可用分辨率
                IReadOnlyList<Windows.Foundation.Size> supportedResolutions = PhotoCaptureDevice.GetAvailableCaptureResolutions(CameraSensorLocation.Back);
                Windows.Foundation.Size resolution = supportedResolutions[0];

                try
                {
                    // 讓后置攝像頭以指定的分辨率捕獲鏡頭內容
                    _captureDevice = await PhotoCaptureDevice.OpenAsync(CameraSensorLocation.Back, resolution);


                    /*
                     * SetCaptureResolutionAsync() - 設置捕獲照片的分辨率
                     * SetPreviewResolutionAsync() - 設置捕獲照片的預覽圖的分辨率
                     * CaptureResolution - 獲取當前捕獲的分辨率
                     * PreviewResolution - 獲取當前捕獲的預覽圖的分辨率
                     * FocusRegion - 對焦區域
                     * SensorLocation - 當前攝像頭的位置(CameraSensorLocation 枚舉:Back 或 Front)
                     * SensorRotationInDegrees - 獲取照相機傳感器相對於屏幕的旋轉度數
                     */


                    /*
                     * KnownCameraPhotoProperties 屬性集包括
                     *     FlashMode - 閃光燈模式:FlashState.On, FlashState.Auto, FlashState.Off
                     *     FlashPower - 閃光亮度,無單位且不同設備上的值不同
                     *     FocusIlluminationMode - 閃光燈的對焦方式:FocusIlluminationMode.Auto, FocusIlluminationMode.Off, FocusIlluminationMode.On
                     *     ExposureCompensation - 曝光補償,單位:1/6 EV
                     *     ExposureTime - 曝光時間,單位:微秒
                     *     ManualWhiteBalance - 手動設置白平衡
                     *     WhiteBalancePreset - 設置預置白平衡(WhiteBalancePreset 枚舉,包括多雲、熒光燈等等)
                     *     LockedAutoFocusParameters - 自動對焦、自動曝光或自動白平衡參數(AutoFocusParameters 枚舉,有 flag 標記)
                     *         AutoFocusParameters.None - 對焦、曝光和白平衡全自動
                     *         AutoFocusParameters.Focus - 暫停自動對焦
                     *         AutoFocusParameters.Exposure - 暫停自動曝光
                     *         AutoFocusParameters.WhiteBalance - 暫停自動白平衡
                     *     Iso - 感光度
                     *     SceneMode - 場景模式(CameraSceneMode 枚舉,包括人像優化、夜景優化等等)
                     */
                    _captureDevice.SetProperty(KnownCameraPhotoProperties.FlashMode, FlashState.On);


                    /*
                     * KnownCameraGeneralProperties 屬性集包括
                     *     AutoFocusRange - 自動對焦的范圍(AutoFocusRange 枚舉,包括微距等)
                     *     EncodeWithOrientation - 照片捕獲完成后編碼時的旋轉角度,必須是 90 的倍數
                     *     SpecifiedCaptureOrientation -  照片捕獲完成后照片元數據中的旋轉角度,必須是 90 的倍數
                     *     IsShutterSoundEnabledByUser - 用戶是否啟用了快門聲音,只讀
                     *     IsShutterSoundRequiredForRegion - 運行應用程序的區域是否需要快門聲音(有些區域為了保護隱私,要求照相或錄像必須要有快門聲音),只讀
                     *     PlayShutterSoundOnCapture - 指定捕獲時是否播放快門聲音
                     *     ManualFocusPosition - 手動對焦的位置
                     */
                    _captureDevice.SetProperty(KnownCameraGeneralProperties.AutoFocusRange, AutoFocusRange.Normal);
                    _captureDevice.SetProperty(KnownCameraGeneralProperties.EncodeWithOrientation, _captureDevice.SensorRotationInDegrees);


                    // 獲取指定屬性的值
                    // _captureDevice.GetProperty(KnownCameraGeneralProperties.IsShutterSoundEnabledByUser);

                    /*
                     * 獲取指定的范圍類屬性在當前相機中所允許的值的范圍
                     */
                    // PhotoCaptureDevice.GetSupportedPropertyRange(CameraSensorLocation.Back, KnownCameraPhotoProperties.ExposureCompensation);

                    /*
                     * 獲取指定的值類屬性在當前相機中所允許的值的列表
                     */
                    // PhotoCaptureDevice.GetSupportedPropertyValues(CameraSensorLocation.Back, KnownCameraPhotoProperties.FlashMode);

                    // 實時顯示捕獲的內容
                    videoBrush.SetSource(_captureDevice); // 擴展方法來自:Microsoft.Devices.CameraVideoBrushExtensions

                    rt.Angle = _captureDevice.SensorRotationInDegrees;
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString());
                }
            }
            else
            {
                MessageBox.Show("沒有后置攝像頭");
            }
        }

        // 照相
        private async void btnCapture_Click(object sender, RoutedEventArgs e)
        {
            // 創建捕獲序列,目前系統僅支持單幀捕獲
            CameraCaptureSequence seq = _captureDevice.CreateCaptureSequence(1);

            // 設置序列中的指定幀的 KnownCameraPhotoProperties 屬性和 KnownCameraGeneralProperties 屬性
            // seq.Frames[0].DesiredProperties[KnownCameraPhotoProperties.FlashMode] = FlashState.On;
            // seq.Frames[0].DesiredProperties[KnownCameraGeneralProperties.AutoFocusRange] = AutoFocusRange.Infinity;

            // 捕獲到的圖片的內存流
            MemoryStream captureStream = new MemoryStream();
            // 捕獲到的圖片的預覽圖的內存流
            MemoryStream captureStreamPreview = new MemoryStream();

            // 設置捕獲到的圖片的內存流
            seq.Frames[0].CaptureStream = captureStream.AsOutputStream();
            // 設置捕獲到的圖片的預覽圖的內存流
            seq.Frames[0].ThumbnailStream = captureStreamPreview.AsOutputStream();

            try
            {
                // 根據捕獲序列的設置,准備好捕獲前的相關數據
                await _captureDevice.PrepareCaptureSequenceAsync(seq);

                // 開始捕獲
                await seq.StartCaptureAsync();

                captureStream.Position = 0;
                captureStreamPreview.Position = 0;

                // 保存捕獲到的圖片到“本機照片”
                MediaLibrary library = new MediaLibrary();
                Picture picture = library.SavePictureToCameraRoll("xxx.jpg", captureStream); // 如果有重名,會自動重命名

                // 顯示捕獲到的圖片的預覽圖(也可以通過 picture.GetThumbnail() 來獲取預覽圖)
                imgPreview.Source = PictureDecoder.DecodeJpeg(captureStreamPreview);

                lblMsg.Text += "拍照完成,且已保存到照片中心";
                lblMsg.Text += System.Environment.NewLine;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }

            captureStream.SetLength(0);
            captureStreamPreview.SetLength(0);

            captureStream.Dispose();
            captureStreamPreview.Dispose();
        }

        // 自動對焦
        private async void btnFocus_Click(object sender, RoutedEventArgs e)
        {
            // 啟動自動對焦、自動曝光和自動白平衡,參考 LockedAutoFocusParameters
            CameraFocusStatus status = await _captureDevice.FocusAsync();
            lblMsg.Text += status.ToString();
            lblMsg.Text += System.Environment.NewLine;

            // 復位對焦
            // _captureDevice.ResetFocusAsync();
        }


        private void Summary()
        {
            lblMsg.Text = "";

            // 獲取電話上的可用相機
            foreach (CameraSensorLocation csl in PhotoCaptureDevice.AvailableSensorLocations)
            {
                // Back 或 Front
                lblMsg.Text += "攝像頭:" + csl.ToString();
                lblMsg.Text += System.Environment.NewLine;


                // 捕獲所支持的分辨率
                lblMsg.Text += "捕獲照片的可用分辨率:";
                foreach (var size in PhotoCaptureDevice.GetAvailableCaptureResolutions(csl))
                {
                    lblMsg.Text += size.Width + "*" + size.Height + " ";
                }
                lblMsg.Text += System.Environment.NewLine;


                // 捕獲后的預覽圖所支持的分辨率
                lblMsg.Text += "捕獲照片的預覽圖的可用分辨率:";
                foreach (var size in PhotoCaptureDevice.GetAvailablePreviewResolutions(csl))
                {
                    lblMsg.Text += size.Width + "*" + size.Height + " ";
                }
                lblMsg.Text += System.Environment.NewLine;


                lblMsg.Text += "是否支持自動對焦:" + PhotoCaptureDevice.IsFocusSupported(csl);
                lblMsg.Text += System.Environment.NewLine;
                lblMsg.Text += "是否支持以編程方式自動對焦:" + PhotoCaptureDevice.IsFocusRegionSupported(csl);
                lblMsg.Text += System.Environment.NewLine;
                lblMsg.Text += System.Environment.NewLine;


                // 關於 CameraButtons 參見以前的文章:http://www.cnblogs.com/webabcd/archive/2012/08/15/2639428.html
                // CameraButtons.ShutterKeyHalfPressed 事件,CameraButtons.ShutterKeyPressed 事件,CameraButtons.ShutterKeyReleased 事件
            }
        }
    }
}



OK
[源碼下載]


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM