File Save Picker - Save Edited Image (C# Metro app) - c#

I want to open an image, edit it, and then save it. I am able to open a file, but I have problems saving it. The way I have written the code, I can only save a file with .jpg but there is nothing in it.
Please explain to me how to save the image I have opened and edited(not made yet).
public sealed partial class MainPage : Page
{
BitmapImage originalImage = new BitmapImage();
public MainPage()
{
this.InitializeComponent();
}
private async void OpenButton_Click(object sender, RoutedEventArgs e)
{
var filePicker = new FileOpenPicker();
filePicker.FileTypeFilter.Add(".jpg");
filePicker.FileTypeFilter.Add(".jpeg");
filePicker.FileTypeFilter.Add(".gif");
filePicker.ViewMode = PickerViewMode.Thumbnail;
filePicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
filePicker.SettingsIdentifier = "PicturePicker";
filePicker.CommitButtonText = "Select File";
StorageFile selectedFile = await filePicker.PickSingleFileAsync();
var stream = await selectedFile.OpenAsync(FileAccessMode.Read);
if (selectedFile != null)
{
originalImage.SetSource(stream);
pictureBox.Source = originalImage;
}
}
private async void SaveButton_Click(object sender, RoutedEventArgs e)
{
FileSavePicker savePicker = new FileSavePicker();
savePicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
savePicker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary;
savePicker.FileTypeChoices.Add("jpeg image", new List<string>() { ".jpg" });
savePicker.SuggestedFileName = "EditedImage";
StorageFile file = await savePicker.PickSaveFileAsync();
}
}

After creating an Images file you need to Update it see FileSavePicker class.
Add the following code in your SaveButton_Click method and try modify it.
This will let you update your created file into real image file.
if (file != null)
{
// Prevent updates to the remote version of the file until we finish making changes and call CompleteUpdatesAsync.
CachedFileManager.DeferUpdates(file);
// write to file
await FileIO.WriteTextAsync(file, file.Name);
// Let Windows know that we're finished changing the file so the other app can update the remote version of the file.
// Completing updates may require Windows to ask for user input.
FileUpdateStatus status = await CachedFileManager.CompleteUpdatesAsync(file);
if (status == FileUpdateStatus.Complete)
{
OutputTextBlock.Text = "File " + file.Name + " was saved.";
}
else
{
OutputTextBlock.Text = "File " + file.Name + " couldn't be saved.";
}
}
else
{
OutputTextBlock.Text = "Operation cancelled.";
}

Related

How can I open the savefile-dialog out of webview in an UWP

I've taken over an UWP project and have to fix an issue with a download button. On a website, there is a link to a software-package. The EXE can be downloaded using a browser.
In my webview, as far as I understood, I won't be able to download directly to disk, but it should be possible to open the standard-browser to take over that part. I managed to open PDFs in the standard-browser from my webview. That already was tricky for me and my noob skills, but it's working now. I tried the same with EXE-files, but that doesn't seem to work. Here is what I did so far:
private async void WebView1_NewWindowRequested(WebView sender, WebViewNewWindowRequestedEventArgs args)
{
if (args.Uri != null && args.Uri.OriginalString.ToLower().Contains(".pdf"))
{
return;
}
else
{ webView1.Navigate(args.Uri); }
args.Handled = true;
}
So this works for PDF, but when I do the same with EXE, it doesn't do anything (visible).
Any ideas on that?
How can I open the savefile-dialog out of webview in an UWP
You could listen NavigationStarting event handler, if the uri contains .exe you could create BackgroundDownloader to download exe file specific folder.
private async void TestWebView_NavigationStarting(WebView sender, WebViewNavigationStartingEventArgs args)
{
if (args.Uri != null && args.Uri.OriginalString.ToLower().Contains(".exe"))
{
try
{
StorageFile destinationFile = await KnownFolders.PicturesLibrary.CreateFileAsync(
"test.exe", CreationCollisionOption.GenerateUniqueName);
BackgroundDownloader downloader = new BackgroundDownloader();
DownloadOperation download = downloader.CreateDownload(args.Uri, destinationFile);
await download.StartAsync();
}
catch (Exception ex)
{
}
}
}
Mahobo solution
string Link = args.Uri.Segments.Last();
try
{
var messagedialog = new MessageDialog("Saving File " + Link + " to your Download folder.");
await messagedialog.ShowAsync();
StorageFile destinationFile = await DownloadsFolder.CreateFileAsync(Link, CreationCollisionOption.GenerateUniqueName);
BackgroundDownloader downloader = new BackgroundDownloader();
DownloadOperation download = downloader.CreateDownload(args.Uri, destinationFile);
await download.StartAsync();
}
catch (Exception e)
{
}

MediaTranscoder.PrepareFileTranscodeAsync UnauthorizedAccessException

I have a Button on a Page with the following method on the click event of the button:
StorageFile _sourceFile;
private string _sourceToken;
private async void btnSelect_Click(object sender, RoutedEventArgs e)
{
FileOpenPicker fop = new FileOpenPicker();
fop.FileTypeFilter.Add(".mp4");
StorageFile inFile = await fop.PickSingleFileAsync();
_sourceToken = Windows.Storage.AccessCache.StorageApplicationPermissions.FutureAccessList.Add(inFile);
_sourceFile = await Windows.Storage.AccessCache.StorageApplicationPermissions.FutureAccessList.GetFileAsync(_sourceToken);
mediaElement.AutoPlay = false;
IRandomAccessStream stream = await _outFile.OpenAsync(FileAccessMode.ReadWrite);
mediaElement.SetSource(stream, _outFile.ContentType);
}
If I click play on the MediaElement the video I select plays fine.
I also have another button which has the following code on its click event:
private async void btnExport_Click(object sender, RoutedEventArgs e)
{
StorageFile outFile = await KnownFolders.VideosLibrary.CreateFileAsync("Outfie.mp4", CreationCollisionOption.ReplaceExisting);
MediaEncodingProfile profile = MediaEncodingProfile.CreateMp4(VideoEncodingQuality.HD1080p);
MediaTranscoder transcoder = new MediaTranscoder();
PrepareTranscodeResult prepareOp = await transcoder.PrepareFileTranscodeAsync(_sourceFile, outFile, profile);
if (prepareOp.CanTranscode)
{
var transcodeOp = prepareOp.TranscodeAsync();
transcodeOp.Progress += new AsyncActionProgressHandler<double>(TranscodeProgress);
transcodeOp.Completed += new AsyncActionWithProgressCompletedHandler<double>(TranscodeComplete);
}
else
{
switch (prepareOp.FailureReason)
{
case TranscodeFailureReason.CodecNotFound:
System.Diagnostics.Debug.WriteLine("Codec not found.");
break;
case TranscodeFailureReason.InvalidProfile:
System.Diagnostics.Debug.WriteLine("Invalid profile.");
break;
default:
System.Diagnostics.Debug.WriteLine("Unknown failure.");
break;
}
}
}
Unfortunately the line transcoder.PrepareFileTranscodeAsync throws an UnauthorizedAccessException. But if I use the following instead of _sourceFile it works:
StorageFile sourceFile = await KnownFolders.VideosLibrary.GetFileAsync("sourceFile.mp4");
The error being thrown is:
System.UnauthorizedAccessException: 'Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))'
To be clear, I am selecting files OUTSIDE the KnownFolders Enumeration, hence I am using Windows.Storage.AccessCache.StorageApplicationPermissions.FutureAccessList.
Can anyone explain why?
EDIT:
If I change the source file to be the result of a FileOpenPicker then it works. So it begs the question, why is the FutureAccessList not working??
private async void btnExport_Click(object sender, RoutedEventArgs e)
{
StorageFile outFile = await KnownFolders.VideosLibrary.CreateFileAsync("Outfie.mp4", CreationCollisionOption.ReplaceExisting);
FileOpenPicker fop = new FileOpenPicker();
fop.SuggestedStartLocation = PickerLocationId.ComputerFolder;
fop.FileTypeFilter.Add(".mp4");
StorageFile sourceFile = await fop.PickSingleFileAsync();
MediaEncodingProfile profile = MediaEncodingProfile.CreateMp4(VideoEncodingQuality.HD1080p);
MediaTranscoder transcoder = new MediaTranscoder();
PrepareTranscodeResult prepareOp = await transcoder.PrepareFileTranscodeAsync(sourceFile, outFile, profile);
if (prepareOp.CanTranscode)
{
var transcodeOp = prepareOp.TranscodeAsync();
transcodeOp.Progress += new AsyncActionProgressHandler<double>(TranscodeProgress);
transcodeOp.Completed += new AsyncActionWithProgressCompletedHandler<double>(TranscodeComplete);
}
else
{
switch (prepareOp.FailureReason)
{
case TranscodeFailureReason.CodecNotFound:
System.Diagnostics.Debug.WriteLine("Codec not found.");
break;
case TranscodeFailureReason.InvalidProfile:
System.Diagnostics.Debug.WriteLine("Invalid profile.");
break;
default:
System.Diagnostics.Debug.WriteLine("Unknown failure.");
break;
}
}
}
Do you have access to the file you're trying to write to? Maybe it's read-only or created by another user other than yourself? (Right click + Properties on the file in Explorer should give you a clearer picture of the file permissions)
Also, you might get that exception if you're trying to write to a folder whom you don't have access to.
Check your credentials, I would guess it's something related to that.
So it seems the fact I was opening the source file in ReadWrite mode
IRandomAccessStream stream = await _outFile.OpenAsync(FileAccessMode.ReadWrite);
Was the cause of the issues. According to this page
Use read/write mode only when you're ready to write immediately in order to avoid conflicts with other operations.
So I changed to this and all works well
IRandomAccessStream stream = await _outFile.OpenAsync(FileAccessMode.Read);

load image from PC as stream

I am trying to load a picture from my PC as a raw image in order to use it with the Microsoft cognitive services emotion (UWP).
below is a piece of my code:
//Chose Image from PC
private async void chosefile_Click(object sender, RoutedEventArgs e)
{
//Open Dialog
FileOpenPicker open = new FileOpenPicker();
open.ViewMode = PickerViewMode.Thumbnail;
open.SuggestedStartLocation = PickerLocationId.Desktop;
open.FileTypeFilter.Add(".jpg");
open.FileTypeFilter.Add(".jpeg");
open.FileTypeFilter.Add(".gif");
open.FileTypeFilter.Add(".png");
file = await open.PickSingleFileAsync();
if (file != null)
{//imagestream is declared as IRandomAccessStream.
imagestream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read);
var image = new BitmapImage();
image.SetSource(imagestream);
imageView.Source = image;
}
else
{
//
}
}
The part above works fine, it selects a photo from the pc (dialog box) and displays it in Image box.
private async void analyse_Click(object sender, RoutedEventArgs e)
{
try
{
emotionResult = await emotionServiceClient.RecognizeAsync(imagestream.AsStream());
}
catch
{
output.Text = "something is wrong in stream";
}
try {
if(emotionResult!= null)
{
Scores score = emotionResult[0].Scores;
output.Text = "Your emotions are: \n" +
"Happiness: " + score.Happiness + "\n" +
"Sadness: " + score.Sadness;
}
}
catch
{
output.Text = "Something went wrong";
}
}
I think the error is due to imagestream.AsStream()
imagestream is declared as IRandomAccessStream.
Can someone please tell me how to fix that part and if the error is in fact due to not loading the image correctly?
EDIT:
Also is there a better way to do this, instead of using stream to pass the emotionServiceClient a saved file instead of a stream?
Your problem is that you've advanced the stream position by virtue of creating the BitmapImage, so your read position is at the end by the time you call emotionServiceClient.RecognizeAsync. So you'll need to 'rewind':
var stream = imagestream.AsStreamForRead();
stream.Position = 0;
emotionResult = await emotionServiceClient.RecognizeAsync(stream);
Why not use their example, instead of trying to hold the file in memory, why don't you hold a path, and then use the path to read the stream at the time.
https://www.microsoft.com/cognitive-services/en-us/Emotion-api/documentation/GetStarted
In there example;
using (Stream imageFileStream = File.OpenRead(imageFilePath))
{
//
// Detect the emotions in the URL
//
emotionResult = await emotionServiceClient.RecognizeAsync(imageFileStream);
return emotionResult;
}
So you would be capturing imageFilePath as the result of the open file dialog.

