Предисловие
Купил себе виндофон и решил попробовать написать что-нибудь под него, тем более, что с .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 Дамы и господа, я прекрасно понимаю, что статья кому-то понравилась, кому-то нет. Но в личку пишут только те, кто положительно отнеслись к посту в целом, но имеют замечания по тем или иным моментам. Убедительная просьба — если минусуете, оставляйте отзыв что не понравилось. Для меня важно на первом этапе понять, что я делаю не так.
