WPF XAML serialize/deserialize - c#

my application is basically taking one WPF Canvas containing other controls and serialize it to an XML file and then deserialize it to display the serialized data or a previously saved one. The serialization/deserialization is working fine everything is saved and restored back. The issue is that after deserialization if I try to change an image source with the bellow code it doesn't work:
testLogo.Source = new BitmapImage(new Uri(file.FileName));
The Image is referrenced in the XAML as bellow:
<Canvas Name="mainCanva" Margin="0,0,12,0" Width="1729" Height="150" VerticalAlignment="Top">
<Border BorderThickness="3" BorderBrush="#FF009B80" FlowDirection="LeftToRight" VerticalAlignment="Top" HorizontalAlignment="Left" Width="1729" Height="150">
<Grid Margin="0" Background="White" Height="Auto" Width="Auto" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Uid="">
<Grid HorizontalAlignment="Left" Margin="3,28,0,57">
<Image HorizontalAlignment="Left" Margin="0,0,0,0" x:Name="testLogo" Stretch="UniformToFill" Width="317" Source="file:///C:/Users/logo.jpg" />
</Grid>
</Grid>
</Border>
</Canvas>
The Deserialization code is as bellow:
Canvas canvas = DeSerializeXAML(appPath + "\\tmp\\mainCanva.xml") as Canvas;
mainCanva.Children.Clear();
while (canvas.Children.Count > 0)
{
UIElement obj = canvas.Children[0];
canvas.Children.Remove(obj);
mainCanva.Children.Add(obj); // Add to canvas
}
Another point to note is that I tried to find out what was happening using Snoop, after Deserialization Snoop is also unable to change the image source although if I reconnect Snoop to the app by drag and dropping the crosshair Snoop is now able to change the Image source. The 'old' Snoop window can see the image source being updated from the testLogo.Source = command. WPF inspector doesn't have this issue it is immediately updating itself when the deserialization is happening. My guess is that there is something wrong with the visual tree ... and as WPF can do it I think it can be sorted.
Thanks for the help guys.
As requested the Serialize/Deserialize functions:
public static void SerializeToXAML(UIElement element, string filename)
{
string strXAML = System.Windows.Markup.XamlWriter.Save(element);
using (System.IO.FileStream fs = System.IO.File.Create(filename))
{
using (System.IO.StreamWriter streamwriter = new System.IO.StreamWriter(fs))
{
streamwriter.Write(strXAML);
}
}
}
public static UIElement DeSerializeXAML(string filename)
{
using (System.IO.FileStream fs = System.IO.File.Open(filename, System.IO.FileMode.Open, System.IO.FileAccess.Read))
{
return System.Windows.Markup.XamlReader.Load(fs) as UIElement;
}
}

You need to update your variable reference.
When you call mainCanva.Children.Clear(), it removes all the children including testLogo. Your variable testLogo will still be pointing at the original testLogo object even though it's not part of the UI anymore.
Try this:
Canvas canvas = DeSerializeXAML(appPath + "\\tmp\\mainCanva.xml") as Canvas;
mainCanva.Children.Clear();
while (canvas.Children.Count > 0)
{
UIElement obj = canvas.Children[0];
canvas.Children.Remove(obj);
mainCanva.Children.Add(obj); // Add to canvas
}
testLogo = mainCanva.FindName("testLogo") as Image;

I ended up using Application resources:
<Application.Resources>
<BitmapImage x:Key="testLogo" >file:///C:/Users/test_B&W.png</BitmapImage>
</Application.Resources>
then in the code:
Resources["AVItestLogoic"] = ...
This way no matter what happens to the Visual Tree, the application resource always point to the right item

Related

Reordering ListView items in UWP messes up the content