XAML c# pick maxiumum 4 images from library with filepicker [duplicate]

I want to pick an image from my pictures album in windows phone 8.1 . For this I used this code but its gives error
private async void gallery_Tapped(object sender, TappedRoutedEventArgs e)
{
FileOpenPicker opener = new FileOpenPicker();
opener.ViewMode = PickerViewMode.Thumbnail;
opener.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
opener.FileTypeFilter.Add(".jpg");
opener.FileTypeFilter.Add(".jpeg");
opener.FileTypeFilter.Add(".png");
StorageFile file = await opener.PickSingleFileAsync();
if (file != null)
{
// We've now got the file. Do something with it.
var stream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read);
var bitmapImage = new Windows.UI.Xaml.Media.Imaging.BitmapImage();
await bitmapImage.SetSourceAsync(stream);
var decoder = await Windows.Graphics.Imaging.BitmapDecoder.CreateAsync(stream);
MyImage.Source=bitmapImage;
}
else
{
//OutputTextBlock.Text = "The operation may have been cancelled.";
}
}
Error
I think you can handle the OnActivated event even in the page where you required. Something like this
CoreApplicationView view = CoreApplication.GetCurrentView();
ImagePath=string.Empty;
FileOpenPicker filePicker = new FileOpenPicker();
filePicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
filePicker.ViewMode = PickerViewMode.Thumbnail;
// Filter to include a sample subset of file types
filePicker.FileTypeFilter.Clear();
filePicker.FileTypeFilter.Add(".bmp");
filePicker.FileTypeFilter.Add(".png");
filePicker.FileTypeFilter.Add(".jpeg");
filePicker.FileTypeFilter.Add(".jpg");
filePicker.PickSingleFileAndContinue();
view.Activated += viewActivated;
private void viewActivated(CoreApplicationView sender, IActivatedEventArgs args1)
{
FileOpenPickerContinuationEventArgs args = args1 as FileOpenPickerContinuationEventArgs;
if (args != null)
{
if (args.Files.Count == 0) return;
view.Activated -= viewActivated;
storageFileWP = args.Files[0];
}
}
When you select the files from the picker the above method will be called. I believe it helps you.
Using FileOpenPicker in Windows Phone 8.1 to choose picture from Picture Gallery.
Step 1: Add Picture Library Capability in your Windows Phone 8.1 app.
Step 2: Add File Open Picker as a declaration.
Step 3: Add a button and image to MainPage.xaml.
<Grid>
<Image Name="img"/>
<Button Content="click me" Click="Button_Click"/>
</Grid>
Step 4: Add global variable view.
CoreApplicationView view;
Step 4.1 Initialize in page constructor.
view = CoreApplication.GetCurrentView();
Step 5: Add the code to call the File Open Picker on Button Click event.
private void Button_Click(object sender, RoutedEventArgs e)
{
FileOpenPicker filePicker = new FileOpenPicker();
filePicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
filePicker.ViewMode = PickerViewMode.Thumbnail;
// Filter to include a sample subset of file types
filePicker.FileTypeFilter.Clear();
filePicker.FileTypeFilter.Add(".bmp");
filePicker.FileTypeFilter.Add(".png");
filePicker.FileTypeFilter.Add(".jpeg");
filePicker.FileTypeFilter.Add(".jpg");
filePicker.PickSingleFileAndContinue();
view.Activated += viewActivated;
}
Step 6: On View activated event set the image to the MainPage.
private async void viewActivated(CoreApplicationView sender, IActivatedEventArgs args1)
{
FileOpenPickerContinuationEventArgs args = args1 as FileOpenPickerContinuationEventArgs;
if (args != null)
{
if (args.Files.Count == 0) return;
view.Activated -= viewActivated;
StorageFile storageFile = args.Files[0];
var stream = await storageFile.OpenAsync(Windows.Storage.FileAccessMode.Read);
var bitmapImage = new Windows.UI.Xaml.Media.Imaging.BitmapImage();
await bitmapImage.SetSourceAsync(stream);
var decoder = await Windows.Graphics.Imaging.BitmapDecoder.CreateAsync(stream);
img.Source=bitmapImage;
}
}
It also allows you to take a photo and use it.
Reference:
Using FileOpenPicker in Windows Phone 8.1 to choose picture from Picture Gallery
Use RoutedEventArgs instead of TappedRoutedEventArgs for button click in wp 8.1 xaml
Don't use async key word
private void OpenImageFile(object sender, RoutedEventArgs e)
{
FileOpenPicker filePicker = new FileOpenPicker();
filePicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
filePicker.ViewMode = PickerViewMode.Thumbnail;
// Filter to include a sample subset of file types
filePicker.FileTypeFilter.Clear();
filePicker.FileTypeFilter.Add(".bmp");
filePicker.FileTypeFilter.Add(".png");
filePicker.FileTypeFilter.Add(".jpeg");
filePicker.FileTypeFilter.Add(".jpg");
filePicker.PickSingleFileAndContinue();
view.Activated += viewActivated;
}
private void viewActivated(CoreApplicationView sender, IActivatedEventArgs args1)
{
FileOpenPickerContinuationEventArgs args = args1 as FileOpenPickerContinuationEventArgs;
if (args != null)
{
if (args.Files.Count == 0) return;
view.Activated -= viewActivated;
StorageFile SelectedImageFile = args.Files[0];
}
}
And use CoreApplicationView view; Any where in the class out side of every method as global
Don't forget to use view = CoreApplication.GetCurrentView(); inside the constructor of the relevant page class after InitializeComponent(); method
I think this will help :) Thanks
var fill = await StorageFile.GetFileFromPathAsync(selectItem.FolderPath);
BitmapImage bit = new BitmapImage();
if (fill != null)
{
// We've now got the file. Do something with it.
var stream = await fill.OpenAsync(Windows.Storage.FileAccessMode.Read);
//var bitmapImage = new Windows.UI.Xaml.Media.Imaging.BitmapImage();
//await bitmapImage.SetSourceAsync(stream);
bit.SetSource(stream);
imgTeste.Source = bit;
pvMestre.SelectedIndex = 1;
}
else
{
//OutputTextBlock.Text = "The operation may have been cancelled.";
}

