I'm building an app that needs to take a photo with webcam and save it to the local disk, so far I have this:
async private void CapturePhoto_Click(object sender, RoutedEventArgs e)
{
Windows.Storage.StorageFolder localFolder = Windows.Storage.ApplicationData.Current.LocalFolder;
ImageEncodingProperties imgFormat = ImageEncodingProperties.CreateJpeg();
// create storage file in local app storage
StorageFile file = await localFolder.CreateFileAsync("TestPhoto.jpg", CreationCollisionOption.GenerateUniqueName);
StorageFile localFile = await localFolder.CreateFileAsync("webcamPhotoTest.jpg", CreationCollisionOption.ReplaceExisting);
// take photo
// save to app storage
await captureManager.CapturePhotoToStorageFileAsync(imgFormat, file);
// save to local storage
await captureManager.CapturePhotoToStorageFileAsync(imgFormat, localFile);
// Get photo as a BitmapImage
BitmapImage bmpImage = new BitmapImage(new Uri(file.Path));
// imagePreview is a <Image> object defined in XAML
imagePreview.Source = bmpImage;
}
I am able to save the jpg image both to app storage and local storage but I need to be able to
a) Specify the path to save to
b) do so without requiring user interaction (e.g windows save file prompt)
There are no support for System.Drawing in Windows 8 apps which complicates things. Most answers I've found have either been using System.Drawing features or windows' save file prompt.
You can't really use any location that you want. There is the list of locations that you can access from your app: File access and permissions in Windows Store apps. Some locations require additional declarations in the manifest file of your project.
Related
On C#, raspberry, windows IOT,
The app stop on this line
StorageFile file = await storageFolder.GetFileAsync("Signature.jpg",
CreationCollisionOption.ReplaceExisting);
I get this error :
an item cannot be found at the specified path
But Signature.jpg is on this folder existing
Thanks for your help,
I can also reproduce this issue when access the shared file on a computer from Windows 10 IoT core.
The workaround for this issue is that you can setup a web server to share the file instead of using file sharing. For example, I setup the IIS on my computer and copy the signature.jpg to the root folder of IIS(C:\inetpub\wwwroot). Then we can use the code below download the file from IIS:
async void DownloadImageAndDisplay()
{
Uri fileUri = new Uri("http://{AddressOfPC}/signature.jpg");
IRandomAccessStreamReference thumbnail =
RandomAccessStreamReference.CreateFromUri(fileUri);
StorageFile imageFile=await StorageFile.CreateStreamedFileFromUriAsync("signature.jpg", fileUri, thumbnail);
BitmapImage bitmapImage = new BitmapImage();
Windows.Storage.Streams.RandomAccessStreamOverStream stream = (Windows.Storage.Streams.RandomAccessStreamOverStream)await imageFile.OpenAsync(FileAccessMode.Read);
bitmapImage.SetSource(stream);
image.Source = bitmapImage;
}
I am attempting to create a file in the Pictures Library as documented in Microsofts UWP api.
The Pictures Library typically has the following path.
%USERPROFILE%\Pictures
I have enabled the Pictures library capability in the app manifest.
Like so:
File.WriteAllBytes("%USERPROFILE%/Pictures", fileData);
It returns:
DirectoryNotFoundException: Could not find a part of the path 'C:\Data\Users\DefaultAccount\AppData\Local\DevelopmentFiles\HoloViewerVS.Debug_x86.jtth.jh\%USERPROFILE%\Pictures'
`
When I try using my username hard-coded, like so:
File.WriteAllBytes("jtth.jh/Pictures", fileData);
it returns the same DirectoryNotFound exception:
DirectoryNotFoundException: Could not find a part of the path 'C:\Data\Users\DefaultAccount\AppData\Local\DevelopmentFiles\HoloViewerVS.Debug_x86.jtth.jh\jtth.jh\Pictures'`
So, how do you access the Pictures Library and write files to it? Clearly I must be missing something small here as the path its trying to access the pictures library at seems quite odd here.
I see it says how to 'Get the Pictures library.' using a StorageFolder:
public static StorageFolder PicturesLibrary { get; }
But I'm not sure how to add files to this folder variable like the way I'm doing it using the file write.
Can I do it the way I am trying to do it, or do I need to jump through StorageFolder and/or async hoops?
Example for clarification:
string imgName = currentFolderLoaded + "/" + temp.GetComponentInChildren<Text>().text;
//example imgName to enhance clairty
imgName = C:\dev\Users\jtth\Hololens\ProjectFolder\App\HoloApp\Data\myFiles\pics\example.png
//load image
byte[] fileData;
Texture2D tex = null;
fileData = File.ReadAllBytes(imgName);
tex = new Texture2D(2, 2);
tex.LoadImage(fileData);
//test hololens access
//previous attempt -> File.WriteAllBytes("%USERPROFILE%/Pictures", fileData);
//New attempt
AsStorageFile(fileData, imgName);
//Read Texture into RawImage component
ImgObject.GetComponent<RawImage>().material.mainTexture = tex;
//Enable component to render image in game
ImgObject.GetComponent<RawImage>().enabled = true;
Function:
private static async Task<StorageFile> AsStorageFile(byte[] byteArray, string fileName)
{
Windows.Storage.StorageFolder storageFolder = Windows.Storage.KnownFolders.PicturesLibrary;
Windows.Storage.StorageFile sampleFile = await storageFolder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);
await Windows.Storage.FileIO.WriteBytesAsync(sampleFile, byteArray);
return sampleFile;
}
I'm checking the Photos app on the Hololens after running through this code and it doesn't seem to be creating the picture?
If you want your pictures showed in the Photos app on Hololens, actually you may need to save the pictures into CameraRoll folder.
But it seems like it cannot be directly saved, you may need to move the picture file as a workaround.
var cameraRollFolder = Windows.Storage.KnownFolders.CameraRoll.Path;
File.Move(_filePath, Path.Combine(cameraRollFolder, _filename));
Details please reference this similar thread.
It is because UWP applications work under isolated storage. Like the first example in your linked MSDN article says, do something like this:
StorageFolder storageFolder = KnownFolders.PicturesLibrary;
StorageFile file = await storageFolder.CreateFileAsync("sample.png", CreationCollisionOption.ReplaceExisting);
// Do something with the new file.
Plain File.Xxx() calls will be isolated to your application's own little world.
I'm currently having trouble finding out how to implement isolated storage in a windows universal project.
All I want to do is safe some text in isolated storage when a button is clicked and the be able to retrieve it later on a different page for use.
You can use ApplicationData.Current.LocalSettings as a dictionary where you can save some primitive object.
ApplicationData.Current.LocalSettings.Values["MyKey"] = MyValue;
if (ApplicationData.Current.LocalSettings.Values.ContainsKey("MyKey"))
MyValue = ApplicationData.Current.LocalSettings.Values["MyKey"];
You can store your app data locally in UWP, e.g. ApplicationData.Current.LocalFolder, and this is 'Isolated storage' what you are talking about. Here is a code sample for you:
//Create dataFile.txt in LocalFolder and write “My text” to it
StorageFolder localFolder = ApplicationData.Current.LocalFolder;
StorageFile sampleFile = await localFolder.CreateFileAsync("dataFile.txt");
await FileIO.WriteTextAsync(sampleFile, "My text");
//Read the first line of dataFile.txt in LocalFolder and store it in a String
StorageFile sampleFile = await localFolder.GetFileAsync("dataFile.txt");
String fileContent = await FileIO.ReadTextAsync(sampleFile);
You can also see here for more details: Getting started storing app data locally
I am working on a Windows Store app for Windows 8.1, and I can't find anything that addresses what I need to do. I am trying to save an image of a pdf page to my local app data storage. I have the following:
private async void GetFirstPage()
{
// Retrieve file from FutureAccessList
StorageFile file = await Windows.Storage.AccessCache.StorageApplicationPermissions.FutureAccessList.GetFileAsync(token);
// Truncate last 4 chars; ex: '.pdf'
FileName = file.Name.Substring(0, file.Name.Length - 4);
// Get access to pdf functionality from file
PdfDocument doc = await PdfDocument.LoadFromFileAsync(file);
// Get a copy of the first page
PdfPage page = doc.GetPage(0);
// Below could be used to tweak render options for optimizations later
//PdfPageRenderOptions options = new PdfPageRenderOptions();
// Render the first page to the BitmapImage
InMemoryRandomAccessStream stream = new InMemoryRandomAccessStream();
await page.RenderToStreamAsync(stream);
// Common code
Cover.SetSource(stream);
// Convert the active BitmapImage Cover to a storage file to be stored locally
// ???
}
The variable, Cover, is a BitmapImage that is bound in XAML to display the image to the user. I want to save this image to my local app data so that I don't have to re-render it through the PDF library every time my app opens! The problem is I can't save anything in a Windows Store app from a stream unless it is text to my knowledge, (no filestream or fileoutputstreams for me), and Cover's URI source is null, since it was sourced from a stream, making it difficult to get my BitmapImage, Cover, to a StorageFile for proper Windows Store saving.
Everything works for me currently, I'm just upset about re-rendering the pdf page to my bitmapimage from scratch every time my app opens. Thanks in advance for any input!
You need to save the image from the PdfPage directly rather than from the BitmapImage since you can't get the data out of the BitmapImage. The PdfPage.RenderToStreamAsync already encodes the stream as a bitmap so you don't need to do any manipulation beyond sending it to the file. This is essentially the same as what you are doing to save to the InMemoryRandomAccessStream, except to a file based stream:
//We need a StorageFile to save into.
StorageFile saveFile = await ApplicationData.Current.LocalFolder.CreateFileAsync("safedPdf.png",CreationCollisionOption.GenerateUniqueName);
using (var saveStream = await saveFile.OpenAsync(FileAccessMode.ReadWrite))
{
await page.RenderToStreamAsync(saveStream);
}
I am writing a Windows store application that loads .png image from assets.
The code:
private static readonly string filePath = "ms-appx:///Base/Assets/Faces/img1.png";
StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(new Uri(filePath, UriKind.Absolute));
When I test application on computer, image loads correctly, but when I test it on a tablet, image doesn't load. For more information: image doesn't load on ARM processors, on x86 everything works.
Image property set to Copy always and Content.
Try calling the method without UriKind parameter:
StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(new Uri(filePath));