Transform selection implemented in sample GUI.
Gistogram output does not work propertly due color conversion problems.
This commit is contained in:
parent
de9f659f1e
commit
bf22567c09
@ -33,38 +33,31 @@
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock TextWrapping="Wrap" Grid.Row="0" Text="This scenario shows how to enumerate cameras in the system. Choose a camera from the list to preview, record or take a photo from the chosen camera. You can add the gray scale effect using the checkbox provided." Style="{StaticResource BasicTextStyle}" HorizontalAlignment="Left"/>
|
||||
<StackPanel Orientation="Horizontal" Grid.Row="1" Margin="0,10,0,0">
|
||||
<ListBox x:Name="EnumedDeviceList2" SelectionChanged="lstEnumedDevices_SelectionChanged" ></ListBox>
|
||||
<Button x:Name="btnStartDevice2" Click="btnStartDevice_Click" IsEnabled="true" Margin="0,0,10,0">StartDevice</Button>
|
||||
<Button x:Name="btnStartPreview2" Click="btnStartPreview_Click" IsEnabled="true" Margin="0,0,10,0">StartPreview</Button>
|
||||
<Button x:Name="btnStartStopRecord2" Click="btnStartStopRecord_Click" IsEnabled="false" Margin="0,0,10,0">StartRecord</Button>
|
||||
<Button x:Name="btnTakePhoto2" Click="btnTakePhoto_Click" IsEnabled="false" Margin="0,0,10,0">TakePhoto</Button>
|
||||
</StackPanel>
|
||||
<StackPanel Orientation="Horizontal" Grid.Row="2" Margin="0,10,0,0">
|
||||
<CheckBox x:Name="chkAddRemoveEffect" Margin="0,0,10,0" Content="Add Effect" IsEnabled="False" Checked="chkAddRemoveEffect_Checked" Unchecked="chkAddRemoveEffect_Unchecked"/>
|
||||
<ComboBox Width="120"/>
|
||||
<ListBox x:Name="EnumedDeviceList2" SelectionChanged="lstEnumedDevices_SelectionChanged" />
|
||||
<Button x:Name="btnStartDevice2" Click="btnStartDevice_Click" IsEnabled="true" Margin="0,0,10,0" Content="StartDevice"/>
|
||||
<Button x:Name="btnStartPreview2" Click="btnStartPreview_Click" IsEnabled="true" Margin="0,0,10,0" Content="StartPreview"/>
|
||||
<ComboBox x:Name="EffectTypeCombo" Width="120" SelectedIndex="0">
|
||||
<ComboBoxItem Content="Preview"/>
|
||||
<ComboBoxItem Content="Grayscale"/>
|
||||
<ComboBoxItem Content="Canny"/>
|
||||
<ComboBoxItem Content="Sobel"/>
|
||||
<ComboBoxItem Content="Histogram"/>
|
||||
</ComboBox>
|
||||
<Button Content="Apply" HorizontalAlignment="Stretch" VerticalAlignment="Top" Click="Button_Click"/>
|
||||
</StackPanel>
|
||||
<StackPanel x:Name="EffectTypeCombo1" Orientation="Horizontal" Grid.Row="1" Margin="324,5,-324,7"/>
|
||||
</Grid>
|
||||
|
||||
<Grid x:Name="Output" HorizontalAlignment="Left" VerticalAlignment="Top" Grid.Row="1">
|
||||
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
|
||||
<StackPanel>
|
||||
<TextBlock Style="{StaticResource BasicTextStyle}" HorizontalAlignment='Center' VerticalAlignment='Center' TextAlignment='Center' Text='Preview' />
|
||||
<Canvas x:Name="previewCanvas2" Width="320" Height="240" Background="Gray">
|
||||
<CaptureElement x:Name="previewElement2" Width="320" Height="240" />
|
||||
</Canvas>
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Style="{StaticResource BasicTextStyle}" HorizontalAlignment='Center' VerticalAlignment='Center' TextAlignment='Center' Text='Captured Video' />
|
||||
<Canvas x:Name='playbackCanvas2' Width='320' Height ='240' >
|
||||
<MediaElement x:Name='playbackElement2' Width="320" Height="240" />
|
||||
</Canvas>
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Style="{StaticResource BasicTextStyle}" HorizontalAlignment='Center' VerticalAlignment='Center' TextAlignment='Center' Text='Captured Images' />
|
||||
<Canvas x:Name="imageCanvas2" Width='320' Height ='240' >
|
||||
<Image x:Name="imageElement2" Width="320" Height="240"/>
|
||||
<Canvas x:Name="previewCanvas2" Background="Gray">
|
||||
<CaptureElement x:Name="previewElement2" />
|
||||
</Canvas>
|
||||
</StackPanel>
|
||||
<StackPanel/>
|
||||
<StackPanel/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
|
@ -23,6 +23,7 @@ using namespace Windows::UI::Xaml::Navigation;
|
||||
using namespace Windows::UI::Xaml::Data;
|
||||
using namespace Windows::System;
|
||||
using namespace Windows::Foundation;
|
||||
using namespace Windows::Foundation::Collections;
|
||||
using namespace Platform;
|
||||
using namespace Windows::UI;
|
||||
using namespace Windows::UI::Core;
|
||||
@ -80,7 +81,6 @@ void AdvancedCapture::OnNavigatedTo(NavigationEventArgs^ e)
|
||||
// A pointer back to the main page. This is needed if you want to call methods in MainPage such
|
||||
// as NotifyUser()
|
||||
rootPage = MainPage::Current;
|
||||
m_eventRegistrationToken = Windows::Media::MediaControl::SoundLevelChanged += ref new EventHandler<Object^>(this, &AdvancedCapture::SoundLevelChanged);
|
||||
|
||||
m_orientationChangedEventToken = Windows::Graphics::Display::DisplayProperties::OrientationChanged += ref new Windows::Graphics::Display::DisplayPropertiesEventHandler(this, &AdvancedCapture::DisplayProperties_OrientationChanged);
|
||||
}
|
||||
@ -96,18 +96,12 @@ void AdvancedCapture::ScenarioInit()
|
||||
rootPage = MainPage::Current;
|
||||
btnStartDevice2->IsEnabled = true;
|
||||
btnStartPreview2->IsEnabled = false;
|
||||
btnStartStopRecord2->IsEnabled = false;
|
||||
m_bRecording = false;
|
||||
m_bPreviewing = false;
|
||||
m_bEffectAdded = false;
|
||||
btnStartStopRecord2->Content = "StartRecord";
|
||||
btnTakePhoto2->IsEnabled = false;
|
||||
previewElement2->Source = nullptr;
|
||||
playbackElement2->Source = nullptr;
|
||||
imageElement2->Source= nullptr;
|
||||
ShowStatusMessage("");
|
||||
chkAddRemoveEffect->IsChecked = false;
|
||||
chkAddRemoveEffect->IsEnabled = false;
|
||||
EffectTypeCombo->IsEnabled = false;
|
||||
previewCanvas2->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
|
||||
EnumerateWebcamsAsync();
|
||||
m_bSuspended = false;
|
||||
@ -119,104 +113,6 @@ void AdvancedCapture::ScenarioReset()
|
||||
ScenarioInit();
|
||||
}
|
||||
|
||||
void AdvancedCapture::SoundLevelChanged(Object^ sender, Object^ e)
|
||||
{
|
||||
create_task(Dispatcher->RunAsync(Windows::UI::Core::CoreDispatcherPriority::High, ref new Windows::UI::Core::DispatchedHandler([this]()
|
||||
{
|
||||
if(Windows::Media::MediaControl::SoundLevel != Windows::Media::SoundLevel::Muted)
|
||||
{
|
||||
ScenarioReset();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_bRecording)
|
||||
{
|
||||
ShowStatusMessage("Stopping Record on invisibility");
|
||||
|
||||
create_task(m_mediaCaptureMgr->StopRecordAsync()).then([this](task<void> recordTask)
|
||||
{
|
||||
try
|
||||
{
|
||||
recordTask.get();
|
||||
m_bRecording = false;
|
||||
}
|
||||
catch (Exception ^e)
|
||||
{
|
||||
ShowExceptionMessage(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (m_bPreviewing)
|
||||
{
|
||||
ShowStatusMessage("Stopping Preview on invisibility");
|
||||
|
||||
create_task(m_mediaCaptureMgr->StopPreviewAsync()).then([this](task<void> previewTask)
|
||||
{
|
||||
try
|
||||
{
|
||||
previewTask.get();
|
||||
m_bPreviewing = false;
|
||||
|
||||
}catch (Exception ^e)
|
||||
{
|
||||
ShowExceptionMessage(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
})));
|
||||
}
|
||||
|
||||
void AdvancedCapture::RecordLimitationExceeded(Windows::Media::Capture::MediaCapture ^currentCaptureObject)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (m_bRecording)
|
||||
{
|
||||
create_task(Dispatcher->RunAsync(Windows::UI::Core::CoreDispatcherPriority::High, ref new Windows::UI::Core::DispatchedHandler([this]()
|
||||
{
|
||||
try
|
||||
{
|
||||
ShowStatusMessage("Stopping Record on exceeding max record duration");
|
||||
EnableButton(false, "StartStopRecord");
|
||||
create_task(m_mediaCaptureMgr->StopRecordAsync()).then([this](task<void> recordTask)
|
||||
{
|
||||
try
|
||||
{
|
||||
recordTask.get();
|
||||
m_bRecording = false;
|
||||
SwitchRecordButtonContent();
|
||||
EnableButton(true, "StartStopRecord");
|
||||
ShowStatusMessage("Stopped record on exceeding max record duration:" + m_recordStorageFile->Path);
|
||||
}
|
||||
catch (Exception ^e)
|
||||
{
|
||||
ShowExceptionMessage(e);
|
||||
m_bRecording = false;
|
||||
SwitchRecordButtonContent();
|
||||
EnableButton(true, "StartStopRecord");
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (Exception ^e)
|
||||
{
|
||||
m_bRecording = false;
|
||||
SwitchRecordButtonContent();
|
||||
EnableButton(true, "StartStopRecord");
|
||||
ShowExceptionMessage(e);
|
||||
}
|
||||
})));
|
||||
}
|
||||
}
|
||||
catch (Exception ^e)
|
||||
{
|
||||
m_bRecording = false;
|
||||
SwitchRecordButtonContent();
|
||||
EnableButton(true, "StartStopRecord");
|
||||
ShowExceptionMessage(e);
|
||||
}
|
||||
}
|
||||
|
||||
void AdvancedCapture::Failed(Windows::Media::Capture::MediaCapture ^currentCaptureObject, Windows::Media::Capture::MediaCaptureFailedEventArgs^ currentFailure)
|
||||
{
|
||||
String ^message = "Fatal error" + currentFailure->Message;
|
||||
@ -267,8 +163,7 @@ void AdvancedCapture::btnStartDevice_Click(Platform::Object^ sender, Windows::UI
|
||||
EnableButton(true, "StartStopRecord");
|
||||
EnableButton(true, "TakePhoto");
|
||||
ShowStatusMessage("Device initialized successful");
|
||||
chkAddRemoveEffect->IsEnabled = true;
|
||||
mediaCapture->RecordLimitationExceeded += ref new Windows::Media::Capture::RecordLimitationExceededEventHandler(this, &AdvancedCapture::RecordLimitationExceeded);
|
||||
EffectTypeCombo->IsEnabled = true;
|
||||
mediaCapture->Failed += ref new Windows::Media::Capture::MediaCaptureFailedEventHandler(this, &AdvancedCapture::Failed);
|
||||
}
|
||||
catch (Exception ^ e)
|
||||
@ -317,192 +212,6 @@ void AdvancedCapture::btnStartPreview_Click(Platform::Object^ sender, Windows::U
|
||||
}
|
||||
}
|
||||
|
||||
void AdvancedCapture::btnTakePhoto_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
|
||||
{
|
||||
try
|
||||
{
|
||||
ShowStatusMessage("Taking photo");
|
||||
EnableButton(false, "TakePhoto");
|
||||
auto currentRotation = GetCurrentPhotoRotation();
|
||||
|
||||
task<StorageFile^>(KnownFolders::PicturesLibrary->CreateFileAsync(TEMP_PHOTO_FILE_NAME, Windows::Storage::CreationCollisionOption::GenerateUniqueName)).then([this, currentRotation](task<StorageFile^> getFileTask)
|
||||
{
|
||||
try
|
||||
{
|
||||
auto tempPhotoStorageFile = getFileTask.get();
|
||||
ShowStatusMessage("Create photo file successful");
|
||||
ImageEncodingProperties^ imageProperties = ImageEncodingProperties::CreateJpeg();
|
||||
|
||||
create_task(m_mediaCaptureMgr->CapturePhotoToStorageFileAsync(imageProperties, tempPhotoStorageFile)).then([this,tempPhotoStorageFile,currentRotation](task<void> photoTask)
|
||||
{
|
||||
try
|
||||
{
|
||||
photoTask.get();
|
||||
|
||||
ReencodePhotoAsync(tempPhotoStorageFile, currentRotation).then([this] (task<StorageFile^> reencodeImageTask)
|
||||
{
|
||||
try
|
||||
{
|
||||
auto photoStorageFile = reencodeImageTask.get();
|
||||
|
||||
EnableButton(true, "TakePhoto");
|
||||
ShowStatusMessage("Photo taken");
|
||||
|
||||
task<IRandomAccessStream^>(photoStorageFile->OpenAsync(FileAccessMode::Read)).then([this](task<IRandomAccessStream^> getStreamTask)
|
||||
{
|
||||
try
|
||||
{
|
||||
auto photoStream = getStreamTask.get();
|
||||
ShowStatusMessage("File open successful");
|
||||
auto bmpimg = ref new BitmapImage();
|
||||
|
||||
bmpimg->SetSource(photoStream);
|
||||
imageElement2->Source = bmpimg;
|
||||
}
|
||||
catch (Exception^ e)
|
||||
{
|
||||
ShowExceptionMessage(e);
|
||||
EnableButton(true, "TakePhoto");
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (Platform::Exception ^ e)
|
||||
{
|
||||
ShowExceptionMessage(e);
|
||||
EnableButton(true, "TakePhoto");
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (Platform::Exception ^ e)
|
||||
{
|
||||
ShowExceptionMessage(e);
|
||||
EnableButton(true, "TakePhoto");
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (Exception^ e)
|
||||
{
|
||||
ShowExceptionMessage(e);
|
||||
EnableButton(true, "TakePhoto");
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (Platform::Exception^ e)
|
||||
{
|
||||
ShowExceptionMessage(e);
|
||||
EnableButton(true, "TakePhoto");
|
||||
}
|
||||
}
|
||||
|
||||
void AdvancedCapture::btnStartStopRecord_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
|
||||
{
|
||||
try
|
||||
{
|
||||
String ^fileName;
|
||||
EnableButton(false, "StartStopRecord");
|
||||
|
||||
if (!m_bRecording)
|
||||
{
|
||||
ShowStatusMessage("Starting Record");
|
||||
|
||||
fileName = VIDEO_FILE_NAME;
|
||||
|
||||
PrepareForVideoRecording();
|
||||
|
||||
task<StorageFile^>(KnownFolders::VideosLibrary->CreateFileAsync(fileName, Windows::Storage::CreationCollisionOption::GenerateUniqueName)).then([this](task<StorageFile^> fileTask)
|
||||
{
|
||||
try
|
||||
{
|
||||
this->m_recordStorageFile = fileTask.get();
|
||||
ShowStatusMessage("Create record file successful");
|
||||
|
||||
MediaEncodingProfile^ recordProfile= nullptr;
|
||||
recordProfile = MediaEncodingProfile::CreateMp4(Windows::Media::MediaProperties::VideoEncodingQuality::Auto);
|
||||
|
||||
create_task(m_mediaCaptureMgr->StartRecordToStorageFileAsync(recordProfile, this->m_recordStorageFile)).then([this](task<void> recordTask)
|
||||
{
|
||||
try
|
||||
{
|
||||
recordTask.get();
|
||||
m_bRecording = true;
|
||||
SwitchRecordButtonContent();
|
||||
EnableButton(true, "StartStopRecord");
|
||||
|
||||
ShowStatusMessage("Start Record successful");
|
||||
}
|
||||
catch (Exception ^e)
|
||||
{
|
||||
m_bRecording = true;
|
||||
SwitchRecordButtonContent();
|
||||
EnableButton(true, "StartStopRecord");
|
||||
ShowExceptionMessage(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (Exception ^e)
|
||||
{
|
||||
m_bRecording = false;
|
||||
EnableButton(true, "StartStopRecord");
|
||||
ShowExceptionMessage(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowStatusMessage("Stopping Record");
|
||||
|
||||
create_task(m_mediaCaptureMgr->StopRecordAsync()).then([this](task<void> recordTask)
|
||||
{
|
||||
try
|
||||
{
|
||||
recordTask.get();
|
||||
m_bRecording = false;
|
||||
EnableButton(true, "StartStopRecord");
|
||||
SwitchRecordButtonContent();
|
||||
|
||||
ShowStatusMessage("Stop record successful");
|
||||
if (!m_bSuspended)
|
||||
{
|
||||
task<IRandomAccessStream^>(this->m_recordStorageFile->OpenAsync(FileAccessMode::Read)).then([this](task<IRandomAccessStream^> streamTask)
|
||||
{
|
||||
try
|
||||
{
|
||||
auto stream = streamTask.get();
|
||||
ShowStatusMessage("Record file opened");
|
||||
ShowStatusMessage(this->m_recordStorageFile->Path);
|
||||
playbackElement2->AutoPlay = true;
|
||||
playbackElement2->SetSource(stream, this->m_recordStorageFile->FileType);
|
||||
playbackElement2->Play();
|
||||
}
|
||||
catch (Exception ^e)
|
||||
{
|
||||
ShowExceptionMessage(e);
|
||||
m_bRecording = false;
|
||||
EnableButton(true, "StartStopRecord");
|
||||
SwitchRecordButtonContent();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (Exception ^e)
|
||||
{
|
||||
m_bRecording = false;
|
||||
EnableButton(true, "StartStopRecord");
|
||||
SwitchRecordButtonContent();
|
||||
ShowExceptionMessage(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (Platform::Exception^ e)
|
||||
{
|
||||
EnableButton(true, "StartStopRecord");
|
||||
ShowExceptionMessage(e);
|
||||
m_bRecording = false;
|
||||
SwitchRecordButtonContent();
|
||||
}
|
||||
}
|
||||
void AdvancedCapture::lstEnumedDevices_SelectionChanged(Platform::Object^ sender, Windows::UI::Xaml::Controls::SelectionChangedEventArgs^ e)
|
||||
{
|
||||
if ( m_bPreviewing )
|
||||
@ -523,15 +232,9 @@ void AdvancedCapture::lstEnumedDevices_SelectionChanged(Platform::Object^ sender
|
||||
|
||||
btnStartDevice2->IsEnabled = true;
|
||||
btnStartPreview2->IsEnabled = false;
|
||||
btnStartStopRecord2->IsEnabled = false;
|
||||
m_bRecording = false;
|
||||
btnStartStopRecord2->Content = "StartRecord";
|
||||
btnTakePhoto2->IsEnabled = false;
|
||||
previewElement2->Source = nullptr;
|
||||
playbackElement2->Source = nullptr;
|
||||
imageElement2->Source= nullptr;
|
||||
chkAddRemoveEffect->IsEnabled = false;
|
||||
chkAddRemoveEffect->IsChecked = false;
|
||||
EffectTypeCombo->IsEnabled = false;
|
||||
m_bEffectAdded = false;
|
||||
m_bEffectAddedToRecord = false;
|
||||
m_bEffectAddedToPhoto = false;
|
||||
@ -617,14 +320,13 @@ void AdvancedCapture::AddEffectToImageStream()
|
||||
effectTask3.get();
|
||||
m_bEffectAddedToPhoto = true;
|
||||
ShowStatusMessage("Adding effect to photo stream successful");
|
||||
chkAddRemoveEffect->IsEnabled = true;
|
||||
EffectTypeCombo->IsEnabled = true;
|
||||
|
||||
}
|
||||
catch(Exception ^e)
|
||||
{
|
||||
ShowExceptionMessage(e);
|
||||
chkAddRemoveEffect->IsEnabled = true;
|
||||
chkAddRemoveEffect->IsChecked = false;
|
||||
EffectTypeCombo->IsEnabled = true;
|
||||
}
|
||||
});
|
||||
|
||||
@ -632,8 +334,7 @@ void AdvancedCapture::AddEffectToImageStream()
|
||||
catch(Exception ^e)
|
||||
{
|
||||
ShowExceptionMessage(e);
|
||||
chkAddRemoveEffect->IsEnabled = true;
|
||||
chkAddRemoveEffect->IsChecked = false;
|
||||
EffectTypeCombo->IsEnabled = true;
|
||||
}
|
||||
|
||||
});
|
||||
@ -654,14 +355,13 @@ void AdvancedCapture::AddEffectToImageStream()
|
||||
effectTask3.get();
|
||||
m_bEffectAddedToPhoto = true;
|
||||
ShowStatusMessage("Adding effect to photo stream successful");
|
||||
chkAddRemoveEffect->IsEnabled = true;
|
||||
EffectTypeCombo->IsEnabled = true;
|
||||
|
||||
}
|
||||
catch(Exception ^e)
|
||||
{
|
||||
ShowExceptionMessage(e);
|
||||
chkAddRemoveEffect->IsEnabled = true;
|
||||
chkAddRemoveEffect->IsChecked = false;
|
||||
EffectTypeCombo->IsEnabled = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -669,82 +369,15 @@ void AdvancedCapture::AddEffectToImageStream()
|
||||
}
|
||||
|
||||
|
||||
|
||||
void AdvancedCapture::chkAddRemoveEffect_Checked(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
|
||||
{
|
||||
try
|
||||
{
|
||||
chkAddRemoveEffect->IsEnabled = false;
|
||||
m_bEffectAdded = true;
|
||||
create_task(m_mediaCaptureMgr->AddEffectAsync(Windows::Media::Capture::MediaStreamType::VideoPreview,"GrayscaleTransform.GrayscaleEffect", nullptr)).then([this](task<void> effectTask)
|
||||
{
|
||||
try
|
||||
{
|
||||
effectTask.get();
|
||||
|
||||
auto mediaCapture = m_mediaCaptureMgr.Get();
|
||||
Windows::Media::Capture::VideoDeviceCharacteristic charecteristic = mediaCapture->MediaCaptureSettings->VideoDeviceCharacteristic;
|
||||
|
||||
ShowStatusMessage("Add effect successful to preview stream successful");
|
||||
if((charecteristic != Windows::Media::Capture::VideoDeviceCharacteristic::AllStreamsIdentical) &&
|
||||
(charecteristic != Windows::Media::Capture::VideoDeviceCharacteristic::PreviewRecordStreamsIdentical))
|
||||
{
|
||||
Windows::Media::MediaProperties::IMediaEncodingProperties ^props = mediaCapture->VideoDeviceController->GetMediaStreamProperties(Windows::Media::Capture::MediaStreamType::VideoRecord);
|
||||
Windows::Media::MediaProperties::VideoEncodingProperties ^videoEncodingProperties = static_cast<Windows::Media::MediaProperties::VideoEncodingProperties ^>(props);
|
||||
if(!videoEncodingProperties->Subtype->Equals("H264")) //Cant add an effect to an H264 stream
|
||||
{
|
||||
task<void>(mediaCapture->AddEffectAsync(Windows::Media::Capture::MediaStreamType::VideoRecord,"GrayscaleTransform.GrayscaleEffect", nullptr)).then([this](task<void> effectTask2)
|
||||
{
|
||||
try
|
||||
{
|
||||
effectTask2.get();
|
||||
ShowStatusMessage("Add effect successful to record stream successful");
|
||||
m_bEffectAddedToRecord = true;
|
||||
AddEffectToImageStream();
|
||||
chkAddRemoveEffect->IsEnabled = true;
|
||||
}
|
||||
catch(Exception ^e)
|
||||
{
|
||||
ShowExceptionMessage(e);
|
||||
chkAddRemoveEffect->IsEnabled = true;
|
||||
chkAddRemoveEffect->IsChecked = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
AddEffectToImageStream();
|
||||
chkAddRemoveEffect->IsEnabled = true;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
AddEffectToImageStream();
|
||||
chkAddRemoveEffect->IsEnabled = true;
|
||||
}
|
||||
}
|
||||
catch (Exception ^e)
|
||||
{
|
||||
ShowExceptionMessage(e);
|
||||
chkAddRemoveEffect->IsEnabled = true;
|
||||
chkAddRemoveEffect->IsChecked = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (Platform::Exception ^e)
|
||||
{
|
||||
ShowExceptionMessage(e);
|
||||
chkAddRemoveEffect->IsEnabled = true;
|
||||
chkAddRemoveEffect->IsChecked = false;
|
||||
}
|
||||
}
|
||||
|
||||
void AdvancedCapture::chkAddRemoveEffect_Unchecked(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
|
||||
{
|
||||
try
|
||||
{
|
||||
chkAddRemoveEffect->IsEnabled = false;
|
||||
EffectTypeCombo->IsEnabled = false;
|
||||
m_bEffectAdded = false;
|
||||
create_task(m_mediaCaptureMgr->ClearEffectsAsync(Windows::Media::Capture::MediaStreamType::VideoPreview)).then([this](task<void> effectTask)
|
||||
{
|
||||
@ -775,8 +408,7 @@ void AdvancedCapture::chkAddRemoveEffect_Unchecked(Platform::Object^ sender, Win
|
||||
catch(Exception ^e)
|
||||
{
|
||||
ShowExceptionMessage(e);
|
||||
chkAddRemoveEffect->IsEnabled = true;
|
||||
chkAddRemoveEffect->IsChecked = true;
|
||||
EffectTypeCombo->IsEnabled = true;
|
||||
}
|
||||
|
||||
});
|
||||
@ -784,14 +416,12 @@ void AdvancedCapture::chkAddRemoveEffect_Unchecked(Platform::Object^ sender, Win
|
||||
else
|
||||
{
|
||||
}
|
||||
chkAddRemoveEffect->IsEnabled = true;
|
||||
EffectTypeCombo->IsEnabled = true;
|
||||
}
|
||||
catch(Exception ^e)
|
||||
{
|
||||
ShowExceptionMessage(e);
|
||||
chkAddRemoveEffect->IsEnabled = true;
|
||||
chkAddRemoveEffect->IsChecked = true;
|
||||
|
||||
EffectTypeCombo->IsEnabled = true;
|
||||
}
|
||||
|
||||
});
|
||||
@ -811,31 +441,27 @@ void AdvancedCapture::chkAddRemoveEffect_Unchecked(Platform::Object^ sender, Win
|
||||
catch(Exception ^e)
|
||||
{
|
||||
ShowExceptionMessage(e);
|
||||
chkAddRemoveEffect->IsEnabled = true;
|
||||
chkAddRemoveEffect->IsChecked = true;
|
||||
EffectTypeCombo->IsEnabled = true;
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
chkAddRemoveEffect->IsEnabled = true;
|
||||
chkAddRemoveEffect->IsChecked = true;
|
||||
EffectTypeCombo->IsEnabled = true;
|
||||
}
|
||||
}
|
||||
catch (Exception ^e)
|
||||
{
|
||||
ShowExceptionMessage(e);
|
||||
chkAddRemoveEffect->IsEnabled = true;
|
||||
chkAddRemoveEffect->IsChecked = true;
|
||||
EffectTypeCombo->IsEnabled = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (Platform::Exception ^e)
|
||||
{
|
||||
ShowExceptionMessage(e);
|
||||
chkAddRemoveEffect->IsEnabled = true;
|
||||
chkAddRemoveEffect->IsChecked = true;
|
||||
EffectTypeCombo->IsEnabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -849,18 +475,6 @@ void AdvancedCapture::ShowExceptionMessage(Platform::Exception^ ex)
|
||||
rootPage->NotifyUser(ex->Message, NotifyType::ErrorMessage);
|
||||
}
|
||||
|
||||
void AdvancedCapture::SwitchRecordButtonContent()
|
||||
{
|
||||
if (m_bRecording)
|
||||
{
|
||||
btnStartStopRecord2->Content="StopRecord";
|
||||
}
|
||||
else
|
||||
{
|
||||
btnStartStopRecord2->Content="StartRecord";
|
||||
}
|
||||
}
|
||||
|
||||
void AdvancedCapture::EnableButton(bool enabled, String^ name)
|
||||
{
|
||||
if (name->Equals("StartDevice"))
|
||||
@ -871,14 +485,6 @@ void AdvancedCapture::EnableButton(bool enabled, String^ name)
|
||||
{
|
||||
btnStartPreview2->IsEnabled = enabled;
|
||||
}
|
||||
else if (name->Equals("StartStopRecord"))
|
||||
{
|
||||
btnStartStopRecord2->IsEnabled = enabled;
|
||||
}
|
||||
else if (name->Equals("TakePhoto"))
|
||||
{
|
||||
btnTakePhoto2->IsEnabled = enabled;
|
||||
}
|
||||
}
|
||||
|
||||
task<Windows::Storage::StorageFile^> AdvancedCapture::ReencodePhotoAsync(
|
||||
@ -1032,8 +638,79 @@ Windows::Media::Capture::VideoRotation AdvancedCapture::VideoRotationLookup(
|
||||
}
|
||||
|
||||
|
||||
|
||||
void SDKSample::MediaCapture::AdvancedCapture::EffectType_SelectionChanged(Platform::Object^ sender, Windows::UI::Xaml::Controls::SelectionChangedEventArgs^ e)
|
||||
void SDKSample::MediaCapture::AdvancedCapture::EffectTypeCombo_SelectionChanged(Platform::Object^ sender, Windows::UI::Xaml::Controls::SelectionChangedEventArgs^ e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
void SDKSample::MediaCapture::AdvancedCapture::Button_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
|
||||
{
|
||||
try
|
||||
{
|
||||
create_task(m_mediaCaptureMgr->ClearEffectsAsync(Windows::Media::Capture::MediaStreamType::VideoPreview)).then([this](task<void> cleanTask)
|
||||
{
|
||||
m_bEffectAdded = true;
|
||||
int index = EffectTypeCombo->SelectedIndex;
|
||||
PropertySet^ props = ref new PropertySet();
|
||||
props->Insert(L"{698649BE-8EAE-4551-A4CB-3EC98FBD3D86}", index);
|
||||
create_task(m_mediaCaptureMgr->AddEffectAsync(Windows::Media::Capture::MediaStreamType::VideoPreview,"GrayscaleTransform.GrayscaleEffect", props)).then([this](task<void> effectTask)
|
||||
{
|
||||
try
|
||||
{
|
||||
effectTask.get();
|
||||
|
||||
auto mediaCapture = m_mediaCaptureMgr.Get();
|
||||
Windows::Media::Capture::VideoDeviceCharacteristic charecteristic = mediaCapture->MediaCaptureSettings->VideoDeviceCharacteristic;
|
||||
|
||||
ShowStatusMessage("Add effect successful to preview stream successful");
|
||||
if((charecteristic != Windows::Media::Capture::VideoDeviceCharacteristic::AllStreamsIdentical) &&
|
||||
(charecteristic != Windows::Media::Capture::VideoDeviceCharacteristic::PreviewRecordStreamsIdentical))
|
||||
{
|
||||
Windows::Media::MediaProperties::IMediaEncodingProperties ^props = mediaCapture->VideoDeviceController->GetMediaStreamProperties(Windows::Media::Capture::MediaStreamType::VideoRecord);
|
||||
Windows::Media::MediaProperties::VideoEncodingProperties ^videoEncodingProperties = static_cast<Windows::Media::MediaProperties::VideoEncodingProperties ^>(props);
|
||||
if(!videoEncodingProperties->Subtype->Equals("H264")) //Cant add an effect to an H264 stream
|
||||
{
|
||||
task<void>(mediaCapture->AddEffectAsync(Windows::Media::Capture::MediaStreamType::VideoRecord,"GrayscaleTransform.GrayscaleEffect", nullptr)).then([this](task<void> effectTask2)
|
||||
{
|
||||
try
|
||||
{
|
||||
effectTask2.get();
|
||||
ShowStatusMessage("Add effect successful to record stream successful");
|
||||
m_bEffectAddedToRecord = true;
|
||||
AddEffectToImageStream();
|
||||
EffectTypeCombo->IsEnabled = true;
|
||||
}
|
||||
catch(Exception ^e)
|
||||
{
|
||||
ShowExceptionMessage(e);
|
||||
EffectTypeCombo->IsEnabled = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
AddEffectToImageStream();
|
||||
EffectTypeCombo->IsEnabled = true;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
AddEffectToImageStream();
|
||||
EffectTypeCombo->IsEnabled = true;
|
||||
}
|
||||
}
|
||||
catch (Exception ^e)
|
||||
{
|
||||
ShowExceptionMessage(e);
|
||||
EffectTypeCombo->IsEnabled = true;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
catch (Platform::Exception ^e)
|
||||
{
|
||||
ShowExceptionMessage(e);
|
||||
EffectTypeCombo->IsEnabled = true;
|
||||
}
|
||||
}
|
||||
|
@ -49,18 +49,12 @@ namespace SDKSample
|
||||
void ScenarioInit();
|
||||
void ScenarioReset();
|
||||
|
||||
void SoundLevelChanged(Object^ sender, Object^ e);
|
||||
void RecordLimitationExceeded(Windows::Media::Capture::MediaCapture ^ mediaCapture);
|
||||
void Failed(Windows::Media::Capture::MediaCapture ^ mediaCapture, Windows::Media::Capture::MediaCaptureFailedEventArgs ^ args);
|
||||
|
||||
void btnStartDevice_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
|
||||
|
||||
void btnStartPreview_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
|
||||
|
||||
void btnStartStopRecord_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
|
||||
|
||||
void btnTakePhoto_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
|
||||
|
||||
void lstEnumedDevices_SelectionChanged(Platform::Object^ sender, Windows::UI::Xaml::Controls::SelectionChangedEventArgs^ e);
|
||||
void EnumerateWebcamsAsync();
|
||||
|
||||
@ -72,7 +66,6 @@ namespace SDKSample
|
||||
void ShowExceptionMessage(Platform::Exception^ ex);
|
||||
|
||||
void EnableButton(bool enabled, Platform::String ^name);
|
||||
void SwitchRecordButtonContent();
|
||||
|
||||
task<Windows::Storage::StorageFile^> ReencodePhotoAsync(
|
||||
Windows::Storage::StorageFile ^tempStorageFile,
|
||||
@ -98,7 +91,8 @@ namespace SDKSample
|
||||
bool m_bRotateVideoOnOrientationChange;
|
||||
bool m_bReversePreviewRotation;
|
||||
Windows::Foundation::EventRegistrationToken m_orientationChangedEventToken;
|
||||
void EffectType_SelectionChanged(Platform::Object^ sender, Windows::UI::Xaml::Controls::SelectionChangedEventArgs^ e);
|
||||
void EffectTypeCombo_SelectionChanged(Platform::Object^ sender, Windows::UI::Xaml::Controls::SelectionChangedEventArgs^ e);
|
||||
void Button_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -15,10 +15,12 @@
|
||||
|
||||
#include "pch.h"
|
||||
#include "MainPage.xaml.h"
|
||||
#include "AdvancedCapture.xaml.h"
|
||||
#include "Common\SuspensionManager.h"
|
||||
|
||||
using namespace SDKSample;
|
||||
using namespace SDKSample::Common;
|
||||
using namespace SDKSample::MediaCapture;
|
||||
|
||||
using namespace Concurrency;
|
||||
using namespace Platform;
|
||||
|
@ -93,7 +93,7 @@ void MainPage::InvalidateSize()
|
||||
{
|
||||
// Make us as big as the the left over space, factoring in the ListBox width, the ListBox margins.
|
||||
// and the LayoutRoot's margins
|
||||
InputSection->Width = ((availableWidth) -
|
||||
InputSection->Width = ((availableWidth) -
|
||||
(layoutRootMarginLeft + layoutRootMarginRight + listBoxMarginLeft + listBoxMarginRight));
|
||||
}
|
||||
else
|
||||
@ -161,7 +161,7 @@ void MainPage::PopulateScenarios()
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method is responsible for loading the individual input and output sections for each scenario. This
|
||||
/// This method is responsible for loading the individual input and output sections for each scenario. This
|
||||
/// is based on navigating a hidden Frame to the ScenarioX.xaml page and then extracting out the input
|
||||
/// and output sections into the respective UserControl on the main page.
|
||||
/// </summary>
|
||||
@ -185,7 +185,7 @@ void MainPage::LoadScenario(String^ scenarioName)
|
||||
if (input == nullptr)
|
||||
{
|
||||
// Malformed input section.
|
||||
NotifyUser("Cannot load scenario input section for " + scenarioName +
|
||||
NotifyUser("Cannot load scenario input section for " + scenarioName +
|
||||
" Make sure root of input section markup has x:Name of 'Input'", NotifyType::ErrorMessage);
|
||||
return;
|
||||
}
|
||||
@ -193,7 +193,7 @@ void MainPage::LoadScenario(String^ scenarioName)
|
||||
if (output == nullptr)
|
||||
{
|
||||
// Malformed output section.
|
||||
NotifyUser("Cannot load scenario output section for " + scenarioName +
|
||||
NotifyUser("Cannot load scenario output section for " + scenarioName +
|
||||
" Make sure root of output section markup has x:Name of 'Output'", NotifyType::ErrorMessage);
|
||||
return;
|
||||
}
|
||||
@ -222,7 +222,7 @@ void MainPage::LoadScenario(String^ scenarioName)
|
||||
else
|
||||
{
|
||||
// Malformed Scenario file.
|
||||
NotifyUser("Cannot load scenario: " + scenarioName + ". Make sure root tag in the '" +
|
||||
NotifyUser("Cannot load scenario: " + scenarioName + ". Make sure root tag in the '" +
|
||||
scenarioName + "' file has an x:Name of 'LayoutRoot'", NotifyType::ErrorMessage);
|
||||
}
|
||||
}
|
||||
@ -284,7 +284,7 @@ void MainPage::Footer_Click(Object^ sender, RoutedEventArgs^ e)
|
||||
/// session. This will be null the first time a page is visited.</param>
|
||||
void MainPage::LoadState(Object^ navigationParameter, IMap<String^, Object^>^ pageState)
|
||||
{
|
||||
(void) navigationParameter; // Unused parameter
|
||||
(void) navigationParameter; // Unused parameter
|
||||
|
||||
PopulateScenarios();
|
||||
|
||||
|
@ -122,9 +122,7 @@
|
||||
<Page Include="Common\StandardStyles.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Include="MainPage.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Include="MainPage.xaml" />
|
||||
<Page Include="Sample-Utils\SampleTemplateStyles.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
|
@ -189,7 +189,7 @@ void TransformImage_NV12(
|
||||
CGrayscale::CGrayscale() :
|
||||
m_pSample(NULL), m_pInputType(NULL), m_pOutputType(NULL),
|
||||
m_imageWidthInPixels(0), m_imageHeightInPixels(0), m_cbImageSize(0),
|
||||
m_TransformType(Preview), m_rcDest(D2D1::RectU()), m_bStreamingInitialized(false),
|
||||
m_TransformType(Preview), m_bStreamingInitialized(false),
|
||||
m_pAttributes(NULL)
|
||||
{
|
||||
InitializeCriticalSectionEx(&m_critSec, 3000, 0);
|
||||
@ -219,7 +219,32 @@ STDMETHODIMP CGrayscale::RuntimeClassInitialize()
|
||||
//-------------------------------------------------------------------
|
||||
HRESULT CGrayscale::SetProperties(ABI::Windows::Foundation::Collections::IPropertySet *pConfiguration)
|
||||
{
|
||||
return S_OK;
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
if (!pConfiguration)
|
||||
return hr;
|
||||
|
||||
HSTRING key;
|
||||
WindowsCreateString(L"{698649BE-8EAE-4551-A4CB-3EC98FBD3D86}", 38, &key);
|
||||
Microsoft::WRL::ComPtr<ABI::Windows::Foundation::Collections::IMap<HSTRING, IInspectable *>> spSetting;
|
||||
pConfiguration->QueryInterface(IID_PPV_ARGS(&spSetting));
|
||||
boolean found;
|
||||
spSetting->HasKey(key, &found);
|
||||
|
||||
if (found)
|
||||
{
|
||||
IInspectable* value;
|
||||
spSetting->Lookup(key, &value);
|
||||
|
||||
Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IReference<int>> ref;
|
||||
value->QueryInterface(IID_PPV_ARGS(&ref));
|
||||
int effect = InvalidEffect;
|
||||
ref->get_Value(&effect);
|
||||
if ((effect >= 0) && (effect < InvalidEffect))
|
||||
{
|
||||
m_TransformType = (ProcessingType)effect;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// IMFTransform methods. Refer to the Media Foundation SDK documentation for details.
|
||||
@ -1327,41 +1352,10 @@ HRESULT CGrayscale::BeginStreaming()
|
||||
|
||||
if (!m_bStreamingInitialized)
|
||||
{
|
||||
// Get the configuration attributes.
|
||||
|
||||
// Get the destination rectangle.
|
||||
|
||||
RECT rcDest;
|
||||
hr = m_pAttributes->GetBlob(MFT_GRAYSCALE_DESTINATION_RECT, (UINT8*)&rcDest, sizeof(rcDest), NULL);
|
||||
if (hr == MF_E_ATTRIBUTENOTFOUND || !ValidateRect(rcDest))
|
||||
{
|
||||
// The client did not set this attribute, or the client provided an invalid rectangle.
|
||||
// Default to the entire image.
|
||||
|
||||
m_rcDest = D2D1::RectU(0, 0, m_imageWidthInPixels, m_imageHeightInPixels);
|
||||
hr = S_OK;
|
||||
}
|
||||
else if (SUCCEEDED(hr))
|
||||
{
|
||||
m_rcDest = D2D1::RectU(rcDest.left, rcDest.top, rcDest.right, rcDest.bottom);
|
||||
}
|
||||
else
|
||||
{
|
||||
goto done;
|
||||
}
|
||||
|
||||
// Get the effect type
|
||||
UINT32 effect = MFGetAttributeUINT32(m_pAttributes, MFT_IMAGE_EFFECT, 1);
|
||||
|
||||
if ((effect >= 0) && (effect < InvalidEffect))
|
||||
{
|
||||
m_TransformType = (ProcessingType)effect;
|
||||
}
|
||||
|
||||
m_bStreamingInitialized = true;
|
||||
hr = S_OK;
|
||||
}
|
||||
|
||||
done:
|
||||
return hr;
|
||||
}
|
||||
|
||||
@ -1465,14 +1459,14 @@ HRESULT CGrayscale::OnProcessOutput(IMFMediaBuffer *pIn, IMFMediaBuffer *pOut)
|
||||
// RGB
|
||||
for (int c=0; c<3; c++)
|
||||
{
|
||||
std::vector<int> hist;
|
||||
cv::Mat hist;
|
||||
cv::calcHist(&BgrFrame, 1, channels[c], cv::Mat(), hist, 1, mHistSize, ranges);
|
||||
cv::normalize(hist, hist, BgrFrame.rows/2, 0, cv::NORM_INF);
|
||||
for(int h=0; h<mHistSizeNum; h++) {
|
||||
cv::Point mP1, mP2;
|
||||
mP1.x = mP2.x = offset + (c * (mHistSizeNum + 10) + h) * thikness;
|
||||
mP1.y = BgrFrame.rows-1;
|
||||
mP2.y = mP1.y - 2 - (int)hist[h];
|
||||
mP2.y = mP1.y - 2 - hist.at<float>(h);
|
||||
cv::line(BgrFrame, mP1, mP2, mColorsRGB[c], thikness);
|
||||
}
|
||||
}
|
||||
|
@ -44,6 +44,7 @@ DEFINE_GUID(MFT_IMAGE_EFFECT,
|
||||
|
||||
enum ProcessingType
|
||||
{
|
||||
Preview,
|
||||
GrayScale,
|
||||
Canny,
|
||||
Sobel,
|
||||
@ -232,7 +233,6 @@ private:
|
||||
|
||||
// Transformation parameters
|
||||
ProcessingType m_TransformType;
|
||||
D2D_RECT_U m_rcDest; // Destination rectangle for the effect.
|
||||
|
||||
// Streaming
|
||||
bool m_bStreamingInitialized;
|
||||
|
@ -22,9 +22,6 @@
|
||||
</Application>
|
||||
</Applications>
|
||||
<Capabilities>
|
||||
<Capability Name="picturesLibrary" />
|
||||
<Capability Name="musicLibrary" />
|
||||
<Capability Name="videosLibrary" />
|
||||
<DeviceCapability Name="webcam" />
|
||||
<DeviceCapability Name="microphone" />
|
||||
</Capabilities>
|
||||
|
Loading…
x
Reference in New Issue
Block a user