I'm using ListViews to make a kanban list in UWP. As the picture below shows, re-ordering items a few times results in the content of one or some of them being wrong.
Further re-ordering will have the content going back and forth being correct and wrong and everything is back to normal when re-loading the page which means there's not data change but just the image control displaying the wrong image. ( It can happen with any other control too )
For reference, The images are local files which I'm loading in the Image control's Loaded event, and the ListView simply has CanReorderItems and AllowDrop set to true.
Here's how the XAML looks
<ListView x:Name="LView" MinWidth="240" Grid.Row="1" ItemsSource="{x:Bind List.Tasks}" ReorderMode="Enabled" CanReorderItems="True" AllowDrop="True" CanDragItems="True" SelectionMode="None" IsItemClickEnabled="True" ScrollViewer.VerticalScrollBarVisibility="Hidden" ScrollViewer.VerticalScrollMode="Enabled" ScrollViewer.IsVerticalRailEnabled="True" ItemClick="LView_ItemClick">
<ListView.ItemContainerStyle>
...
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate x:DataType="mongo:Task">
<Grid Padding="12 0" >
<Grid.RowDefinitions>
...
</Grid.RowDefinitions>
<Border CornerRadius="4 4 0 0" Margin="-12 0" >
<Image x:Name="Cover" MaxHeight="160" Stretch="UniformToFill" Tag="{x:Bind Attachments}" Loaded="Image_Loaded" HorizontalAlignment="Center" VerticalAlignment="Bottom"/>
</Border>
...
And here's the Loaded event
private async void Image_Loaded(object sender, RoutedEventArgs e)
{
var img = sender as Image;
if (img.Source is object) return;
var attachments = img.Tag as ObservableCollection<TaskAttachment>;
if (attachments is null) return;
var cover = attachments.Where(_a => _a.is_cover).FirstOrDefault();
if (cover is object && cover.type == "image")
{
var path = BrandboxSettings.Instance.server_path + "projects\\" + cover.path;
Output.WriteLine(path);
var file = await StorageFile.GetFileFromPathAsync(path);
using (IRandomAccessStream fileStream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read))
{
// Set the image source to the selected bitmap
BitmapImage bitmapImage = new BitmapImage();
await bitmapImage.SetSourceAsync(fileStream);
img.Source = bitmapImage;
}
}
}
Edit: It's worth noting that even if one of the cards does not initially have an image, reordering will cause it to have one.
Any help would be appreciated
Okay so I tried changing the ItemsPanel to a StackPanel and it seems to be working now.
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizationStackPanel/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
Edit:
It also seems to work by setting the Panel to VirtualizationStackPanel

UWP App: Load images from folder to gallery without locking the files in .Net Core

