I am using MediaCapture class for camera view. But i have a problem that it supports only front camera of tablet, i want to switch between front and back camera by clicking a button.
How can i do it??
Sajid,
This example code from the Win8 Dev Center will show you how to enumerate through the camera devices connected to a current machine: http://code.msdn.microsoft.com/windowsapps/Media-Capture-Sample-adf87622
And here's another example which deals with DeviceEnumeration more specifically: http://code.msdn.microsoft.com/windowsapps/Device-Enumeration-Sample-a6e45169
Relevant code (from first link) :
private async void EnumerateWebcamsAsync()
{
try
{
ShowStatusMessage("Enumerating Webcams...");
m_devInfoCollection = null;
EnumedDeviceList2.Items.Clear();
m_devInfoCollection = await DeviceInformation.FindAllAsync(DeviceClass.VideoCapture);
if (m_devInfoCollection.Count == 0)
{
ShowStatusMessage("No WebCams found.");
}
else
{
for (int i = 0; i < m_devInfoCollection.Count; i++)
{
var devInfo = m_devInfoCollection[i];
EnumedDeviceList2.Items.Add(devInfo.Name);
}
EnumedDeviceList2.SelectedIndex = 0;
ShowStatusMessage("Enumerating Webcams completed successfully.");
btnStartDevice2.IsEnabled = true;
}
}
catch (Exception e)
{
ShowExceptionMessage(e);
}
}
edit: this code is taken from the AdvancedCapture.xaml.cs file from the first code sample I posted.
Related
I am having a problem with my gallery code, my Android does not recognize the right folder with the .jpg images on the line 20 and 30. It´s a lot different that a PC code cause of the disk details, if someone could help me, i will be a lot gratefull
public class Gallery : MonoBehaviour {
public List<Sprite> gallery = new List<Sprite>();
public Image displayImage;
public Button nextImg;
public Button prevImg;
public int i = 0;
void Start ()
{
// var Images = Directory.GetFiles("C:/Users/Bandeira/Downloads/Menu Start/Assets/Sprite/JPG/","*.jpg");
var Images = Directory.GetFiles("file:///" + "/unitypictures/","*.jpg");
Debug.Log(Images);
StartCoroutine(LoadImages(Images));
}
IEnumerator LoadImages(string[] Images)
{
foreach (var path in Images)
{
Debug.Log(path);
using (var uwr = UnityWebRequestTexture.GetTexture("file:///" + path))
// using (var uwr = UnityWebRequestTexture.GetTexture(path))
{
Debug.Log(path);
yield return uwr.SendWebRequest();
if (uwr.result != UnityWebRequest.Result.Success)
{
Debug.Log(uwr.error);
yield break;
}
var tex = DownloadHandlerTexture.GetContent(uwr);
var sprite = Sprite.Create(tex, new Rect(0f, 0f, tex.width, tex.height), new Vector2(0.5f, 0.5f), 50f, 0, SpriteMeshType.FullRect);
gallery.Add(sprite);
uwr.Dispose();
}
yield return null;
}
}
public void BtnNext (){
if(i + 1 < gallery.Count){
i++;
}
displayImage.sprite = gallery[i];
}
public void BtnPrev () {
if (i - 1 > 0){
i--;
}
displayImage.sprite = gallery[i];
}
}
Dude, I already told you yesterday.
You are using absolute paths, and they cannot work, because for each operating system they are different.
If you connect your Android phone to your computer, or install a file manager, you can see that there should be no folder called "UnityPictures", and even if there is you can't get there easily because I believe they are protected by the device.
The answer is always the same: you can use Persistent data path to save the images and resume them later.
For example you can save them in the Directory (Application.PersistentDataPath + "UnityPictures") and get them back from the same path.
So to be clear: you have to create the folder and insert those images, if you then want to download them.
Alternatively you can also download them from a server. So you could edit them, add more, or remove them without the need for updates, and it would be usable for all devices.
I need some advice on how to use the camera in Xamarin.Forms.
Currently, NuGet Xam.Plugin.Media.
Media. With the following code, when you press a button from the UI, the camera starts up, takes a picture and displays the image on the screen.
private async void OnCameraTapped(object sender, EventArgs e)
{
var photo = await CaptureCamera();
Image.Source = ImageSource.FromStream() =>
{
return new MemoryStream(photo);
});
}
```
```
private async Task<byte[]> CaptureCamera()
{
await Plugin.Media.CrossMedia.Current. Initialize();
Initialize(); if (!Plugin.Media.CrossMedia.Current. IsCameraAvailable ||
!Plugin.Media.CrossMedia.Current. IsTakePhotoSupported)
{
return null;
}
var file = await Plugin.Media.CrossMedia. CrossMedia.
.TakePhotoAsync(
new Plugin.Media.Abstractions. StoreCameraMediaOptions
{
Directory = "Photo",
Name = DateTime.Now.ToString("yyyy_MMdd_HHHmm ") + "Photo.jpg",
});
if (file == null)
return null;
var bytes = new Queue<byte>();
using (var s = file.GetStream())
{
var length = s.Length;
int b;
while ((b = s.ReadByte()) ! = -1)
bytes.Enqueue((byte)b);
}
Dispose();
Dispose(); if (bytes == null) return null;
return bytes.ToArray();
}
However, this method uses Plugin.Media.CrossMedia, which means that the There are some restrictions. I would like to know how to get around those constraints.
Q) I need to press the shutter release and then press "OK" on the activated camera. I want to finish the process by just pressing the shutter release.
Q) The camera I started up defaults to out-camera. I want to take a picture of myself, so I want to start the in-camera as the default.
How can I get around the above two points?
My environment is as follows.
OS Windows 10 Home
IDE Visual Studio 2019 community
Xamarin.Form(.NET Standard 2.1)
Target Android 9.0(API 28)
I have a UWP app running on a surface pro device and I am trying to tell if a keyboard is attached to the device (this is the surface pro keyboard so attaches to the bottom, not usb) so that my application can go down different code paths.
Here is the list of things I have tried and their results:
1.
How to detect if the surface keyboard is attached?
KeyboardCapabilities keyboardCapabilities = new Windows.Devices.Input.KeyboardCapabilities();
return keyboardCapabilities.KeyboardPresent != 0 ? true : false;
But this always returns true on a surface pro device as specified here: Windows 8 WinRT KeyboardCapabilities.KeyboardPresent is always true
2. How to detect if the surface keyboard is attached?
Converted the Network watcher to c#
public bool KeyboardAttached { get; set; }
private void SetupKeyboardWatcher()
{
var watcher = Windows.Devices.Enumeration.DeviceInformation.CreateWatcher();
watcher.Added += Watcher_Added;
watcher.Updated += Watcher_Updated;
watcher.Removed += Watcher_Removed;
watcher.Start();
}
private void Watcher_Updated(Windows.Devices.Enumeration.DeviceWatcher sender, Windows.Devices.Enumeration.DeviceInformationUpdate args)
{
if (args.Id.IndexOf("{884b96c3-56ef-11d1-bc8c-00a0c91405dd}") != -1)
{
if (args.Properties.ContainsKey("System.Devices.InterfaceEnabled"))
{
// keyboard is connected
KeyboardAttached = true;
}
else
{
// keyboard disconnected
KeyboardAttached = false;
}
}
}
private void Watcher_Added(Windows.Devices.Enumeration.DeviceWatcher sender, Windows.Devices.Enumeration.DeviceInformation args)
{
if ((args.Id.IndexOf("{884b96c3-56ef-11d1-bc8c-00a0c91405dd}") != -1) && (args.Id.IndexOf("MSHW0007") == -1))
{
if (args.Properties.ContainsKey("System.Devices.InterfaceEnabled"))
{
// keyboard is connected
KeyboardAttached = true;
}
}
}
private void Watcher_Removed(Windows.Devices.Enumeration.DeviceWatcher sender, Windows.Devices.Enumeration.DeviceInformationUpdate args)
{
if (args.Id.IndexOf("{884b96c3-56ef-11d1-bc8c-00a0c91405dd}") != -1)
{
if (args.Properties.ContainsKey("System.Devices.InterfaceEnabled"))
{
// keyboard is connected
KeyboardAttached = true;
}
else
{
// keyboard disconnected
KeyboardAttached = false;
}
}
}
This returns keyboardAttached true when the onscreen keyboard shows up
3. How to detect if the surface keyboard is attached?
bool bIsDesktop = false;
var uiMode = UIViewSettings.GetForCurrentView().UserInteractionMode;
if (uiMode == Windows.UI.ViewManagement.UserInteractionMode.Mouse) // Typical of Desktop
bIsDesktop = true;
always returns true
Outside of my app the Windows OS acts differently depending on whether the keyboard is attached or not (it pops up a on screen keyboard) so there must be a way of doing it.
I'm not sure whether this link contains any information of relevance https://learn.microsoft.com/en-us/windows-hardware/drivers/hid/keyboard-and-mouse-class-drivers
Is there a way of telling if a keyboard is attached to a surface pro device?
I have a video player which loads videos (.wav) to a playlist and scrolls through the playlist using a play queue manipulated by the playstatechange events. It works fine except for a black flicker (usually just one) that happens on the last frame of a random video (never the same spot in the play list or the same video). This also occurs on multiple computers so I am pretty sure it is not any video card settings, unless an obscure codec issue. This is for a research experiment and cannot have the flicker, it must be completely seamless. I have searched through every question and the only similar one did not involve a playlist of multiple videos, his flicker was when looping the same video, thus a totally different solution. Here is my video player creation and implementation:
public void MultipleVideos()
{
player.CreateControl();
player.Enabled = true;
player.enableContextMenu = false;
player.uiMode = "none";
player.Name = "player";
player.Anchor = AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Bottom;
WMPLib.IWMPMedia media;
WMPLib.IWMPPlaylist playlist = player.playlistCollection.newPlaylist("myplaylist");
for (int x = 0; x < _presented.count; x++)
{
media = player.newMedia(_presented.getItem(x).video);
playlist.appendItem(media);
}
player.currentPlaylist = playlist;
}
private void player_PlayStateChange(object sender, AxWMPLib._WMPOCXEvents_PlayStateChangeEvent e)
{
if (!currSess.playOne)
{
if (e.newState == 8 | e.newState == 9)
{
if (e.newState == 8)
{
currSess.playQueue++;
}
}
if (currSess.playQueue+1 > player.currentPlaylist.count -1)
{
if (e.newState == 10)
{
player.uiMode = "invisible";
player.Visible = false;
displayImgs();
currSess._timer.start();
AllowControls(true);
allowItems();
player.PlayStateChange -= foo;
currSess.playQueue = 0;
}
}
}
}
I'm having a little hard time after navigating around the site to find out solution. The problem I have is that I'm trying to capture an image using mediacapture taken from this url (download here).
I've found a couple threads in SO that deal with resolution already, but what they're doing is using default resolution as following
3024*4992.......4:3
1936*2592...162:121
1536*2048.......4:3
480*640..........4:3
3024*5376.....16:9
1728*3072.....16:9
1456*2592...162:91
(suggeted by this)
However what I want is to capture an image with 800x600 resolution, is this really possible somehow?
You can use 800x600 only if your camera supports it. My camera for example doesn't.
Find available resolutions:
uint[] x_res; // available horizontal resolutions
uint[] y_res; // available vertical resolutions
uint resolutionwidth; //used horizontal resolution
uint resolutionheight; //used vertical resolution
private void get_res_button_click(object sender, RoutedEventArgs e)
{
resolution_listbox.Items.Clear();
IEnumerable<VideoEncodingProperties> available_resolutions = captureManager.VideoDeviceController.GetAvailableMediaStreamProperties(MediaStreamType.Photo).Select(x => x as VideoEncodingProperties);
int total_res = available_resolutions.Count();
x_res = new uint[total_res];
y_res = new uint[total_res]
int i = 0;
foreach (VideoEncodingProperties resolution in available_resolutions)
{
x_res[i] = resolution.Width;
y_res[i] = resolution.Height;
resolution_listbox.Items.Add(x_res[i].ToString() + " x " + y_res[i].ToString());
i++;
}
}
Select the one you want:
private async void resolution_listbox_selectionchanged(object sender, SelectionChangedEventArgs e)
{
if (resolution_listbox.SelectedItem != null)
{
int j = resolution_listbox.SelectedIndex;
resolutionwidth = x_res[j];
resolutionheight = y_res[j];
}
// And apply it:
IReadOnlyList<IMediaEncodingProperties> resolutions = captureManager.VideoDeviceController.GetAvailableMediaStreamProperties(MediaStreamType.Photo);
for (int k = 0; k < resolutions.Count; k++)
{
if (resolutions[k] is VideoEncodingProperties)
{
VideoEncodingProperties vidprops = (VideoEncodingProperties)resolutions[k];
// check which VideoEncodingProperties contains the correct resolution
if (vidprops.Width == resolutionwidth && vidprops.Height == resolutionheight)
{
await captureManager.VideoDeviceController.SetMediaStreamPropertiesAsync(MediaStreamType.Photo, resolutions[k]);
}
}
}
}
Note:in the 1st method I used IEnumerable< VideoEncodingProperties > . This because I only want the numbers.
In the 2nd method I used IReadOnlyList< IMediaEncodingProperties >. This is because only the VideoEncodingProperties which contains the wanted resolution, needs to be applied. Not every IMediaEncodingProperties contains resolution information.