How to change the default camera app in Windows 10 desktop ? The option is available from Settings in Phones but not from Desktops
If you want to make 'advanced' photo capture, then you can use MediaCapture class. Everything about this you will find at MSDN. There are also quite nice samples at GitHub.
It also seems that my old post for WinRT is still quite relevant. You will find there that I'm using GetCameraID:
private static async Task<DeviceInformation> GetCameraID(Windows.Devices.Enumeration.Panel desired)
{
DeviceInformation deviceID = (await DeviceInformation.FindAllAsync(DeviceClass.VideoCapture))
.FirstOrDefault(x => x.EnclosureLocation != null && x.EnclosureLocation.Panel == desired);
if (deviceID != null) return deviceID;
else throw new Exception(string.Format("Camera of type {0} doesn't exist.", desired));
}
to choose a device to be used to capture the photo. In your app you can enumerate devices and choose the one that suits you.
Related
I am developing an UWP application with a camera feature, I have studied this sets of codes,
https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/CameraStarterKit
And successfully developed a camera feature on my application. However, in my application, I wish to not store the picture into my local machine as the application is actually like a kiosk system whereby everyone will be using the same machine to take the picture.
What I am planning to do is actually to allow users to send the picture that they have taken to their own email address via the kiosk system. When they have taken a photo, a preview will be shown, and only if the user want to send the picture, then will the picture be "save"
The codes for my take photo function is something like this:
rivate async Task TakePhotoAsync()
{
var stream = new InMemoryRandomAccessStream();
Debug.WriteLine("Taking photo...");
await _mediaCapture.CapturePhotoToStreamAsync(ImageEncodingProperties.CreateJpeg(), stream);
try
{
var file = await _captureFolder.CreateFileAsync("SimplePhoto.jpg", CreationCollisionOption.GenerateUniqueName);
Debug.WriteLine("Photo taken! Saving to " + file.Path);
var photoOrientation = CameraRotationHelper.ConvertSimpleOrientationToPhotoOrientation(_rotationHelper.GetCameraCaptureOrientation());
await ReencodeAndSavePhotoAsync(stream, file, photoOrientation);
Debug.WriteLine("Photo saved!");
}
catch (Exception ex)
{
// File I/O errors are reported as exceptions
Debug.WriteLine("Exception when taking a photo: " + ex.ToString());
}
}
And to get the preview of the picture will be:
private async Task GetPreviewFrameAsSoftwareBitmapAsync()
{
// Get information about the preview
var previewProperties = _mediaCapture.VideoDeviceController.GetMediaStreamProperties(MediaStreamType.VideoPreview) as VideoEncodingProperties;
// Create the video frame to request a SoftwareBitmap preview frame
var videoFrame = new VideoFrame(BitmapPixelFormat.Bgra8, (int)previewProperties.Width, (int)previewProperties.Height);
// Capture the preview frame
using (var currentFrame = await _mediaCapture.GetPreviewFrameAsync(videoFrame))
{
// Collect the resulting frame
SoftwareBitmap previewFrame = currentFrame.SoftwareBitmap;
// Show the frame information
FrameInfoTextBlock.Text = String.Format("{0}x{1} {2}", previewFrame.PixelWidth, previewFrame.PixelHeight, previewFrame.BitmapPixelFormat);
// Create a SoftwareBitmapSource to display the SoftwareBitmap to the user
var sbSource = new SoftwareBitmapSource();
await sbSource.SetBitmapAsync(previewFrame);
// Display it in the Image control
PreviewFrameImage.Source = sbSource;
}
}
There are (at least) two ways:
1) "Better" one:
Create a backend that sends email using SmtpClient
Post your image from UWP to backend using HttpClient
2) "Easier" one: launch Mail app
The downside is that users will be able to edit the message, receiver and things like that.
Also you can try to use SmtpClient directly from UWP client (may be now with .Net Standard 2.0 it would be possible but I guess no one yet tried) or third-party open-source replacement (which might be a bit outdated as it was created for Windows 8) or even try to launch your backend as Windows Service on the client machine.
I am using MediaCapture to capture photos and store them. It works in the emulator. But when running the app on a real phone (Nokia Lumia 530) the captured photos are just black. They have a correct size and the file has a certain byte length, but when displaying the photo it's black. Please note that I do not use Silverlight and am fixed on using MediaCapture. The camera on the phone works when using the default camera app. The App's manifest includes the capabilities "Pictures Library" and "Webcam".
Does someone know what could be wrong?
Here is the test code I use:
using (var mediaCapture = new MediaCapture())
{
await mediaCapture.InitializeAsync();
ImageEncodingProperties imageFormat = ImageEncodingProperties.CreateJpeg();
StorageFile photoFile = await KnownFolders.PicturesLibrary.CreateFileAsync("TestPhoto.jpg", CreationCollisionOption.GenerateUniqueName);
await mediaCapture.CapturePhotoToStorageFileAsync(imageFormat, photoFile);
BitmapImage bitmap = new BitmapImage();
using (var photoStream = await photoFile.OpenReadAsync())
{
bitmap.SetSource(photoStream);
}
}
Edit
I found a solution. The photo is captured correctly if we have a CaptureElement, set it's source to the MediaCapture object, invoke MediaCapture.StartPreviewAsync before taking the photo, take the photo (using CapturePhotoToStorageFileAsync) and finally invoke StopPreviewAsync. It seems that MediaCapture needs an existing (and displayed) preview to be able to capture photos. Strange that this is not documented and using CapturePhotoToStorageFileAsync without a preview does not throw an Exception.
The photo is captured correctly if we have a CaptureElement, set it's source to the MediaCapture object, invoke MediaCapture.StartPreviewAsync before taking the photo, take the photo (using CapturePhotoToStorageFileAsync) and finally invoke StopPreviewAsync. It seems that MediaCapture needs an existing (and displayed) preview to be able to capture photos. Strange that this is not documented and using CapturePhotoToStorageFileAsync without a preview does not throw an Exception.
I'm starting with Kinect SDK 1.7, using KinectRegion and other controls like KinectTileButton and KinectScrollViewer from the toolkit. My questions are:
How to enable KinectRegion to work with left and right hands?
Does the SDK 1.7 have something ready to work with zooming?
How to detect grip and release?
Any code available on the Internet?
Thank you!
To Enable the Kinect Region :
Import "Microsoft.Kinect.Toolkit.Controls" project into your solution. (Use Add -> Existing Project)
Add Reference of "Microsoft.Kinect.Toolkit.Controls" into your project.
Add KinectRegion into your XAML using this code :
Import/Use "Microsoft.Kinect.Toolkit.Controls" in your xaml.cs file :
using Microsoft.Kinect.Toolkit;
Bind the sensor chooser's current sensor to the KinectRegion :
var regionSensorBinding = new Binding("Kinect") { Source = this.sensorChooser };
BindingOperations.SetBinding(this.kinectRegion, KinectRegion.KinectSensorProperty,
regionSensorBinding);
I don't get what you mean about "zooming". Please give more detail.
To detect hand gripping and hand release, you can add "AddHandPointerGripHandler" and "AddHandPointerGripReleaseHandler" to your KinectRegion. Please take a look to the KinectScrollViewer.cs.
You can explore the code about the hand pointer and stuff from the "Kinect Developer Toolkit Browser App".
As far as I can remember, KinectRegion works with both hand and automatically detects which one is the main one.
The grip and release detection is also automatic on KinectScrollViewer controls.
About the zooming I have no idea.
You'll find good tutorial on Kinect SDK 1.7 Interactions features on this link
Absolutely outstanding course is on the links below:
The first part shows the basic of Kinect SDK
The second part is similiar to firs part, but with use of MS Blend
And the third part is tutorial for interaction stream, where you can get information of both hands.
But if you´d like to use both hand at Kinect region, you have to edit Microsoft.Kinect.Toolkit.Controls -> KinectRegion.cs -> line 1000 (more info in MSDN Blog question)
It helped to me! (I have the same problem)!
For Grip detection is available in kinectRegion -> kinectRegion.HandPointers[idex of hand(0 is left, 1 is right)].IsInGripInteraction - it´s bool - I added some code:
private Skeleton []skeleton;
private void kinect_SkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
{
using (SkeletonFrame sf = e.OpenSkeletonFrame())
{
if (sf != null && this.skeleton != null) // check that a frame is available
{
sf.CopySkeletonDataTo(this.skeleton); // get the skeletal information in this frame
}
}
}
sensor.SkeletonFrameReady += new EventHandler<SkeletonFrameReadyEventArgs>(kinect_SkeletonFrameReady);
foreach (var sk in skeleton)
{
if (sk.TrackingId == 0) continue;
else
{
if (kinectRegion.HandPointers[0].IsInGripInteraction == true)
{
.......
}
}
}
I have got a MVC4 application where I used 51Degrees (Lite) to detect device and accordingly select the mobile (.mobile.cshtml) or desktop (.cshtml) view. 51Degrees can properly do that job. However if I want to switch from Mobile to Desktop view (on a mobile device) using HttpContext.SetOverriddenBrowser(BrowserOverride.Desktop) it doesn't work. FYI, it works without 51Degrees.
Here is the code to select display mode (Application_Start() in Global.asax.cs):
DisplayModeProvider.Instance.Modes.Insert(0, new DefaultDisplayMode("mobile")
{ContextCondition = Context =>Context.Request.Browser["IsMobile"] == "True"
});
Here is the view switcher controller action code:
public class ViewSwitcherController : Controller
{
public RedirectResult SwitchView(bool mobile, string ReturnUrl="/Login/Login")
{
// If the mobile user has requested to view the mobile view
// remove any overridden user agent for the current request
if (Request.Browser.IsMobileDevice == mobile)
HttpContext.ClearOverriddenBrowser();
else
// Otherwise override the browser setting to desktop mode
HttpContext.SetOverriddenBrowser(mobile ? BrowserOverride.Mobile : BrowserOverride.Desktop);
return Redirect(ReturnUrl);
}
}
Here is the code in the view to switch to Desktop view:
#Html.ActionLink("Desktop view", "SwitchView", "ViewSwitcher", new { mobile = false, ReturnUrl = Request.Url.PathAndQuery }, new { rel = "external" })
Please let me know if I'm missing something.
Thanks in advance.
Sorry for my long delayed answer.
The following solution was provided by one of the developers at 51Degrees:
DisplayModeProvider.Instance.Modes.Insert(0, new DefaultDisplayMode("mobile")
{
ContextCondition = Context => Context.GetOverriddenBrowser()["IsMobile"] == "true"
});
So replacing Context.Request.Browser["IsMobile"] with Context.GetOverriddenBrowser()["IsMobile"] fixes my problem.
Hope that helps.
I know this is a bit dated, but I ran into this tonight. Same symptoms. Works without Mobi51, does not with. My working theory is that Request.Browser.IsMobileDevice is touched by Mobi51 and it takes control of that property and sets its value regardless of what you would expect .NET to do with it.
My current solution is this. When I check in my viewstart file to switch layouts I check that both Request.Browser.IsMobileDevice and Context.GetOverridenBrowser().IsMobileDevice are true.
When it's truly Mobile, both will be true. When it's truly desktop, both are false. When it's a mobile view requesting desktop, Request.Browser.IsMobileDevice will be true (because Mobi51 says so) and Context.GetOverridenBrowser().IsMobileDevice will be false. Here's my viewstart
#{
Layout = Request.Browser.IsMobileDevice && Context.GetOverriddenBrowser().IsMobileDevice
? "~/Views/Shared/_LayoutMobile.cshtml"
: "~/Views/Shared/_Layout.cshtml";
}
I'm still vetting this and have to add desktop to mobile switching still (which I can already see a problem, but the change to make that direction work as well is easy enough , but in my five minutes of testing so far tonight this has worked. I'm curious if you found another reason/way to work with this, or if this solution is satisfactory for you.
I would like to know if its possible to get full screen snapshots from an air application.
What i am interested in, is functionality similar to PrintScreen button in windows, which takes snapshots of all screens, including third party application windows, not just window in which air app is running.
If its not specific to air, and flash/flex API can provide such functionality, it also would be great.
Thanx a lot in advance.
Check out this article as it explains obtaining a screenshot by calling a native process:
import flash.filesystem.File;
import flash.events.NativeProcessExitEvent;
var process:NativeProcess;
if(NativeProcess.isSupported) {
var file:File = File.applicationDirectory;
var args:Vector.<String> = new Vector.<String>();
if (Capabilities.os.toLowerCase().indexOf("win") > -1) {
file = file.resolvePath("PATH/TO/WINDOWS/printscr");
//use your prefered screenshot tool here (e.g. https://code.google.com/p/screenshot-cmd/
//also setup the args as needed
} else if (Capabilities.os.toLowerCase().indexOf("mac") > -1) {
file = file.resolvePath("/usr/sbin/screencapture");
args[0] = "-i";
args[1] = "screencapture.png";
}
var nativeProcessStartupInfo:NativeProcessStartupInfo = new NativeProcessStartupInfo();
nativeProcessStartupInfo.arguments = args;
nativeProcessStartupInfo.executable = file;
nativeProcessStartupInfo.workingDirectory = File.desktopDirectory;
process = new NativeProcess();
process.start(nativeProcessStartupInfo);
process.addEventListener(NativeProcessExitEvent.EXIT,done);
}else trace("NativeProcess NOT SUPPORTED!");
function done(e:NativeProcessExitEvent):void{
trace("screenshot comprete");
}
One important thing to bear in mind is the AIR device profile.
If you're initially testing in ADL, be sure to use the extendedDesktop profile, otherwise NativeProcess.isSupported will return false.
For more details check out the NativeProcess documentation and the Communicating with native processes in AIR developer guide