Xamarin Forms: save camera image to external storage - c#

I'm developing an application using Xamarin Forms, I'm using this MediaPlugin to capture image and store it in the device. What I want is to store the captured image in the external storage (external SD Card), here is my code, it stores the images in a folder created in the local storage when the application installed. I tried to change the directory line to
Directory = "/storage/extSdCard/ImagesFolder/",
but his creates a local folder with name storageextSdCardImagesFolder
is there any idea how to store the image in external storage? I'm only interested in Android device.
private async void takePhotoBtn_Clicked(object sender, EventArgs e)
{
await CrossMedia.Current.Initialize();
if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakePhotoSupported)
{
await DisplayAlert("No Camera", ":(No camera available.", "OK");
return;
}
_mediaFile = await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions
{
Directory = "ImagesFolder",
Name = _farmId + ".jpg"
});
if (_mediaFile == null)
return;
FileImage.Source = ImageSource.FromStream(() =>
{
var stream = _mediaFile.GetStream();
_mediaFile.Dispose();
return stream;
});
}

Related

Copy files to USB using C# Windows 10 iot core

I am trying to copy .csv files created in the local folder in Windows 10 iot core. I have tried few ways but no luck. My latest code is as follows:
string aqs = UsbDevice.GetDeviceSelector(0x045E, 0x0611);
var myDevices = await Windows.Devices.Enumeration.DeviceInformation.FindAllAsync(aqs);
UsbDevice usbDevice;
try
{
if(myDevices == null)
{
return;
}
usbDevice = await UsbDevice.FromIdAsync(myDevices[0].Id);
StorageFolder localFolder = Windows.Storage.ApplicationData.Current.LocalFolder;
StorageFolder sourcef = await localFolder.CreateFolderAsync("My Data", CreationCollisionOption.OpenIfExists);
IReadOnlyList<StorageFile> filel = await sourcef.GetFilesAsync();
StorageFolder removableDevices = KnownFolders.RemovableDevices;
//var externalDrives = await removableDevices.GetFoldersAsync();
//var drive0 = externalDrives[0];
//var destFolder = await removableDevices.CreateFolderAsync("My Data", CreationCollisionOption.GenerateUniqueName);
foreach (StorageFile file in filel)
{
await file.CopyAsync(removableDevices);
}
}
In the above i get an exception on:
usbDevice = await UsbDevice.FromIdAsync(myDevices[0].Id);
'myDevices[0].Id' threw an exception of type 'System.ArgumentOutOfRangeException'
I have tried checking if this is null and it is not null.
The aim of this is to basically copy few text files from Local Folder to the USB drive.
The usb storage can not be found by using UsbDevice.GetDeviceSelector, the methods in Windows.Devices.Usb namespace are used for valid WinUSB device which has a compatible id of USB\MS_COMP_WINUSB, but a usb storage will not include compatible id.In fact, KnownFolders.RemovableDevices is enough to access the device.

Uploading video to Azure Storage through Xamarin

I'm trying to upload a video file to my Azure Storage account. I've got it working with images, however trying to view an uploaded video gives the message "Video format or MIME-type is not supported". The video format is mp4.
I use the following code to upload:
public async Task UploadVideo(Stream video, string path)
{
var container = GetContainer("videos");
// Creates the container if it does not exist
await CreateContainer(container);
//Gets the file extension
string lastPart = path.Split('.').Last();
// Uploads the video to the blob storage
CloudBlockBlob videoBlob = container.GetBlockBlobReference(path);
videoBlob.Properties.ContentType = "video/" + lastPart;
await videoBlob.UploadFromStreamAsync(video);
}
Am I doing something wrong?
Thanks
Edit:
Here's the code I use to capture video on the phone:
private async Task TakeVideoButton_Clicked(object sender, EventArgs e)
{
if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakeVideoSupported)
{
await DisplayAlert("No Camera", ":( No camera avaialble.", "OK");
return;
}
mediaFile = await CrossMedia.Current.TakeVideoAsync(new Plugin.Media.Abstractions.StoreVideoOptions
{
Name = "video.mp4",
Directory = "DefaultVideos",
});
if (mediaFile == null)
return;
await DisplayAlert("Video Recorded", "Location: " + mediaFile.Path, "OK");
videoStream = mediaFile.GetStream();
file.Dispose();
}
I just tested this on my phone instead of my emulator and it worked perfectly there, so I'm going to assume it's purely a emulator related issue.

UWP playing a .aif file with AudioGraph