Currently I am working on a project to create a UWP app based on .Net Core.
To describe my problem:
I am trying to display some images from a local folder in a gallery of the app. After selecting an image I draw something on it and i want to save the image to the folder. Currently I am creating a whole new image because I can't edit the original one since it is still opened and locked.
So after a lot of research I know, that the image will be open till I exit my app since I bind it as a BitmapImage with a URI.
So I tried some code from the net but the Problem is, the most of the code is not for .Net Core. I tried it with System.Drawing.Common and a Converter to load the image using BitmapImage because this solution is widely spread but I only got the Library Windows.UI.Xaml.Media.Imaging and that's not what is needed.
From the underlying code I only have the URI. So that's my xaml
<Image MaxWidth="270" MaxHeight="180" Stretch="Uniform" Margin="5,5,5,15"
Tapped="Image_SelectedImage_Tapped">
<Image.Source>
<BitmapImage UriSource="{x:Bind ImageUri,Converter={StaticResource ImageConverter}, Mode=OneWay}"DecodePixelWidth="270" DecodePixelType="Logical"/>
</Image.Source>
</Image>
And the ImageConverter I try to use:
class ImageConverter :IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
//load the image here, close it and return it
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
The ImageConverter is empty now because no found solution works till now.
At the moment I am trying to use the SixLabors ImageSharp library to load the Image but I don't get it to work either.
Did anyone struggle with a similar problem and found a solution especially for .Net Core? Is there a possibility to load the image from a stream and pass it to xaml?
I just want the image to still be editable even if it gets opened by the application.
I really hope someone could help me because I tried a lot of stuff but I can't bring it to work.
(In Continuation from the comment)You can use InkCanvas to Store your strokes on the image and export it as you want. You can also overwrite the existing file.
Sample Image Exported
MainPage.Xaml
<Page
x:Class="App1.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App1"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Name="YourPage"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid HorizontalAlignment="Stretch" Background="Aqua" VerticalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid x:Name="outputGrid">
<Image Source="ms-appx:///Assets/1.jpg"></Image>
<InkCanvas x:Name="inkCanvas" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
</Grid>
<Button Content="Save" Grid.Row="1" Click="Button_Click"></Button>
</Grid>
</Page>
MainPage.xaml.cs
public sealed partial class MainPage : Page
{
public MainPage() { this.InitializeComponent();
inkCanvas.InkPresenter.InputDeviceTypes =
Windows.UI.Core.CoreInputDeviceTypes.Mouse |
Windows.UI.Core.CoreInputDeviceTypes.Touch |
Windows.UI.Core.CoreInputDeviceTypes.Pen;
}
private async void Button_Click(object sender, RoutedEventArgs e)
{
RenderTargetBitmap rtb = new RenderTargetBitmap();
await rtb.RenderAsync(outputGrid);
var pixelBuffer = await rtb.GetPixelsAsync();
var pixels = pixelBuffer.ToArray();
var displayInformation = DisplayInformation.GetForCurrentView();
FileSavePicker savePicker = new FileSavePicker();
savePicker.FileTypeChoices.Add("Jpeg", new List<string>() { ".jpg" });
savePicker.SuggestedFileName = "chart";
StorageFile file = await savePicker.PickSaveFileAsync();
if (file != null)
{
using (var stream = await file.OpenAsync(FileAccessMode.ReadWrite))
{
var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, stream);
encoder.SetPixelData(BitmapPixelFormat.Bgra8,
BitmapAlphaMode.Premultiplied,
(uint)rtb.PixelWidth,
(uint)rtb.PixelHeight,
displayInformation.RawDpiX,
displayInformation.RawDpiY,
pixels);
await encoder.FlushAsync();
}
}
}
}
So finally I solved the problem using the SkiaSharp Library. My Converter returns the image loaded via a Filestream as a WriteableBitmap. With this solution the image is displayed but I am still able to delete or edit the original file in the folder.
Here is the Converter:
public object Convert(object value, Type targetType, object parameter, string language)
{
string imageFolderPath = Path.Combine(ApplicationData.Current.LocalFolder.Path, "Images");
var path = (Uri)value;
SKBitmap map;
using (FileStream stream = new FileStream(imageFolderPath + "\\" + path.Segments[3],
System.IO.FileMode.Open, FileAccess.Read))
{
map = SKBitmap.Decode(stream);
}
return map.ToWriteableBitmap();
}
And here is the xaml Binding:
<Image Source="{x:Bind ImageUri,Converter={StaticResource ImageConverter}}" MaxWidth="270" MaxHeight="180" Stretch="Uniform" Margin="5,5,5,15"
Tapped="Image_SelectedImage_Tapped">
</Image>
I don't know wether it is correct or even good practice but it works.
Anyway, thanks for your answers and your spent time :)

Call GIF image source from the code behind in WPF c# for the tabcontrol's setter

i am using wpf tab control and setting the Icon and text in the tab header through style, i am able to set the text dynamically through getter and setter but can not able to set the image source. I tried to bind the image source through getter and setter but failed. Following is the style code in which i want to set the image source dynamically from the code behind.
-->
<Setter Property="HeaderTemplate" >
<Setter.Value>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<!--<Image gif:ImageBehavior.AnimatedSource="{DynamicResource MyFillBrush}" Width="20" />-->
<Image gif:ImageBehavior.AnimatedSource="25.gif" Width="20" />
<Label Content="{Binding }"/>
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
I know this is a bit old thread, but this is how you update the AnimatedSource from code:
var image = new BitmapImage();
image.BeginInit();
image.UriSource = new Uri(value);
image.EndInit();
ImageBehavior.SetAnimatedSource(Imagereference, image);
The 'value' is the location of your gif file such as "25.gif".
The Imagereference is the Image control you want to update. Also ensure you have the namespace referenced: using WpfAnimatedGif;
Maybe you can use Binding, something like
private string _dynamicGif = "test.gif";
public string DynamicGif
{
get { return _dynamicGif; }
private set
{
_dynamicGif = value;
RaisePropertyChanged("DynamicGif");
}
}
and
<Image gif:ImageBehavior.AnimatedSource="{Binding DynamicGif, UpdateSourceTrigger=PropertyChanged}" Width="20" />
Or, if it doesn't work, you can use MediaElement instead of Image, it won't require WPF Animated GIF. It's also pretty simple to use:
private Uri _imgSource = new Uri("test.gif");
public Uri ImgSource
{
get { return _imgSource; }
private set
{
_imgSource = value;
RaisePropertyChanged("ImgSource");
}
}
and
<MediaElement x:Name="gifImg" LoadedBehavior="Play" Width="20" Source="{Binding ImgSource}"/>
Hope this helps.

