Pull to refresh

Фонарик для Windows Phone 7

Reading time 4 min
Views 4.5K

Предисловие


Купил себе виндофон и решил попробовать написать что-нибудь под него, тем более, что с .NET знаком по роду деятельности. Идею подсказал товарищ с android-приложением фонарик, источником света которого являлась LED вспышка.


Первое решение


Почитал msdn, все показалось просто. Создаем объект Microsoft.Devices.PhotoCamera; смотрим, поддерживает ли наше устройство фото-вспышку; если поддерживает, то переключаем PhotoCamera.FlashMode, по нажатию кнопки. Как сказал бы Ливанов: «Элементарно, Ватсон!». Но не тут-то было.

Первый момент, который меня озадачил — инициализация камеры. Просто создать объект Microsoft.Devices.PhotoCamera не достаточно. Для этих целей, в уже знакомой статье на msdn, используется установка созданного объекта камеры в качестве источника для VideoBrush. Это излишняя нагрузка, как мне кажется, но других способов я не нашел (может кто-то из читающих подскажет). К слову сказать, плотно и не искал, ибо мною двигала другая цель.

А вот второй момент поставил в тупик описываемый вариант решение. В результате, по нажатию кнопки, мы видим, что дисплей подсвечивается, а LED-вспышка работать не желает. Чтож, печалька.


Второе решение


Начинаем копать дальше… С удивлением узнаю у гугла, что ребята из Microsoft скрыли от непросвещенных некоторые сборки (вот негодяи).

Нашел умельца на codeproject, который хакнул камеру WP7 с помощью скрытых от посторонних глаз возможностей. Но не столь интересен сам пост, сколько ссылки, которые он предоставляет в общее пользование. Идея состоит в том, что бы, как описано в Tom's blog, сделать необходимые сборки доступными и воспользоваться для подсветки, как советует Clarity Consulting Blog, Microsoft.Devices.VideoCamera.


Реализация


Итак, информации более чем достаточно, приступим к делу. В Tom's blog говориться, что легче всего достать необходимые сборки из «Emulator BIN» или скачать его собственный дамп. Что такое «Emulator BIN» я не понял и долго заморачиваться не стал, воспользовался его наработкой. Берем из архива GAC_Microsoft.Phone.Media.Extended_v7_0_0_0_cneutral_1.dll и, чтобы нам легче было добавлять ссылки в следующий раз на эту сборку, копируем в папку "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\Silverlight\v4.0\Profile\WindowsPhone71" (нужны права администратора) с именем Microsoft.Phone.Media.Extended.dll. Естественно, у кого ОС стоит на другом разделе или не 64-разрядная, будут небольшие вариации.
Затем открываем папку с именем RedistList (она лежит в той же директории, что и скопированный только что файл), а в ней файл FrameworkList.xml. Его нужно отредактировать (я это делал в фаре, ибо папка со специфическими правами доступа). Копируем произвольный узел File, например для AssemblyName=«Microsoft.Phone.Interop», удаляем во вновь скопированном узле PublicKeyToken и меняем AssemblyName на Microsoft.Phone.Media.Extended.
Теперь нужно открыть visual studio command prompt и выполнить команду sn -Vr Microsoft.Phone.Media.Extended.dll, иначе у нас при построении проекта с этой сборкой будут ошибки.


Теперь самое приятное — создание приложения. Достаточно создать обычный Silverlight проект для WP7 и добавить сборку Microsoft.Phone.Media.Extended. В нем будет довольно простенькая разметка, единственное, что здесь достойно внимания, так это контрол CameraVisualizer, он отображает захваченное с камеры изображение (но мы-то помним, что он нам нужен только для инициализации объекта камеры). И чтобы нас не отвлекала картинка на дисплее установим этому элементу полную непрозрачность.
Вот разметка


<phone:PhoneApplicationPage 
    x:Class="PhoneApp1.MainPage"
    ...
    xmlns:media="clr-namespace:Microsoft.Phone;assembly=Microsoft.Phone.Media.Extended"
    ...
    shell:SystemTray.IsVisible="False">
    <Grid x:Name="LayoutRoot" Background="Transparent">
        <media:CameraVisualizer x:Name="_cameraVisualizer" Opacity="0" />
        <Button x:Name="_btnFlash" Click="ButtonClick" IsEnabled="false">
            <Button.Content>
                <Image VerticalAlignment="Center" HorizontalAlignment="Center" Width="300" Height="300" Source="Power_On_Off.png"/>
            </Button.Content>
        </Button>
    </Grid>
</phone:PhoneApplicationPage>


Так же интересным фактором является то, что в коде необходимо указать на необходимость использовать LED вспышку _videoCamera.LampEnabled = true; и то, что фонарик начинает работать только во время записи с камеры. Точнее говоря, самой записи не будет, то есть поток данных не будет занимать физического пространства.


using System.Windows;
using Microsoft.Phone;

namespace PhoneApp1
{
    public partial class MainPage
    {
        private VideoCamera _videoCamera;

        public MainPage()
        {
            InitializeComponent();
        }

        protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
        {
            base.OnNavigatedTo(e);
            InitializeCamera();
        }

        protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
        {
            base.OnNavigatedFrom(e);
            _videoCamera.Dispose();
            _videoCamera = null;
        }

        private void InitializeCamera()
        {
            _videoCamera = new VideoCamera(); //  Создание объекта камеры
            _videoCamera.Initialized += VideoCameraInitialized;
            _cameraVisualizer.SetSource(_videoCamera);// Инициализация объекта камеры
        }

        void VideoCameraInitialized(object sender, System.EventArgs e)
        {
            _videoCamera.Initialized -= VideoCameraInitialized;
            _videoCamera.LampEnabled = true; // Да будет свет!!!
            Dispatcher.BeginInvoke(() => { _btnFlash.IsEnabled = true; });
        }

        private void ButtonClick(object sender, RoutedEventArgs e)
        {
            // Когда идет запись, фонарик работает. При прекращении записи, он отключается.
            if (_videoCamera.IsRecording)
                _videoCamera.StopRecording();
            else
                _videoCamera.StartRecording();
        }
    }
}


PS: Конструктивная критика в адрес первого топика и моего стиля изложения приветствуется.

Используемые источники


1 msdn
2 codeproject
3 Tom's blog
4 Clarity Consulting Blog
5 xda-developers


UPD Дамы и господа, я прекрасно понимаю, что статья кому-то понравилась, кому-то нет. Но в личку пишут только те, кто положительно отнеслись к посту в целом, но имеют замечания по тем или иным моментам. Убедительная просьба — если минусуете, оставляйте отзыв что не понравилось. Для меня важно на первом этапе понять, что я делаю не так.
Tags:
Hubs:
+50
Comments 26
Comments Comments 26

Articles