酢ろぐ!

カレーが嫌いなスマートフォンアプリプログラマのブログ。

Windows Phone OS 7.0でPhotoCameraクラスを使ってカメラプレビューを扱う

Windows Phone OS 7.0では開発者は自由にカメラの操作をおこなうことができません。非公式なライブラリの Microsoft.Phone.Media.Extended.dll を使ってカメラ機能を使用することができます。

概要

PhotoCameraクラスはMicrosoft.Phone.Media.Extended.dll に含まれるクラスです。非公式ながらWindows Phone OS 7.0でカメラ機能を使用する事が出来ます。

注意 Windows Phone OS 7.1以降の場合、PhotoCameraクラスを利用することで、カメラプレビュー中のフレームを扱うことが出来ます。

名前空間:Microsoft.Phone

Tips

Windows Phone OS 7.0でカメラプレビューを扱う

Windows Phone OS 7.0のSilverlightは、Silverlight 3ベースのサブセットでありSilverlight 4からサポートとなったカメラプレビューを直接扱う事が出来ないはずです。

メーカー製のアプリケーションでは、カメラプレビューを扱ったアプリがリリースされていました。海外のハッカーがアプリを解析して、カメラプレビューを使うには、Microsoft.Phone.Media.Extended.dllを使えば良いらしいというところまでが分かっていました。

今回、実際に試してみたのでその方法を紹介したいと思います。カメラプレビューをSilverlightで扱うためには、まずMicrosoft.Phone.Media.Extended.dllをプロジェクトへ参照の追加します。次にWMAppManifest.xmlで定義されているCapabilitiesに`ID_CAP_CAMERA`を付与します。

WMAppManifest.xml

マニフェストに「ID_CAP_CAMERA」を追加します。

<?xml version="1.0" encoding="utf-8"?>

<Deployment xmlns="http://schemas.microsoft.com/windowsphone/2009/deployment" AppPlatformVersion="7.0">
  <App xmlns="" ProductID="{cf343ff5-ae42-4517-a0ff-89570013e092}" Title="MediaExtendedTest" 
     RuntimeType="Silverlight" Version="1.0.0.0" Genre="apps.normal"
     Author="MediaExtendedTest author" Description="Sample description" 
     Publisher="MediaExtendedTest">

    <IconPath IsRelative="true" IsResource="false">ApplicationIcon.png</IconPath>
    <Capabilities>
      <Capability Name="ID_CAP_GAMERSERVICES"/>
      <Capability Name="ID_CAP_IDENTITY_DEVICE"/>
      <Capability Name="ID_CAP_IDENTITY_USER"/>
      <Capability Name="ID_CAP_LOCATION"/>
      <Capability Name="ID_CAP_MEDIALIB"/>
      <Capability Name="ID_CAP_MICROPHONE"/>
      <Capability Name="ID_CAP_NETWORKING"/>
      <Capability Name="ID_CAP_PHONEDIALER"/>
      <Capability Name="ID_CAP_PUSH_NOTIFICATION"/>
      <Capability Name="ID_CAP_SENSORS"/>
      <Capability Name="ID_CAP_WEBBROWSERCOMPONENT"/>
      <Capability Name="ID_CAP_CAMERA"/> <!--  ←★ここに追記 -->
    </Capabilities>
    <Tasks>
      <DefaultTask  Name ="_default" NavigationPage="MainPage.xaml"/>
    </Tasks>
    <Tokens>
      <PrimaryToken TokenID="MediaExtendedTestToken" TaskName="_default">
        <TemplateType5>
          <BackgroundImageURI IsRelative="true" IsResource="false">Background.png</BackgroundImageURI>
          <Count>0</Count>
          <Title>MediaExtendedTest</Title>
        </TemplateType5>
      </PrimaryToken>
    </Tokens>
  </App>
</Deployment>

この`ID_CAP_CAMERA`を付与してしまうと、権限を持ったApp Hubのアカウントでないと、自動テストの部分でチェックを落とされてしまうようです(参考:QRコードをリアルタイムで読めるアプリ作ったら審査にすら進めなかった)。

MainPage.xaml

Microsoft.Phone名前空間のCameraVisualizerを配置します。プログラム上から表示の角度を変更できるように、`cameraVisualizer`と名前を付けました。

<phone:PhoneApplicationPage 
    x:Class="MediaExtendedTest.MainPage"
    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"
    xmlns:media="clr-namespace:Microsoft.Phone;assembly=Microsoft.Phone.Media.Extended"
    mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"
    FontFamily="{StaticResource PhoneFontFamilyNormal}"
    FontSize="{StaticResource PhoneFontSizeNormal}"
    Foreground="{StaticResource PhoneForegroundBrush}"
    SupportedOrientations="Portrait" Orientation="Portrait"
    shell:SystemTray.IsVisible="True">

    <!--LayoutRoot is the root grid where all page content is placed-->
    <Grid x:Name="LayoutRoot" Background="Transparent">

        <!--TitlePanel contains the name of the application and page title-->
        <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="500,17,0,28">
            <media:CameraVisualizer x:Name="cameraVisualizer">
                <media:CameraVisualizer.RenderTransform>
                    <CompositeTransform Rotation="0"/>
                </media:CameraVisualizer.RenderTransform>
            </media:CameraVisualizer>
        </StackPanel>

    </Grid> 
</phone:PhoneApplicationPage>

MainPage.xaml.cs

センサーから取り込んだ画像をそのまま表示しているのだと思いますが、カメラセンサーが90度回転した状態で付けられており、表示側のElementの表示を90度回転させないと正しい方向で写りませんでした。

Microsoft.Phone名前空間のPhotoCameraクラスのインスタンスをcameraVisualizerに設定すればカメラプレビューが開始されます。

CompositeTransform cameraTrans = cameraVisualizer.RenderTransform as CompositeTransform;
cameraTrans.Rotation = 90;

var photo = new Microsoft.Phone.PhotoCamera();
cameraVisualizer.SetSource(photo);

PhotoCameraの部分をVideoCameraに差換えても動くと思います。写真撮影の時は高解像度で撮影するけれど、動画録画の時はそれに比べて低解像度です。おそらくカメラセンサーへの設定の切り分けをしているのだと思います。

参照

関連記事