Performance issues while recalculating ´WriteableBitmap´

Since my issue is rather uncommon and I have not a single clue what could be causing it, I will try to include every code that might have anything to do with it, stripped down to the very essentials to avoid unnecessary clutter.
Basically, I have a TabControl that includes TabItems whoes Contents are custom UserControls.
Those controls are of the following form:
<UserControl>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinition>
<ScrollViewer Height="Auto" HorizontalAlignment="Stretch" Margin="0" Name="scrollViewer11" VerticalAlignment="Stretch" Width="Auto" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"></ScrollViewer>
<ScrollViewer Grid.Column="1" Height="Auto" Name="scrollViewer12" Width="Auto" Margin="0" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto"></ScrollViewer>
<ScrollViewer Grid.Row="1" Height="Auto" Name="scrollViewer21" Width="Auto" Margin="0" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"></ScrollViewer>
<ScrollViewer Grid.Row="1" Grid.Column="1" Height="Auto" Name="scrollViewer22" Width="Auto" Margin="0" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"></ScrollViewer>
</Grid>
</UserControl>
The amount of rows and columns depends on the control used and ranges from a single cell in a 1x1 grid to 6 cells in a 3x2 grid (each contraining the ScrollViewer).
Now to my actual C# code. To each cell the user may add a WriteableBitmap where the code is organized as such:
public partial class MainWindow : Window
{
List<WorkSpace> WorkSpaceList = new List<WorkSpace>();
private WorkSpace currentSpace = null;
//one of the methods that adds to the TabControl, here a 2x2 grid:
private void NewWorkspaceFour(WorkSpace ws)
{
WorkSpaceFour workSpaceFour = new WorkSpaceFour();
for (int i = 0; i < 4; i++)
{
WorkPlace wp = new WorkPlace();
ws.workPlaceList.Add(wp);
switch (i)
{
case 0:
workSpaceFour.scrollViewer11.Content = wp.grid;
break;
case 1:
workSpaceFour.scrollViewer12.Content = wp.grid;
break;
case 2:
workSpaceFour.scrollViewer21.Content = wp.grid;
break;
case 3:
workSpaceFour.scrollViewer22.Content = wp.grid;
break;
}
}
ws.tabItem.Content = workSpace;
tabControlImages.Items.Add(ws.tabItem);
}
//triggered in UI e.g. by moving a Slider
private void NewSettings(object sender, RoutedPropertyChangedEventArgs<double> e)
{
currentSpace.NewSettings((float)(e.NewValue));
}
}
internal class WorkSpace
{
internal delegate void NewSettingHandler(float e);
internal List<WorkPlace> workPlaceList = new List<WorkPlace>();
internal TabItem tabItem = new TabItem();
internal WorkPlace currentPlace = null;
internal NewSettingsHandler NewSettings;
internal WorkSpace()
{
NewSettings += ChangeSettings;
}
internal void ChangeSettings(float newValue)
{
//do something small with newValue
currentPlace.RecalculateImage();
}
//...more methods that would use "newValue" in a different way, thus the delegate
}
internal class WorkPlace
{
internal WriteableBitmap bitmap;
internal Image image = new Image {//settings};
internal Grid grid = new Grid {//settings};
internal Grid gridImage = new Grid {//settings};
internal WorkPlace()
{
grid.Children.Add(gridImage);
gridImage.Children.Add(image);
}
internal void RecalculateImage()
{
//some rather long calculations...
bitmap.WritePixels(...,...,...,...);
image.Source = bitmap;
}
}
Through the program the user can change the tabs to change currentSpace and click on the cells to change the respective currentPlace both simply by change the reference i.e. currentSpace = space, where space refers to the WorkSpace that contains the new selected TabItem.
Now the issue is as follows. When a tab contains a simple 1x1 grid with an image in it and I move the slider, it runs very smoothly. When a tab contains a 3x2 grid and only a single cell of this grid contains a WorkPlace with a bitmap that is not null it works the same. However, when the 3x2 grid is completely filled with "painted" bitmaps and the slider is moved a noticable lag appears, even though only a single of the 6 images is recalculated redrawn. I don't see why this should be the case. It might have something to do with rendering or the object references but I don't know C# well enough to see and issues here.
Hopefully, the code is not too long (I have stripped it down as much as I could) and clear enough. If anything is not, please say so and I will update/add it. In a previous version of this program the UI was basically the same but the recalculation of the images was fairly different but I could never observe this problem.

Capturing Photo from PhotocaptureDevice

i my creating an image editing application. i want to give the option to user that he can also capture the image at run time and apply editing effects on that captured. at the moment i am following the instructions from Advanced Photo Capture for windows Phone 8.
there are 2 problems
First that i am facing is that when i hit the capture button the image captured will be an inverted image. if i put the phone in Landscape mode then it take the right picture.
When the app starts there is nothing on the screen in other words its totally black. I want the screen to show the camera view so that user knows that what he is going to capture.
Below is my code for Mainpage.xaml.cs file and MainPage.xaml file.
namespace CapturingPhoto {
public partial class MainPage : PhoneApplicationPage {
private MemoryStream imageStream;
private PhotoCaptureDevice captureDevice;
private CameraCaptureSequence seq;
// Constructor
public MainPage() {
InitializeComponent();
imageStream = new MemoryStream();
// Sample code to localize the ApplicationBar
//BuildLocalizedApplicationBar();
prepareResouceToCapture();
}
private async void prepareResouceToCapture() {
if((!PhotoCaptureDevice.AvailableSensorLocations.Contains(CameraSensorLocation.Back)) &&
(!PhotoCaptureDevice.AvailableSensorLocations.Contains(CameraSensorLocation.Front))){
return;
}
Windows.Foundation.Size size;
if(PhotoCaptureDevice.AvailableSensorLocations.Contains(CameraSensorLocation.Back)){
IReadOnlyList <Windows.Foundation.Size> avalaibleSizeList =
PhotoCaptureDevice.GetAvailableCaptureResolutions(CameraSensorLocation.Back);
size = avalaibleSizeList[0];
this.captureDevice = await PhotoCaptureDevice.OpenAsync(CameraSensorLocation.Back, size);
}
else{
IReadOnlyList<Windows.Foundation.Size> avalaibleSizeList =
PhotoCaptureDevice.GetAvailableCaptureResolutions(CameraSensorLocation.Front);
size = avalaibleSizeList[0];
this.captureDevice = await PhotoCaptureDevice.OpenAsync(CameraSensorLocation.Front, size);
}
// await this.captureDevice.SetCaptureResolutionAsync(size);
// await this.captureDevice.SetPreviewResolutionAsync(size);
// BackgroundVideoBrush.SetSource(this.captureDevice);
}
private async void onCaptureImage(object sender, RoutedEventArgs e) {
seq = captureDevice.CreateCaptureSequence(1);
captureDevice.SetProperty(KnownCameraPhotoProperties.FlashMode, FlashState.On);
captureDevice.SetProperty(KnownCameraGeneralProperties.PlayShutterSoundOnCapture, false);
captureDevice.SetProperty(KnownCameraGeneralProperties.AutoFocusRange, AutoFocusRange.Normal);
seq.Frames[0].CaptureStream = imageStream.AsOutputStream();
await captureDevice.PrepareCaptureSequenceAsync(seq);
CaptureImage();
}
public async void CaptureImage() {
await seq.StartCaptureAsync();
// Set the stream position to the beginning.
imageStream.Seek(0, SeekOrigin.Begin);
MediaLibrary library = new MediaLibrary();
Picture picture1 = library.SavePictureToCameraRoll("image1", imageStream);
}
}
}
Code for Xaml file
<phone:PhoneApplicationPage
x:Class="CapturingPhoto.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"
mc:Ignorable="d"
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" Height="768" VerticalAlignment="Bottom">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- LOCALIZATION NOTE:
To localize the displayed strings copy their values to appropriately named
keys in the app's neutral language resource file (AppResources.resx) then
replace the hard-coded text value between the attributes' quotation marks
with the binding clause whose path points to that string name.
For example:
Text="{Binding Path=LocalizedResources.ApplicationTitle, Source={StaticResource LocalizedStrings}}"
This binding points to the template's string resource named "ApplicationTitle".
Adding supported languages in the Project Properties tab will create a
new resx file per language that can carry the translated values of your
UI strings. The binding in these examples will cause the value of the
attributes to be drawn from the .resx file that matches the
CurrentUICulture of the app at run time.
-->
<!--ContentPanel - place additional content here-->
<Canvas x:Name="VideoCanvas" RenderTransformOrigin="0.5,0.5" Canvas.ZIndex="0">
<Canvas.RenderTransform>
<CompositeTransform/>
</Canvas.RenderTransform>
<Canvas.Background>
<!-- The background contains the camera view finder
encapsulated in VideoBrush. -->
<VideoBrush x:Name="BackgroundVideoBrush" >
<VideoBrush.RelativeTransform>
<CompositeTransform x:Name="VideoBrushTransform" CenterY="0.5" CenterX="0.5"/>
</VideoBrush.RelativeTransform>
</VideoBrush>
</Canvas.Background>
</Canvas>
<Button x:Name="btn_Edit" Content="Capture" HorizontalAlignment="Left"
Margin="23,691,0,0" VerticalAlignment="Top"
Width="400" Click="onCaptureImage"/>
<!--Uncomment to see an alignment grid to help ensure your controls are
aligned on common boundaries. The image has a top margin of -32px to
account for the System Tray. Set this to 0 (or remove the margin altogether)
if the System Tray is hidden.
Before shipping remove this XAML and the image itself.-->
<!--<Image Source="/Assets/AlignmentGrid.png" VerticalAlignment="Top" Height="800" Width="480" Margin="0,-32,0,0" Grid.Row="0" Grid.RowSpan="2" IsHitTestVisible="False" />-->
</Grid>
I see that string:
BackgroundVideoBrush.SetSource(this.captureDevice);
is comment.
You can't see camera view, if VideoBrush is empty.
To answer your first question use the "EncodeWithOrientation" property. Put the following switch statement at the top of your onCaptureImage(). This will ensure the saved image is in the correct orientation when taking a photo in portrait mode.
// Initialize variables.
int encodedOrientation = 0;
int sensorOrientation = (Int32)this._camera.SensorRotationInDegrees;
switch (this.Orientation)
{
// Camera hardware shutter button up.
case PageOrientation.LandscapeLeft:
encodedOrientation = -90 + sensorOrientation;
break;
// Camera hardware shutter button down.
case PageOrientation.LandscapeRight:
encodedOrientation = 90 + sensorOrientation;
break;
// Camera hardware shutter button right.
case PageOrientation.PortraitUp:
encodedOrientation = 0 + sensorOrientation;
break;
// Camera hardware shutter button left.
case PageOrientation.PortraitDown:
encodedOrientation = 180 + sensorOrientation;
break;
}
// Apply orientation to image encoding.
this._camera.SetProperty(KnownCameraGeneralProperties.EncodeWithOrientation, encodedOrientation);
Also see the following on MSDN: http://msdn.microsoft.com/EN-US/library/windowsphone/develop/windows.phone.media.capture.knowncamerageneralproperties.encodewithorientation(v=vs.105).aspx

Categories