i need to save the picture getting from the camera in a specific folder but i can't find the way, i онли show it in the xaml.
class CameraOpening{
public async Task<SoftwareBitmapSource> PhotoTake(){
var captureUI = new CameraCaptureUI();
captureUI.PhotoSettings.Format = CameraCaptureUIPhotoFormat.Jpeg;
captureUI.PhotoSettings.AllowCropping = false;
var photo = await captureUI.CaptureFileAsync(CameraCaptureUIMode.Photo);
var bitmapSource = new SoftwareBitmapSource();
if (photo != null){
var folder = await ApplicationData.Current.LocalFolder.CreateFolderAsync(
"ProfilePhotoFolder", CreationCollisionOption.OpenIfExists);
await photo.CopyAsync(folder,"ProfilePhoto.jpg",NameCollisionOption.ReplaceExisting);
using (var stream = await photo.OpenAsync(FileAccessMode.Read)){
var decoder = await BitmapDecoder.CreateAsync(stream);
var softwareBitmap = await decoder.GetSoftwareBitmapAsync();
var softwareBitmapBGR8 = SoftwareBitmap.Convert(
softwareBitmap, BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied);
await bitmapSource.SetBitmapAsync(softwareBitmapBGR8);}
await photo.DeleteAsync();}
return bitmapSource;}}
public async void Buttonfoto(object sender, RoutedEventArgs e)
{
var cam = new CameraOpening();
imageControl.Source = await cam.PhotoTake();
}
and the xaml has the Image and the Button
there is a way for save the picture taken in a specific directory?
or a copy of it.
Lines:
var folder = await ApplicationData.Current.LocalFolder.CreateFolderAsync("ProfilePhotoFolder", CreationCollisionOption.OpenIfExists);
await photo.CopyAsync(folder, "ProfilePhoto.jpg", NameCollisionOption.ReplaceExisting);
already seems to be saving your photo to path ./ProfilePhotoFolder/ProfilePhoto.jpg.
But it will save only if picture was actually taken.
var photo = await captureUI.CaptureFileAsync(CameraCaptureUIMode.Photo);
// < ... >
if (photo != null) { /* save file! */ }
Check what captureUI.CaptureFileAsync actually returns.
If it's null - nothing will happen.
But if your photo is being taken and already saving itself to ./ProfilePhotoFolder/ProfilePhoto.jpg you can save it again via:
await photo.CopyAsync(folder, "C:\\SomeFolder\\MyPhoto.jpg", NameCollisionOption.ReplaceExisting);
Or copy already created picture via:
File.Copy(".\\ProfilePhotoFolder\\ProfilePhoto.jpg", "C:\\SomeFolder\\MyPhoto.jpg");
More info here:
System.IO and System.IO.File
Related
I'm trying to get this mini app to save the photo taken by the camera but I get this error.System.IO.FileNotFoundException: 'The system cannot find the file specified. (Exception from HRESULT: 0x80070002)'
I followed the Microsoft Tutorial but cant get it to work.
private async void btnTakePhoto_Click(object sender, RoutedEventArgs e)
{
CameraCaptureUI captureUI = new CameraCaptureUI();
captureUI.PhotoSettings.Format = CameraCaptureUIPhotoFormat.Jpeg;
captureUI.PhotoSettings.CroppedSizeInPixels = new Size(200, 200);
//StorageFile photo = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/mypic.jpg"));
StorageFile photo = await captureUI.CaptureFileAsync(CameraCaptureUIMode.Photo);
if (photo == null)
{
// User cancelled photo capture
return;
}
StorageFolder destinationFolder =
await ApplicationData.Current.LocalFolder.CreateFolderAsync("ProfilePhotoFolder",
CreationCollisionOption.OpenIfExists);
await photo.CopyAsync(destinationFolder, "ProfilePhoto.jpg", NameCollisionOption.ReplaceExisting);
await photo.DeleteAsync();
IRandomAccessStream stream = await photo.OpenAsync(FileAccessMode.Read);
BitmapDecoder decoder = await BitmapDecoder.CreateAsync(stream);
SoftwareBitmap softwareBitmap = await decoder.GetSoftwareBitmapAsync();
SoftwareBitmap softwareBitmapBGR8 = SoftwareBitmap.Convert(softwareBitmap,
BitmapPixelFormat.Bgra8,
BitmapAlphaMode.Premultiplied);
SoftwareBitmapSource bitmapSource = new SoftwareBitmapSource();
await bitmapSource.SetBitmapAsync(softwareBitmapBGR8);
imageControl.Source = bitmapSource;
}
From the above mentioned code snippet remove the line that I have written below.
await photo.DeleteAsync();
After removing the line it works fine.
Is there a way I can get the image as Stream and then store it locally to upload it to server?
So far I found the code below which lets me load the image to an image view , but how do I create a stream from the image source to pass it to SaveToLocalFolderAsync method?
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);
imgCover.Source = bitmapImage;
//save the image in local folder
//SaveToLocalFolderAsync(stream, "Test.jpg");
}
}
public async Task SaveToLocalFolderAsync(Stream file, string fileName)
{
StorageFolder localFolder = ApplicationData.Current.LocalFolder;
StorageFile storageFile = await localFolder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);
using (Stream outputStream = await storageFile.OpenStreamForWriteAsync())
{
await file.CopyToAsync(outputStream);
}
}
I want to share my canvas as image in my window store app I am using this code
if (DrawCanvas.Children.Count == 0)
{
MessageDialog dlg = new MessageDialog("Please add some content", "Warning");
dlg.ShowAsync();
return;
}
// Render to an image at the current system scale and retrieve pixel contents
RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap();
await renderTargetBitmap.RenderAsync(DrawCanvas);
var pixelBuffer = await renderTargetBitmap.GetPixelsAsync();
var savePicker = new FileSavePicker();
savePicker.DefaultFileExtension = ".png";
savePicker.FileTypeChoices.Add(".png", new List<string> { ".png" });
savePicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
savePicker.SuggestedFileName = "snapshot.png";
// Prompt the user to select a file
var saveFile = await savePicker.PickSaveFileAsync();
// Verify the user selected a file
if (saveFile == null)
return;
// Encode the image to the selected file on disk
using (var fileStream = await saveFile.OpenAsync(FileAccessMode.ReadWrite))
{
var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, fileStream);
encoder.SetPixelData(
BitmapPixelFormat.Bgra8,
BitmapAlphaMode.Ignore,
(uint)renderTargetBitmap.PixelWidth,
(uint)renderTargetBitmap.PixelHeight,
DisplayInformation.GetForCurrentView().LogicalDpi,
DisplayInformation.GetForCurrentView().LogicalDpi,
pixelBuffer.ToArray());
await encoder.FlushAsync();
}
This code is saving my image file onto my disk I want to change this code to share this image from my app not save on my disk ,How can I achieve that ?
Need help.
I see solution for this problem:
Saving as jpeg from memorystream in c#
but it does not work in winRT.
Is there a simple way to save MemoryStream as JPEG using FileSavePicker?
I tried:
private async void Save_Image(MemoryStream image)
{
// Launch file picker
FileSavePicker picker = new FileSavePicker();
picker.FileTypeChoices.Add("JPeg", new List<string>() { ".jpg", ".jpeg" });
StorageFile file = await picker.PickSaveFileAsync();
if (file == null)
return;
Stream x = await file.OpenStreamForWriteAsync();
image.WriteTo(x)
}
but it is saving blank file. May be I am doing something wrong.
Tried one more approach but again blank image:
private async void Save_Image(MemoryStream image)
{
// Launch file picker
FileSavePicker picker = new FileSavePicker();
picker.FileTypeChoices.Add("JPeg", new List<string>() { ".jpg", ".jpeg" });
StorageFile file = await picker.PickSaveFileAsync();
if (file == null)
return;
int end = (int)image.Length;
byte[] buffer = new byte[end];
await image.ReadAsync(buffer, 0, end);
await FileIO.WriteBytesAsync(file, buffer);
}
Got it! It was the seeking position I was missing and also the "using". Had to set it externally to 0.
Here is the code:
private async void Save_Image(MemoryStream image)
{
// Launch file picker
FileSavePicker picker = new FileSavePicker();
picker.FileTypeChoices.Add("JPeg", new List<string>() { ".jpg", ".jpeg" });
StorageFile file = await picker.PickSaveFileAsync();
if (file == null)
return;
using (Stream x = await file.OpenStreamForWriteAsync())
{
x.Seek(0, SeekOrigin.Begin);
image.WriteTo(x);
}
}
I make some application which edit photo and save it in other location. So I find a question which shows how to resize photos in Windows Store Apps. Then I implement it in my program:
private async void ResizeButton_Click(object sender, RoutedEventArgs e)
{
uint width, height;
if (uint.TryParse(WidthTextBox.Text, out width) && uint.TryParse(HeightTextBox.Text, out height)
&& _folderWithPhoto != null && _targetFolder != null)
//_folderWithPhoto and _targetFolder are StorageFolder values get from FolderPicker
{
var files = await _folderWithPhoto.GetFilesAsync();
foreach (StorageFile item in files)
{
if (item.ContentType.Contains("image"))
{
StorageFile targetFile = await item.CopyAsync(_targetFolder, item.Name, NameCollisionOption.GenerateUniqueName);
var fileStream = await targetFile.OpenAsync(Windows.Storage.FileAccessMode.ReadWrite);
BitmapDecoder decoder = await BitmapDecoder.CreateAsync(fileStream);
InMemoryRandomAccessStream ras = new InMemoryRandomAccessStream();
BitmapEncoder enc = await BitmapEncoder.CreateForTranscodingAsync(ras, decoder);
enc.BitmapTransform.ScaledHeight = height;
enc.BitmapTransform.ScaledWidth = width;
await enc.FlushAsync();
}
}
}
}
Problem
Result of this code is the same photo saved in _targetFolder catalogue. So I have no idea how to fix it.
Any help would be appreciated.
Mateusz will something like this inside your foreach loop work I am not sure
ras.Seek(0);
fileStream.Seek(0);
fileStream.Size = 0;
await RandomAccessStream.CopyAsync(ras, fileStream);
fileStream.Dispose();
ras.Dispose();