I am trying to play a sound with audio graph and it is failing on creating a file output node from a storage file. I have checked and the storage file is not null; The error I am getting is just unknown error and is of no help
Any ideas?
private async void HandlePlayCommand()
{
if (_audioGraph == null)
{
var settings = new AudioGraphSettings(AudioRenderCategory.Media);
var createResults = await AudioGraph.CreateAsync(settings);
if (createResults.Status != AudioGraphCreationStatus.Success) return;
_audioGraph = createResults.Graph;
var deviceResult = await _audioGraph.CreateDeviceOutputNodeAsync();
if(deviceResult.Status != AudioDeviceNodeCreationStatus.Success) return;
var outputNode = deviceResult.DeviceOutputNode;
StorageFile file = await GetStorageFiles();
var fileResult = await _audioGraph.CreateFileInputNodeAsync(file);
if (fileResult.Status != AudioFileNodeCreationStatus.Success) return;
var fileInputNode = fileResult.FileInputNode;
fileInputNode.AddOutgoingConnection(outputNode);
_audioGraph.Start();
}
}
private async Task<StorageFile> GetStorageFiles()
{
string CountriesFile = #"Assets\909_1.aif";
StorageFolder InstallationFolder = Windows.ApplicationModel.Package.Current.InstalledLocation;
StorageFile file = await InstallationFolder.GetFileAsync(CountriesFile);
return file;
}
By testing on my side, I'm afraid the .aif format currently is not supported by AudioGraph.CreateFileInputNodeAsync method. The formats sure to be supported that are .mp3,.wav,.wna,.m4a and so on. So the solution maybe change the audio files to other formats.
More details please reference the audio official sample.

How to access isolated storage file from HTML or Javascript for Windows Phone and PhoneGap Application

I am using PhoneGap to develop application for Windows, Android and iOS platform.
I have one problem and need expert assistance from you guys.
I have created one plugin for Windows Phone. Plugin is basically download images from URL and stored in isolated storage folder inside Downloads folder this is working successfully.
Now my problem is does there any way to access isolated storage files from javascript. for example i have downloaded one image and stored in isolated storage ("Download/logo.png) now i have to set this image to my html image source. e.g. <img src="ms-appdata:///local/Downloads/logo.png"/>
But couldn't get success. i have tried several way without luck.
I have using following code to save files in isolated storage.
//This code is working fine for saving image from url to isolated storage
IsolatedStorageFile ISF = IsolatedStorageFile.GetUserStoreForApplication();
//Create directory if does not exists
if (ISF.DirectoryExists(IMAGE_FOLDER_PATH) == false)
{
Debug.WriteLine("Directory created");
ISF.CreateDirectory(IMAGE_FOLDER_PATH);
}
WebClient client = new WebClient();
string modeuleName = hamBurgerMenu[MODULENAME_COLUMN_INDEX];
client.OpenReadCompleted += (s, e) =>
{
if (e.Error == null)
{
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
using (var isoStore = IsolatedStorageFile.GetUserStoreForApplication())
{
string fullPath = Path.Combine(IMAGE_FOLDER_PATH, modeuleName + ".png");
var bi = new BitmapImage();
bi.SetSource(e.Result);
var wb = new WriteableBitmap(bi);
using (var isoFileStream = isoStore.CreateFile(fullPath))
{
var width = wb.PixelWidth;
var height = wb.PixelHeight;
Extensions.SaveJpeg(wb, isoFileStream, width, height, 0, 100);
}
}
});
}
};
client.OpenReadAsync(new Uri(imageURL, UriKind.Absolute));
I have tried following solutions but couldn't get success at all.
<img src="file:///C:|/Data/Users/DefApps/AppData/{9DB..............0CC}/local/Downloads/logo.png"/>
<img src="ms-appdata:///local/Downloads/logo.png"/>
<img src="ms-appx:///Downloads/logo.png"/>
Your comments or suggestion would be highly appreciated!
Thanks & Regards,
Imdadhusen
I have resolved the issue using below code. The purpose of posting answer is it might help other people who are searching for the same.
Now i am saving downloaded images at app's Local Folder.
Following function will download image from live URL.
private void downloadImage(string imageURL, string[] hamBurgerMenu)
{
string ext = Path.GetExtension(imageURL.Trim());
try
{
WebClient client = new WebClient();
client.OpenReadCompleted += (s, e) =>
{
if (e.Error == null)
{
Deployment.Current.Dispatcher.BeginInvoke(async () =>
{
await saveImage(e.Result, imageURL);
});
}
else
{
//Download Image Not Found
}
};
client.OpenReadAsync(new Uri(imageURL, UriKind.Absolute));
}
catch (Exception e)
{
//Download Error
}
}
Now i am saving the downloaded image using below function
// Save a downloaded images to the app’s local folder.
public async Task saveImage(Stream photoToSave, string imageURL)
{
StorageFile photoFile = null;
try
{
string ext = Path.GetExtension(imageURL.Trim());
photoFile = await localFolder.CreateFileAsync(ext, CreationCollisionOption.ReplaceExisting);
using (var photoOutputStream = await photoFile.OpenStreamForWriteAsync())
{
await photoToSave.CopyToAsync(photoOutputStream);
}
}
catch (Exception e)
{
//Error while saving file
}
}
Now we can access the file using following path at HTML page or Client side script
Important:- <APP_ID> e.g. {8A027331-C7348-182D188-8A02473-1247801} should be replace with your Application ID. It will be 32 digit key.
<img src="C:\\Data\\Users\\DefApps\\AppData\\<APP_ID>\\local\\ Mobile.jpg" alt="Mobile.jpg" />

