CopyAsync method don`t replace existing file. UWP. Application-storage - c#

Now I am working on edit operation in my app. So in edit operation there is an ability to change image and in the same time name of the file that keep image of the contact can not be renamed(during one session of operation image files will be changing but all this file will take same name).
And I used overload of CopyAsync method (docs to this method here) that as I have understand must to replace file to the existing file with the same name.
I get imageFile variable by FileOpenPicker. Code below runs every time I have choosed image by FileOpenPicker. And when I re-choose image at the result Image UI control show me previous chosen image. I expect that Image will view last image that I have choosed but this does not occurred.
public BitmapImage Image { set; get; }
//Copy of the file that saved in temporary storage
StorageFile fileForView = await imageFile.CopyAsync
(ApplicationData.Current.TemporaryFolder,
fileName,
NameCollisionOption.ReplaceExisting);
Image = new BitmapImage(new Uri(fileForView.Path));
Maybe I understand logic of CopyAsync method not correctly if I am in this case please show me how make my plan working with this method if it is possible. Otherwise offer your solution cause I have no idea now how to do this.
Also I tried to do this with CopyAndReplaceAsync method. But still no result. I do it in this way:
if (null != await ApplicationData.Current.TemporaryFolder.TryGetItemAsync(fileName))
{
StorageFile storageFile = await ApplicationData.Current.TemporaryFolder.GetFileAsync(fileName);
await storageFile.CopyAndReplaceAsync(imageFile);
}

I expect that Image will view last image that I have choosed but this does not occurred.
The above CopyAsync method is correct, and I have tested with the following code, it works well.
private async void ListOption_ItemClick(object sender, ItemClickEventArgs e)
{
FileOpenPicker openPicker = new FileOpenPicker();
openPicker.ViewMode = PickerViewMode.Thumbnail;
openPicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
openPicker.FileTypeFilter.Add(".jpg");
openPicker.FileTypeFilter.Add(".jpeg");
openPicker.FileTypeFilter.Add(".png");
StorageFile file = await openPicker.PickSingleFileAsync();
if (file != null)
{
StorageFile fileForView = await file.CopyAsync(ApplicationData.Current.TemporaryFolder, file.Name, NameCollisionOption.ReplaceExisting);
Image = new BitmapImage(new Uri(fileForView.Path));
TestImg.Source = Image;
}
else
{
}
}

Related

How to save an Image or File Stream in application's settings? UWP C#

I have a List View with some ListViewItems and each one contains a TextBox and an Image.
The user can add or remove these ListViewItems, so I would like to save them in the settings each time the app is closed and load each time it is opened.
I managed to save the TextBoxes' texts in the settings and load them, but how to save and load Images / Image Sources / File Streams?
The images are created when the user chooses an image in a FileOpenPicker and then a Bitmap Image is created with a File Stream to that chosen Image, as the ListViewItem's image source.
private async void openFileInputEvent(object sender, RoutedEventArgs e)
{
var picker = new Windows.Storage.Pickers.FileOpenPicker();
picker.ViewMode = Windows.Storage.Pickers.PickerViewMode.Thumbnail;
picker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.PicturesLibrary;
picker.FileTypeFilter.Add(".jpg");
picker.FileTypeFilter.Add(".jpeg");
picker.FileTypeFilter.Add(".png");
Windows.Storage.StorageFile file = await picker.PickSingleFileAsync();
if (file != null)
{
using (IRandomAccessStream fileStream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read))
{
BitmapImage tmpimg = new BitmapImage();
await tmpimg.SetSourceAsync(fileStream);
imglist.Add(tmpimg);
}
}
else
{
var dialog = new MessageDialog("File not chosen", "No chosen Image");
await dialog.ShowAsync();
imglist.Add(new BitmapImage());
}
}
The bitmap images for all the ListViewItems' images are stored in a list of bitmap images (List<BitmapImage>) and they are chosen by choosing the last item on the list (imglist[imglist.Count-1])
I would like to save and load this Images / their source / file stream to their source, is there any way to do that?
I could save paths to the images, but I can't later create an Image with the path as its source, it has to be a file stream.
How to save an Image or File Stream in application's settings? UWP C#
LocalSettings does not support store the big data, I'm afraid you can't store the BitmapImage into LocalSettings directly, for your scenario, we suggest you store your image in the app's LocalFolder and access them with uri scheme.

Acces Denied when I use Open File Picker for open text file for RichEditBox UWP C#

I want to open a text file with Open File Picker and show in a RichEditBox, but when I select the file and push Ok, Visual Studio show "Access Denied", I want to know how to solve this please, there is my code:
var picker = new FileOpenPicker();
picker.ViewMode = PickerViewMode.Thumbnail;
picker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary;
picker.FileTypeFilter.Add("*");
picker.FileTypeFilter.Add(".txt");
picker.FileTypeFilter.Add(".text");
picker.FileTypeFilter.Add(".bat");
picker.FileTypeFilter.Add(".js");
picker.FileTypeFilter.Add(".vbs");
StorageFile file = await picker.PickSingleFileAsync();
if (file != null)
{
StorageFolder storageFolder = ApplicationData.Current.LocalFolder;
StorageFile filepath = await StorageFile.GetFileFromPathAsync(file.Path);
string text = await FileIO.ReadTextAsync(filepath);
RichEditBox1.Document.SetText(Windows.UI.Text.TextSetOptions.None, text);
}
You don't need to call StorageFile.GetFileFromPathAsync(file.Path) since you already have this StorageFile in the file variable returned from PickSingleFileAsync:
StorageFile file = await picker.PickSingleFileAsync();
if (file != null)
{
string text = await FileIO.ReadTextAsync(file);
RichEditBox1.Document.SetText(Windows.UI.Text.TextSetOptions.None, text);
}
The unnecessary GetFileFromPathAsync probably throws an AccessDenied error since the FileOpenPicker provides access only through the returned StorageFile and doesn't give direct access to the file through its path. This behavior is version dependent and new versions of Windows 10 will allow more direct access through file system API (see the Build 2017 talk UWP Apps file access improvements

WinRT binding an Image to a string or StorageFile

I am trying to display an image from a StorageFile after selecting it from a FilePicker. Since the Source of an Image has to be either a URI or an ImageSource, I am trying to get either of those from the StorageFile.
I am having a hard time getting data binding to work on an Image in XAML. I have tried the following:
<Image Width="300"
Height="300"
x:Name="LogoImage">
<Image.Source>
<BitmapImage UriSource="{Binding ImagePath}" />
</Image.Source>
</Image>
This way doesn't work, as the Path property of a StorageFile is not a URI. Also, I can't bind directly to the StorageFile itself, as it is not an ImageSource.
I tried to use this method:
public async Task<Image> GetImageAsync(StorageFile storageFile)
{
BitmapImage bitmapImage = new BitmapImage();
FileRandomAccessStream stream = (FileRandomAccessStream)await storageFile.OpenAsync(FileAccessMode.Read);
bitmapImage.SetSource(stream);
Image image = new Image();
image.Source = bitmapImage;
return image;
}
But, it returns a Task<Image>, which is also not an ImageSource or URI. It seems like it should be something more straightforward than what I am trying to do, but I am just not seeing it. Also, I have tried just specifying a file in the XAML for the Image.Source and it works fine. I just haven't been able to link it up based on the selected file from the FilePicker.
My ultimate goal is: select a file from FilePicker, update the ImageSource of the displayed Image, encode to base64 for storage in database. Then later, load existing base64 string from database, convert back to Image to be displayed.
Edit:
I was able to accomplish this task using the solution I posted below. Thanks in great part to Jerry Nixon's blog post: http://blog.jerrynixon.com/2014/11/reading-and-writing-base64-in-windows.html
The best solution would be to set the source in code behind instead of using a binding as it would let you handle things like cancellation in case the ImagePath gets updated while the previous image is still loading.
Alternatively, you could create a bitmap, start a task of loading it and return before that task is complete, e.g.
public Image GetImage(StorageFile storageFile)
{
var bitmapImage = new BitmapImage();
GetImageAsync(bitmapImage, storageFile);
// Create an image or return a bitmap that's started loading
var image = new Image();
image.Source = bitmapImage;
return image ;
}
private async Task GetImageAsync(BitmapImage bitmapImage, StorageFile storageFile)
{
using (var stream = (FileRandomAccessStream)await storageFile.OpenAsync(FileAccessMode.Read))
{
await bitmapImage.SetSource(stream);
}
}
If anyone else comes across this question looking for an answer, what I ultimately ended up doing for my situation, is take the StorageFile that is selected from the FilePicker, encode that as a base64 string (which I will save to my database for later retrieval).
Once I have the base64 string, I can decode that string into an ImageSource to set in code-behind. Here is my full ButtonClick event handler:
private async void ChooseImage_Click(object sender, RoutedEventArgs e)
{
var filePicker = new FileOpenPicker();
filePicker.FileTypeFilter.Add(".jpg");
filePicker.ViewMode = PickerViewMode.Thumbnail;
filePicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
filePicker.SettingsIdentifier = "picker1";
filePicker.CommitButtonText = "Open File to Process";
var files = await filePicker.PickMultipleFilesAsync();
if (files.Count > 0)
{
// encode the storage file to base64
var base64 = await Encoding.ToBase64(files[0]);
// asynchronously save base64 string to database
// ...
// decode the base64 and set the image source
LogoImage.Source = await Encoding.FromBase64(base64);
}
}
The base64 encoding/decoding I found at the great Jerry Nixon's blog here: http://blog.jerrynixon.com/2014/11/reading-and-writing-base64-in-windows.html

how to copy image from filepiker to app folder windows store apps

this is the code of file picker
i need to copy the image that user open it to app folder.
any one can help me please
private async void Button_Click(object sender, RoutedEventArgs e)
{
if (Windows.UI.ViewManagement.ApplicationView.Value != Windows.UI.ViewManagement.ApplicationViewState.Snapped ||
Windows.UI.ViewManagement.ApplicationView.TryUnsnap() == true)
{
Windows.Storage.Pickers.FileOpenPicker openPicker = new Windows.Storage.Pickers.FileOpenPicker();
openPicker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.PicturesLibrary;
openPicker.ViewMode = Windows.Storage.Pickers.PickerViewMode.Thumbnail;
// Filter to include a sample subset of file types.
openPicker.FileTypeFilter.Clear();
openPicker.FileTypeFilter.Add(".bmp");
openPicker.FileTypeFilter.Add(".png");
openPicker.FileTypeFilter.Add(".jpeg");
openPicker.FileTypeFilter.Add(".jpg");
// Open the file picker.
Windows.Storage.StorageFile file = await openPicker.PickSingleFileAsync();
// file is null if user cancels the file picker.
if (file != null)
{
// Open a stream for the selected file.
Windows.Storage.Streams.IRandomAccessStream fileStream =
await file.OpenAsync(Windows.Storage.FileAccessMode.Read);
// Set the image source to the selected bitmap.`
Windows.UI.Xaml.Media.Imaging.BitmapImage bitmapImage =
new Windows.UI.Xaml.Media.Imaging.BitmapImage();
bitmapImage.SetSource(fileStream);
img.Source = bitmapImage;
this.DataContext = file;
}
}
}
thanks
Use StorageFile.CopyAsync, that is, file.CopyAsync. The first argument is the destination StorageFolder, e.g. Windows.Storage.ApplicationData.Current.LocalFolder if you wanted to copy to appdata; otherwise you'd need to create a folder or get one from a picker separately.
You might, for example, have the user choose a default folder with the file picker (configured for folders). Just be sure to save that StorageFolder in the [Windows.Storage.AccessCache][2] to preserve programmatic access for future use.

Taking a Picture, and saving it to Disk in a Windows 8 Metro-style App

I am ABLE to take a picture, but I am having trouble saving it to one of the KnownFolders.
Yes, I have declared the Picture Library Access Capability in Package.appxmanifest.
var ui = new CameraCaptureUI();
ui.PhotoSettings.CroppedAspectRatio = new Size(4, 3);
StorageFile file = await ui.CaptureFileAsync(CameraCaptureUIMode.Photo);
if (file != null)
{
var stream = await file.OpenAsync(FileAccessMode.Read);
var bitmap = new BitmapImage();
bitmap.SetSource(stream);
Photo.Source = bitmap;
StorageFolder storageFolder = KnownFolders.PicturesLibrary;
var result = await file.CopyAsync(storageFolder, "tps.jpg");
}
The code stops on the last line. What am I doing wrong?
I think you also need declare the file types!
In the Declarations tab, choose File Type Associations from Available
Declarations and click Add.
Under Properties, set the Name property to image.
In the Supported File Types box, add .jpg as a supported file type by
entering .jpg in the FileType field.

Categories