Exception while accessing 'FileOpenPicker' for the SecondTime in WindowsStoreApps

I want to open FileOpenPicker for two times one after the other.i.e)After selecting the image from FileOpenPicker for first time it returns back to the page with the selected image,that time a MessageDialog is shown,And clicking OK button on MessageDialog I am opening the FileOpenPicker again,this time I get a weird crash on
open.FileTypeFilter.Clear();
as 'Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))'.And My code is below.
private async void PickImage()
{
FileOpenPicker open = new FileOpenPicker();
open.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
open.ViewMode = PickerViewMode.Thumbnail;
// Filter to include a sample subset of file types
open.FileTypeFilter.Clear();
open.FileTypeFilter.Add(".bmp");
open.FileTypeFilter.Add(".png");
open.FileTypeFilter.Add(".jpeg");
open.FileTypeFilter.Add(".jpg");
StorageFile file = await open.PickSingleFileAsync();
if (file != null)
{
if (prop1.Source == null)
{
Dialogpopup();
return;
}
else if (prop2.Source == null)
{
Dialogpopup();
return;
}
}
}
private async void Dialogpopup()
{
MessageDialog msgDialog = new MessageDialog("Would you like to add additional photos?");
UICommand okBtn = new UICommand("Yes");
okBtn.Invoked = OkBtnClick;
msgDialog.Commands.Add(okBtn);
UICommand cancelBtn = new UICommand("No");
cancelBtn.Invoked = CancelBtnClick;
msgDialog.Commands.Add(cancelBtn);
//Show message
msgDialog.ShowAsync();
}
private async void OkBtnClick(IUICommand command)
{
img_PointerPressed(img_galary, null);
}
private void img_PointerPressed(object sender, PointerRoutedEventArgs e)
{
if (sender == img_galary)
{
PickImage();
}
}

Categories

Resources