I'm new to C# and I want to create an application metro who can take picture and save themself in localstorage. I know, i need to use isolated storage but i really don't understand how to use it for image. I saw a lot of examples for string but not for picture.
If anyone know how to do it ? Actually i take a picture and i ask the user to record it where he wants. But I want an auto record after the user take the picture. This my code for the moment :
private async void Camera_Clicked(object sender, TappedRoutedEventArgs e)
{
CameraCaptureUI camera = new CameraCaptureUI();
camera.PhotoSettings.CroppedAspectRatio = new Size(16, 9);
StorageFile photo = await camera.
CaptureFileAsync(CameraCaptureUIMode.Photo);
if (photo != null)
{
BitmapImage bmp = new BitmapImage();
IRandomAccessStream stream = await photo.
OpenAsync(FileAccessMode.Read);
bmp.SetSource(stream);
ImageSource.Source = bmp;
ImageSource.Visibility = Visibility.Visible;
appSettings[photoKey] = photo.Path;
FileSavePicker savePicker = new FileSavePicker();
savePicker.FileTypeChoices.Add
("jpeg image", new List<string>() { ".jpeg" });
savePicker.SuggestedFileName = "New picture";
StorageFile ff = await savePicker.PickSaveFileAsync();
if (ff != null)
{
await photo.MoveAndReplaceAsync(ff);
}
}
}
All what you need to do is to replace File Picker logic with retrieving of StorageFile object in Local folder, for example like this:
private async void Camera_Clicked(object sender, TappedRoutedEventArgs e)
{
CameraCaptureUI camera = new CameraCaptureUI();
camera.PhotoSettings.CroppedAspectRatio = new Size(16, 9);
StorageFile photo = await camera.
CaptureFileAsync(CameraCaptureUIMode.Photo);
if (photo != null)
{
var targetFile = await ApplicationData.Current.LocalFolder.CreateFileAsync("some_file_name.jpg");
if (targetFile != null)
{
await photo.MoveAndReplaceAsync(targetFile);
}
}
}
Related
I'm trying to store a model informations in my Data Base, this informations contain an image, so I created a simple view with some entrys, with a media picker button to pick it and an image witch display the picked one.
This is the button method and the store method:
async void Button_Clicked(System.Object sender, System.EventArgs e)
{
var result = await MediaPicker.PickPhotoAsync(new MediaPickerOptions
{
Title = "Please pick a photo"
});
if (result != null)
{
var stream = await result.OpenReadAsync();
resultImage.Source = ImageSource.FromStream(() => stream);
}
}
public async Task SaveMachine()
{
var machine = new Machine
{
Machine_Name = nom.Text,
Machine_Qr = qr.Text,
Files = resultImage
};
await _rest.AddMachine(machine);
await Shell.Current.GoToAsync("..");
}
But I can't create Files = resultImage because the Files in the model is in IFormFile.
I use InkCanvas to implement signature function.
after signed, I can use RenderTargetBitmap class to save the signature-drawing into bitmap.
but RenderTargetBitmap always save InkCanvas itself, means can not save ONLY the signature content.
my question is, how to save StrokeCollection into bitmap?
I think you should use Win2D (Win2D.uwp NuGet package); it is pretty easy.
Here is the code:
async void SaveAsBitmap(object sender, RoutedEventArgs e)
{
//copy from origianl canvas and paste on the new canvas for saving
var strokes = inkCanvas.InkPresenter.StrokeContainer.GetStrokes();
//check if canvas is not empty
if (strokes.Count == 0) return;
//select all the strokes to be copied to the clipboard
foreach (var stroke in strokes)
{
stroke.Selected = true;
}
inkCanvas.InkPresenter.StrokeContainer.CopySelectedToClipboard();
//paste the strokes to a new InkCanvas and move the strokes to the topper left corner
var newCanvas = new InkCanvas();
newCanvas.InkPresenter.StrokeContainer.PasteFromClipboard(new Point(0, 0));
//using Win2D to save ink as png
CanvasDevice device = CanvasDevice.GetSharedDevice();
CanvasRenderTarget renderTarget = new CanvasRenderTarget(device,
(int)inkCanvas.InkPresenter.StrokeContainer.BoundingRect.Width,
(int)inkCanvas.InkPresenter.StrokeContainer.BoundingRect.Height,
96);
using (var ds = renderTarget.CreateDrawingSession())
{
//ds.Clear(Colors.White); //uncomment this line for a white background
ds.DrawInk(newCanvas.InkPresenter.StrokeContainer.GetStrokes());
}
//save file dialog
var savePicker = new Windows.Storage.Pickers.FileSavePicker()
{
SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.DocumentsLibrary
};
savePicker.FileTypeChoices.Add("Image file", new List<string>() { ".jpeg", ".png" });
savePicker.SuggestedFileName = "mysign.png";
var file = await savePicker.PickSaveFileAsync();
if (file != null)
{
using (var fileStream = await file.OpenAsync(FileAccessMode.ReadWrite))
{
await renderTarget.SaveAsync(fileStream, CanvasBitmapFileFormat.Png);
}
}
}
A similar question got asked here, but I also would like to know if there is a way to limit this filePicker to 4 images or would I have to implement this by my own?
Thank You
It's not pretty but it works for now.
I've declared two global variables of the type ObservableCollection called myimageList and alt-myImageList. I've just check the size of these collections and proceed from this point on.
That's the code:
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;
foreach (var item in args.Files)
{
// instead of item args.Files[0];
StorageFile storageFile = item;
var stream = await storageFile.OpenAsync(FileAccessMode.Read);
var bitmapImage = new BitmapImage();
await bitmapImage.SetSourceAsync(stream);
var wbImage = new WriteableBitmap(bitmapImage.PixelWidth, bitmapImage.PixelHeight);
wbImage.SetSource(stream);
//var decoder = await Windows.Graphics.Imaging.BitmapDecoder.CreateAsync(stream);
//bitmapImage.UriSource = new Uri(item.Path, UriKind.Absolute);
if (myImageList.Count < 4)
{
myImageList.Add(bitmapImage);
alt_myImageList.Add(item);
ErrorMessage.Text = "";
}
else
{
ErrorMessage.Text = "Please pick not more than 4 pictures";
}
}
}
private void Gallery_Click(object sender, object e)
{
view = CoreApplication.GetCurrentView();
var filePicker = new FileOpenPicker
{
SuggestedStartLocation = PickerLocationId.PicturesLibrary,
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");
mediaCapture.StopPreviewAsync();
filePicker.PickSingleFileAndContinue();
view.Activated += ViewActivated;
}
private async void ViewActivated(CoreApplicationView sender, IActivatedEventArgs args)
{
var arguments = args as FileOpenPickerContinuationEventArgs;
if (arguments != null && arguments.Files.Count != 0)
{
view.Activated -= ViewActivated;
var storageFile = arguments.Files[0];
var file =
await
ApplicationData.Current.LocalFolder.CreateFileAsync("Photo.jpg",
CreationCollisionOption.GenerateUniqueName);
await storageFile.CopyAndReplaceAsync(file);
var bmpImage = new BitmapImage(new Uri(file.Path));
UseThePhoto(bmpImage);
}
else
await mediaCapture.StartPreviewAsync();
}
I have this code above. When I choose an image from a gallery I can use it in an Image control that is on the same page. However, if I want to navigate to any other page, I get an error. No details from it. The code ends in App.g.i.cs
Problem solved. I was using not the blank page template but the basic page. And for some reason the method OnNavigatedFrom invoked this error so i created an override and let it empty, so it couldn't call the navigation helper class.
I have a Image control
<Image Name="img" HorizontalAlignment="Left" Height="400" Margin="499,155,0,0" VerticalAlignment="Top" Width="400"/>
And I capture photo from Camera
private async void TakePhoto_Click(object sender, RoutedEventArgs e)
{
CameraCaptureUI camera = new CameraCaptureUI();
camera.PhotoSettings.CroppedAspectRatio = new Size(4, 3);
var photo = await camera.CaptureFileAsync(CameraCaptureUIMode.Photo);
if (photo != null)
{
BitmapImage image = new BitmapImage();
image.SetSource(await photo.OpenAsync(FileAccessMode.Read));
img.Source = image;
}
}
And now I want to save this image from img control to folder, but I don't know how decode image from img control to StorageFile
private async void SaveFile_Click(object sender, RoutedEventArgs e)
{
FileSavePicker savePicker = new FileSavePicker();
savePicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
savePicker.FileTypeChoices.Add("jpeg image", new List<string>() { ".jpeg" });
savePicker.SuggestedFileName = "New picture";
StorageFile ff = await savePicker.PickSaveFileAsync();
if (ff != null)
{
await photo.MoveAndReplaceAsync(ff);
}
}
this is a save method, which i want to save image from Image control
The
var photo = await camera.CaptureFileAsync(CameraCaptureUIMode.Photo); returns a StorageFile. All you have to do is save it to the location you want.
You can accomplish this in may ways.
Example:
StorageFolder localFolder = ApplicationData.Current.LocalFolder; // the app's local storage folder
await photo.MoveAsync(localFolder); //move the file to a new location
2.
//Create a new copy in a new location
await photo.CopyAsync(localFolder);
Note that var photo == StorageFile photo. This means that the after the photo was captured, a copy of it was already saved to a temporary location(The App's TempState directory) on the local storage.