I have created a flashlight app for Windows Phone. As i already acces the camera to enable the flash, i thought it would be a nice feature to also allow the user to view the previewframes, and be able to zoom in to get a better look at things.
I have a canvas with a composite transform (as i also have to rotate the camera to match potrait mode). I use a slider (started with pinch, but i want one hand control) to increase and decrease the scale of the canvas, effectively zooming in and out. So far so good and on windows Phone 8 (HTC 8x) this works fine, i can go crazy on the slider and nothing bad happens.
On Windows Phone 8.1 (Lumia 930) however, at seemingly randoms moments when moving the slider, the app just closes down and in the debug output the following line is shown:
The program '[3164] TaskHost.exe' has exited with code -1073741819 (0xc0000005) 'Access violation'.
I have no idea how to find the cause of this as the moment of the crash seems to be different, its just Always related to the scaling of the canvas. I am hoping someone can point me in the right direction so i can solve this.
The canvas in XAML:
<Canvas x:Name="viewfinderCanvas">
<Canvas.Background>
<VideoBrush x:Name="viewfinderBrush"/>
</Canvas.Background>
<Canvas.RenderTransform>
<CompositeTransform x:Name="rt" />
</Canvas.RenderTransform>
</Canvas>
And my code for setting the scale:
private void Zoom_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
if (canZoom && !isFocusing)
{
zoomValue = Math.Round(Zoom.Value, 1);
rt.ScaleX = zoomValue * staticValue;
rt.ScaleY = zoomValue * staticValue;
ZoomValue.Text = zoomValue.ToString() + " x";
}
}
Where canzoom is set to true on the loaded event of the mainpage, and isFocusing is set to true upon the autofocus.
Related
a couple days ago I started game developing in MonoGame with Visual Studio 2017 and porting my code which i wrote in WinForms to MonoGame. Now I have a problem with the fullscreen mode. I searched the internet and the only thing I found out is that it depends on the resolution the monitor has.
In the default window mode of the application the screen looks like follows:
Now when I switch to fullscreen mode - this happens:
Now my problems are:
One can not see it on the picture because I used the print button and pasted in to paint but the image is largely strechted.
The right part of the screen is cut off
the sprites are moved to the top.
I'm using
graphics.ToggleFullScreen();
Is there a way to keep the original status like it is in window mode? Maybe to put flexible bars for a 4:3 mode and keep the sprite positions? My positions are fixed. So use something like
spriteBatch.Draw(Params.CUR_SPRITE_P1, new Rectangle(Convert.ToInt32(POSITION_P1.X), Convert.ToInt32(POSITION_P1.Y), 750, 476), Color.White); for the player position and the screen (to implement scrolling).
Or maybe adjust everything in full screen mode bu keep the positions of the sprites on different screen resolutions...
Thank you a lot!
Ok after searching and searching I finally found an answer:
var scaleX = (float)ActualWidth / VirtualWidth;
var scaleY = (float)ActualHeight / VirtualHeight;
var matrix = Matrix.CreateScale(scaleX, scaleY, 1.0f);
spriteBatch.Begin(transformMatrix: matrix);
This has to be put in the Draw()-Method.
My virtual screensize was 800x480. I tested it with my Monitor size 1920x1080 and this did the job.
I am trying to create an extended SplashScreen on my UWP app for which the SplashScreen image coordinates are needed. I am using the following code in App.xaml.cs:
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
if (e.SplashScreen != null)
var SplashLocation = e.SplashScreen.ImageLocation;
//Rest of initialization...
}
However, if I inspect SplashLocation which is a Rect, SplashLocation.Height and SplashLocation.Width return 1280 and 768 which is the dimension of my phone's screen. All other properties are 0.
Is this a known bug in Win 10 Mobile [build 10536]? It works fine on desktop Windows 10.
Actually the issue is that the code given on the MSDN docs is wrong. Have a look at their samples on Github instead. You can find it here:
Splash Screen Sample
Notice the differences between the MSDN docs and the sample:
ExtendedSplash DOES NOT extend page
They use a ScaleFactor for phone
The root element of the XAML is Grid and not page.
I followed their sample (after hours of wondering) and it all worked well. I hope they update their docs to reflect the correct thing.
As a workaround, here's what I did:
Create an Image in XAML inside a Grid (and NOT inside a Canvas as suggested by the msdn Docs)
<Image Name="ExtSplash"
Stretch="Uniform"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Source="Assets/Splash/SplashScreen.png"/>
Now, the trick is to make it work on both Mobile (which doesn't give correct Rect coordinates and Desktop (which works as expected)
So, in the loaded event of Page in code behind, I used this code:
if (splash.Top < splash.Left)
ExtSplash.Margin = new Thickness(splash.Top);
else
ExtSplash.Margin = new Thickness(splash.Left);
where Splash = e.SplashScreen.ImageLocation from the OnLaunched event in App.xaml.cs.
This works because, Splash.Top and Splash.Left both return 0 in case of Mobile. So the app just displays the splashscreen fully extended to the width. In case of Desktop, the Image may have some Left or Top Coordinates as it's reported correctly on desktop, where I set them as Margin for the centrally aligned uniform stretched image.
NOTE 1: There may be cases where a slight variation may occur between splashscreen and the ExtendedSplash image. But in my testing it worked fine. It will continue to work even when in a later build MS fixes the issue, so you can take your time to implement the standard method then.
NOTE 2: I had some issues with this logic if scale-400 splashscreen image was provided. For some reason WM10 picks up the highest resolution available. So I just supplied 100, 125, 150 and 200 scale images (skipped the 400)
I ended up ditching the SplashScreen.ImageLocation approach. The Microsoft tutorial does not work on mobile at the time of writing, and the sample is hackish. Instead I used a simple layout like this for the extended splash screen:
<Grid>
<Image x:Name="splashScreenImage" Source="Assets/SplashScreen.png" MaxWidth="620" MaxHeight="300"/>
<!-- plus some other control -->
</Grid>
The magic is to use MaxWidth/MaxHeight.
On mobile the the image will be slightly different positioned vertically (because of status bar and navigation bar I guess), but otherwise correct including size. On desktop the image seems to be exactly positioned and sized as the initial splash.
I have a media element in my wpf application which includes a loading gif. When the user selects a long running process, it basically displays a loader gif to let the user know that the process is running. What I am trying to do is to disable it once the long running process has stopped running. I have included the XAML and process ended event for it below. Also, the main part, this is how I am starting the gif and stopping the gif. I might be wrong there.
loadGif.Play();
// Long running process(s)
loadGif.Pause();
loadGif.Close();
XAML BELOW:
<MediaElement Name="loadGif" HorizontalAlignment="Left" LoadedBehavior="Manual" MediaEnded="process_Ended" Height="22" Margin="609,226,0,0" VerticalAlignment="Top" Width="31" RenderTransformOrigin="-0.258,0.523" Source="C:\\ajax-loader.gif"/>
Process Ended:
private void process_Ended(object sender, RoutedEventArgs e)
{
loadGif.Position = new TimeSpan(0, 0, 1);
loadGif.Play();
}
Also, I forgot to mention what happens right now, at the moment, the gif starts when its supposed to start and after the process(s) are done, it disappears and a black square takes its spot. Since the background of my application is white, its just a small black box sitting there after the processing is done. Essentially, the media element spot goes all black. Thanks for any help!
Set the Visibility of the MediaElement to either Collapsed or Hidden, depending on how you want the layout to work.
loadGif.Visibility = Visibility.Collapsed;
I am facing a severe issue with the Camera API, and even if I know that in 99.99% of the situations, frameworks are not to blame, I'm starting to consider that there may be an issue with the way cameras are handled in windows phone.
The Issue
My code is trivial, there are just two very simple pages: the first one is a button used to navigate to the second one, which uses the camera API and renders the preview buffer on screen. On the first page, I also added a rectangle with a looping animation to rotate it, in order to force the application to update the frame rate.
The result of a profile session is as follows:
As long as I stay on the first page, the framerate counter displays a rock solid 60fps. Once I launch the second page featuring the camera, the fps drops due to the use of the system camera. However, when I hit the back key, the camera is correctly disposed, but the framerate is a bit lower (~53 fps). More impressive, the graph data shows that something is still running and hurting the perfs! The built-in analysis tells me that system apps use 47% of the CPU, the same that when the camera page was shown!
Is there a known reason for this behavior?
My Code
My code-behind for the second page:
public partial class MyScannerView : PhoneApplicationPage {
private PhotoCamera camera;
public MyScannerView() {
InitializeComponent();
}
protected override void OnNavigatedTo(NavigationEventArgs e) {
base.OnNavigatedTo(e);
camera = new PhotoCamera(CameraType.Primary);
viewfinderBrush.SetSource(camera);
}
protected override void OnNavigatedFrom(NavigationEventArgs e) {
base.OnNavigatedFrom(e);
if (camera != null) {
camera.Dispose();
camera = null;
}
}
}
My XAML for the second page:
<Canvas x:Name="viewfinderCanvas">
<Canvas.Background>
<VideoBrush x:Name="viewfinderBrush">
<VideoBrush.RelativeTransform>
<CompositeTransform x:Name="viewfinderTransform" CenterX="0.5" CenterY="0.5" />
</VideoBrush.RelativeTransform>
</VideoBrush>
</Canvas.Background>
</Canvas>
I had similar looking issue with application, which uses camera.
Managed to overcome it with using not OnNavigatedFrom but OnNavigatingFrom override and doing it in such order:
Unsubscribing from events
Dispose();
camera = null;
I added camera to an my App which is all in Portrait mode so would like the to keep it this way.
Here is the relevant code snippets I use in my .XAML
SupportedOrientations="Portrait" Orientation="Portrait"
mc:Ignorable="d" d:DesignHeight="800" d:DesignWidth="480"
<Canvas x:Name="viewfinderCanvas" Width="480" Height="800" >
<!--Camera viewfinder -->
<Canvas.Background>
<VideoBrush x:Name="viewfinderBrush">
</VideoBrush>
</Canvas.Background>
</Canvas>
Here is my setup code from the .XAML.CS
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
if (PhotoCamera.IsCameraTypeSupported(CameraType.FrontFacing))
{
cam = new Microsoft.Devices.PhotoCamera(CameraType.FrontFacing);
}
else
{
cam = new Microsoft.Devices.PhotoCamera(CameraType.Primary);
}
cam.Initialized += new EventHandler<Microsoft.Devices.CameraOperationCompletedEventArgs>(cam_Initialized);
cam.CaptureCompleted += new EventHandler<CameraOperationCompletedEventArgs>(cam_CaptureCompleted);
cam.CaptureImageAvailable += new EventHandler<Microsoft.Devices.ContentReadyEventArgs>(cam_CaptureImageAvailable);
cam.CaptureThumbnailAvailable += new EventHandler<ContentReadyEventArgs>(cam_CaptureThumbnailAvailable);
viewfinderBrush.SetSource(cam);
}
The problem is that I hold the phone in Portrait and point the phone at a person. The screen shows the persons head on the right side of the screen and the persons feet at the left of the screen.
While as they stand in front of me there head should be at the top of the screen and there feet at the bottm, cause these people aint superman.
So it seems the image from the camera is getting rotated -90 before it appears on the screen.
Can anybody explain whats going wrong and what sample code I need to implement to fix this problem.
Thanks,
-Code
You need to implement a VideoBrush.RelativeTransform, as detailed in the following article :-
http://msdn.microsoft.com/en-us/magazine/hh708750.aspx
Also covered in the following :-
ViewFinder Orientation With Windows Phone 7 Mango PhotoCamera
just add this line to the C# code of your camera page. It will transform and handle the camera video stream in portrait mode correctly.
viewfinderTransform.Rotation = 90;