Mediaelement in Windows 8 Metro App

I have a scenario specific to my app. I am managing music file playlist in XML for my metro app. And its saving music files actual path like this
D:\MyMedia\1.mp3
I have media element in my XAML page and I am setting its Source like this.
mediaElement.Source = new Uri(#"D:\MyMedia\1.mp3", UriKind.Absolute);
mediaElement.Play();
but its not playing the media and its giving the error like this
MF_MEDIA_ENGINE_ERR_SRC_NOT_SUPPORTED : HRESULT - 0x80070005
So someone tell me how I can play some media file in MediaElement of metro app with absoulte path. Or how I can get stream of my local file to play this media in my mediaElement of Metro app.
To open files on the local system, you can use the FileOpenPicker to get the file and SetSource to set the media source.
var openPicker = new Windows.Storage.Pickers.FileOpenPicker();
openPicker.FileTypeFilter.Add(".mp3");
var file = await openPicker.PickSingleFileAsync();
var stream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read);
if (null != file)
{
mediaElement.SetSource(stream, file.ContentType);
mediaElement.Play();
}
There is only a limited number of locations on a user's PC that you can access. "D:\Mymedia" is not one of those. You will find all the necessary information in the Microsoft help. Check out these two articles:
Quickstart: Accessing files programmatically
File access and permissions in Windows Store apps
This can be done without a file picker. You just have to add Music Library capabilities to your app manifest, make sure the music is in My Music or on an SD Card, and use KnownFolders.MusicLibrary.
In short and in keeping with the music theme of the question:
"You might think file picker...
...but all I need is StorageFile"
//
// Opens and plays song titled "[Cars]You_Might_Think.mp3"
// in the 80s folder.
//
// IMPORTANT: the example song must be in the user's Music
// folder or SD card to be found. Also, the app manifest
// must have 'Music Library' capabilities enabled.
//
//
//
async void OpenAndPlayAwesomeSongFromThe80s()
{
Windows.Storage.StorageFolder folder = KnownFolders.MusicLibrary;
StorageFile song = await folder.GetFileAsync("80s\\[Cars]You_Might_Think.mp3");
if (song != null)
{
IRandomAccessStream stream = await song.OpenAsync(Windows.Storage.FileAccessMode.Read);
if (stream != null)
{
mediaElement = new MediaElement();
mediaElement.SetSource(stream, song.ContentType);
mediaElement.Play();
}
}
}
I know it's an old problem, I found a really simple solution..
Windows.Storage.StorageFile file = null;
mediaElement player = new MediaElement();
async Task PlayAsync()
{
if (file == null)
{
file = await OpenFileAsync();
try { player.MediaOpened -= Player_MediaOpenedAsync; } catch { }
try { player.MediaEnded -= Player_MediaEnded; } catch { }
try { player.MediaFailed -= Player_MediaFailed; } catch { }
player.MediaOpened += Player_MediaOpenedAsync;
player.MediaEnded += Player_MediaEnded;
player.MediaFailed += Player_MediaFailed;
player.SetPlaybackSource(MediaSource.CreateFromStorageFile(file)); //Works with media playback..
//player.Source = new Uri(mediasource, UriKind.RelativeOrAbsolute); //Doesn't work with media playback for some reason..
Playing = true;
Paused = false;
}
else
{
if (Paused)
{
player.Play();
Paused = false;
}
else
{
player.Pause();
Paused = true;
}
}
}
async Task<StorageFile> OpenFileAsync()
{
try
{
var ofd = new FileOpenPicker();
ofd.FileTypeFilter.Add("*");
return await ofd.PickSingleFileAsync();
}
catch { }
return null;
}

Categories

Resources