I got an image by using FileOpenPicker. I want to save the path of the image in database, so that by using that path I can get that image any other screen,,
Now I simply send my image path to second page. but with the same Path I'm not able to get image.
Here is my code.
private async void button_Click(object sender, RoutedEventArgs e)
{
ImagePath = string.Empty;
FileOpenPicker filePicker = new FileOpenPicker();
filePicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
filePicker.ViewMode = PickerViewMode.Thumbnail;
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 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);
**//ImagePath is global string. I get the image path here**
ImagePath = storageFile.Path;
var bitmapImage = new Windows.UI.Xaml.Media.Imaging.BitmapImage();
await bitmapImage.SetSourceAsync(stream);
var decoder = await Windows.Graphics.Imaging.BitmapDecoder.CreateAsync(stream);
//image is my image control in Xaml.
image.Source = bitmapImage;
}
}
private void image_click(object sender, TappedRoutedEventArgs e)
{
this.Frame.Navigate(typeof(detail), ImagePath);
}
By tapping on Image I move to detail screen. where I have another image control where I wan to show the same image ,,,,getting through path.
My Detail screen code is:
protected async override void OnNavigatedTo(NavigationEventArgs e)
{
var imagePath = e.Parameter as string;
image2.Source = new BitmapImage(new Uri(imagePath, UriKind.RelativeOrAbsolute));
}
The above code didn't work.
Then I tried another way,,
var file = await Windows.Storage.StorageFile.GetFileFromApplicationUriAsync(new Uri(imagePath));
Stream stream = await file.OpenStreamForReadAsync();
using (var memStream = new MemoryStream())
{
await stream.CopyToAsync(memStream);
memStream.Position = 0;
BitmapDecoder decoder = await BitmapDecoder.CreateAsync(memStream.AsRandomAccessStream());
// create a new stream and encoder for the new image
InMemoryRandomAccessStream mrAccessStream = new InMemoryRandomAccessStream();
BitmapEncoder encoder = await BitmapEncoder.CreateForTranscodingAsync(mrAccessStream, decoder);
// convert the bitmap to a 400px by 600px bitmap
encoder.BitmapTransform.ScaledHeight = 400;
encoder.BitmapTransform.ScaledWidth = 600;
try
{
await encoder.FlushAsync();
}
catch (Exception ex)
{
string s = ex.ToString();
}
// render the stream to the screen
WB = new WriteableBitmap(500, 500);
WB.SetSource(mrAccessStream);
image2.Source = WB;
This also didn't work.
I think the problem is in path. I got path awkward path like
"C:\\Data\\Users\\Public\\Pictures\\Saved Pictures\\Image-130872081698409356.jpeg".
Please help me to get rid of this problem.
This is by design and it is a security issue. Imagine what would happen if just knowing the path to a file you could access that file. The security model of store apps would be broken.
Note that is the file picker that provides you with a file that you have access to. You can start from a file picker to get access to a file. You cannot start from a path to get access to a file. A file picker guarantees that the user will be involved and hence aware of what is going on. If you were allowed to start from a path and programmatically access a file that would violate the security rules for app stores.
Related
I am trying to import a video into a UWP canvas.
I have this code that successfully imports a picture:
private async void AddImageButton_Click(object sender, RoutedEventArgs e)
{
Image MyImage = new Image();
var picker = new FileOpenPicker();
picker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
picker.FileTypeFilter.Add(".jpg");
picker.FileTypeFilter.Add(".png");
StorageFile file = await picker.PickSingleFileAsync();
if (file != null)
{
StorageApplicationPermissions.FutureAccessList.AddOrReplace("PickedFolderToken", file);
// var files = await file.GetFilesAsync();
var bitmap = new BitmapImage();
var stream = await file.OpenReadAsync();
// AddHandler(, new ExceptionRoutedEventHandler(Bitmap_ImageFailed), true);
bitmap.ImageFailed += Bitmap_ImageFailed;
await bitmap.SetSourceAsync(stream);
MyImage.Source = bitmap;
AddHandler(ManipulationStartedEvent, new ManipulationStartedEventHandler(Image_ManipulationStarted), true);
AddHandler(ManipulationDeltaEvent, new ManipulationDeltaEventHandler(Image_ManipulationDelta), true);
AddHandler(ManipulationCompletedEvent, new ManipulationCompletedEventHandler(Image_ManipulationCompleted), true);
ManipulationMode = ManipulationModes.All;
MyImage.RenderTransform = ImageTransforms;
parentCanvas.Children.Add(MyImage);
}
}
I tried adapting this to import a video but got stuck when converting the bitmap to a MediaPlayerElement. Any suggestions?
Thanks!
According your above code of adding image to the Canvas, you can try the following code to add the MediaPlayerElement to the Canvas and use the FileOpenPicker to picker a media file as the MediaPlayerElement's source. You can make some modification to meet your requirement.
private async void AddMediaPlayerElementButton_Click_1(object sender, RoutedEventArgs e)
{
var picker = new FileOpenPicker();
picker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
picker.FileTypeFilter.Add(".mp4");
StorageFile file = await picker.PickSingleFileAsync();
MediaPlayerElement mediaPlayer = new MediaPlayerElement() { AreTransportControlsEnabled = true };
if (file != null)
{
mediaPlayer.Source = MediaSource.CreateFromStorageFile(file);
}
parentCanvas.Children.Add(mediaPlayer);
}
trying to capture screenshot on uwp But some issue is arising,saying
1) writable map doesn't contain a definition for Render.
2) writable map doesn't contain a definition for Save.jpeg
3)Type or namespace media library doesn't found.
any type of help would be appreciated.
Code
private void Download(object sender, TappedRoutedEventArgs e)
{
// Create a WriteableBitmap with height and width same as that of Layoutroot
WriteableBitmap bmp = new WriteableBitmap(480, 696);
//Render the layoutroot element on it
bmp.Render(Scrshot, null);
bmp.Invalidate();
//Save the image to Medialibrary
//create a stream of image
var ms = new MemoryStream();
bmp.SaveJpeg(ms, 480, 696, 0, 100);
ms.Seek(0, SeekOrigin.Begin);
//every path must be unique
var filePath = "myfile" + DateTime.Now.ToString();
//Remember to include Medialib capabilty from WMAppManifest.xml for acessing the Medialibrary
var lib = new MediaLibrary();
lib.SavePicture(filePath, ms);
MessageBox.Show("Saved in your media library!", "Done", MessageBoxButton.OK);
}
Instead of WriteableBitmap use RenderTargetBitmap to create a bitmap representation of a visible UIElement. To save this bitmap as a file you can use this extension method I've created (here's a great example for extension methods):
public static class RenderTargetBitmapExtensions {
public static async Task<StorageFile> ToFile(this RenderTargetBitmap renderTargetBitmap, string filename, StorageFolder folder = null, bool overrideExisting = true) {
if (folder == null) folder = ApplicationData.Current.TemporaryFolder;
try {
byte[] pixels = (await renderTargetBitmap.GetPixelsAsync()).ToArray();
StorageFile outputFile = await folder.CreateFileAsync(filename, overrideExisting ? CreationCollisionOption.ReplaceExisting : CreationCollisionOption.GenerateUnique);
var bitmapEncodingMode = BitmapEncoder.PngEncoderId;
using (var writeStream = await outputFile.OpenAsync(FileAccessMode.ReadWrite)) {
var encoder = await BitmapEncoder.CreateAsync(bitmapEncodingMode, writeStream);
encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Straight, (uint)renderTargetBitmap.PixelWidth, (uint)renderTargetBitmap.PixelHeight, 96, 96, pixels);
await encoder.FlushAsync();
}
return outputFile;
} catch {
return null;
}
}
}
And finally to get the public Images folder (as MediaLibrary is a Silverlight class and does not exist in UWP anymore) you can do the following according to this thread:
StorageFolder picturesLibrary = KnownFolders.PicturesLibrary;
StorageFolder savedPicturesFolder = await picturesLibrary.CreateFolderAsync("Saved Pictures", CreationCollisionOption.OpenIfExists);
Note: By default, apps do not have access to the Pictures Library. You must add the capability in Package.appxmanifest. Open Package.appxmanifest and click on the Capabilities tab. There is a checkbox for the Pictures Library.
So a whole code to do this should be:
RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap();
await renderTargetBitmap.RenderAsync(LayoutRoot, Convert.ToInt32(LayoutRoot.ActualWidth), Convert.ToInt32(LayoutRoot.ActualHeight));
StorageFolder savedPicturesFolder = await KnownFolders.PicturesLibrary.CreateFolderAsync("Saved Pictures", CreationCollisionOption.OpenIfExists);
await renderTargetBitmap.ToFile("filename.jpg", savedPicturesFolder);
Or if you don't want to override existing files, the last line would be:
await renderTargetBitmap.ToFile("filename.jpg", savedPicturesFolder, false);
For that you can alternatively create a time-based filename:
string filename = String.Format("downloaded_{0}.jpg", DateTime.Now.ToString("yyyyMMdd_HHmmss"));
await renderTargetBitmap.ToFile(filename, savedPicturesFolder, false);
I have captured picture using
cameracaptureui and I have the image in image control.
Now the problem is how to save this captured image to my database.?
normally i did this task in windows form via converting image to byets. but now bit confused in UWP.
thanks in advance
What I have tried:`
private async void button_Copy_Click(object sender, RoutedEventArgs e)
{
//create camera instance with camera capture ui
CameraCaptureUI captureUI = new CameraCaptureUI();
captureUI.PhotoSettings.Format = CameraCaptureUIPhotoFormat.Jpeg;
captureUI.PhotoSettings.CroppedSizeInPixels = new Size(200, 200);
StorageFile photo = await captureUI.CaptureFileAsync(CameraCaptureUIMode.Photo);
if (photo == null)
{
// User cancelled photo capture
return;
}
//return the captured results to fram via bitmap
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;
}
Convert Image to Base64 and save it to mysql database. Save Captured Image to Application Local Folder and Convert it to Base64.
C# code:
using System.Threading.Tasks;
using Windows.Storage;
using Windows.Storage.Streams;
private async void btn_Click(object sender, RoutedEventArgs e)
{
var file = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appdata:///local/" + "your_image_name.png"));
string base64image = await _encodeToBase64(file.Path);
}
public async Task<string> _encodeToBase64(string filePath)
{
string encode = String.Empty;
if (!string.IsNullOrEmpty(filePath))
{
StorageFile file = await StorageFile.GetFileFromPathAsync(filePath);
IBuffer buffer = await FileIO.ReadBufferAsync(file);
DataReader reader = DataReader.FromBuffer(buffer);
byte[] fileContent = new byte[reader.UnconsumedBufferLength];
reader.ReadBytes(fileContent);
encode = Convert.ToBase64String(fileContent);
}
return encode;
}
I am loading a BitmapImage from IsolatedStorage and would like to set the value to the background of MainPage. I am not sure how to properly do this?
TombstoningHelper.cs
public async Task StorePhoto(Stream photoStream, string fileName)
{
// persist data into isolated storage
StorageFile file = await ApplicationData.Current.LocalFolder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);
using (Stream current = await file.OpenStreamForWriteAsync())
{
await photoStream.CopyToAsync(current);
}
}
public async Task<BitmapImage> RetrievePhoto(string fileName)
{
StorageFile file = await ApplicationData.Current.LocalFolder.GetFileAsync(fileName);
Stream imageStream = await file.OpenStreamForReadAsync();
//Check if file exists
// display the file as image
BitmapImage bi = new BitmapImage();
bi.SetSource(imageStream);
return bi;
}
MainPage.xaml.cs
protected async override void OnNavigatedTo(NavigationEventArgs e)
{
//Set Page Theming
ImageBrush ib = new ImageBrush();
TombstoningHelper tsh = new TombstoningHelper();
if (Settings.TransparentBackground.Value == null)
ib.ImageSource = new BitmapImage(new Uri("/Assets/Graphics/" + Settings.Background.Value, UriKind.Relative)); //No Error
else
ib.ImageSource = tsh.RetrievePhoto(Constants.BackgroundImageName); //Error occurs here
LayoutRoot.Background = ib;
I am getting an error above stating Cannot implicitly convert type 'System.Threading.Tasks.Task<System.Windows.Media.Imaging.BitmapImage>' to 'System.Windows.Media.ImageSource.
You need to use the await keyword since your Helper's methods are asynchronous.
else
ib.ImageSource = await tsh.RetrievePhoto(Constants.BackgroundImageName);
You should use await statement, like this:
ib.ImageSource = await tsh.RetrievePhoto(Constants.BackgroundImageName);
I'm using this code, so user can sets custom background image for the application:
private void Button_Click(object sender, RoutedEventArgs e)
{
PhotoChooserTask photoChooserTask = new PhotoChooserTask();
photoChooserTask.Completed += new EventHandler<PhotoResult>(photoChooserTask_Completed);
photoChooserTask.Show();
}
void photoChooserTask_Completed(object sender, PhotoResult e)
{
if (e.TaskResult == TaskResult.OK)
{
System.Windows.Media.Imaging.BitmapImage bmp = new System.Windows.Media.Imaging.BitmapImage();
bmp.SetSource(e.ChosenPhoto);
var imageBrush = new ImageBrush
{
ImageSource = bmp,
Opacity = 0.5d
};
App.RootFrame.Background = imageBrush;
}
}
but this won't save background image for next application lunch.
now how can I save chosen photo to isolated storage to remains as app background even after restarting the application?
Save image asynchronously, applies to WP8 only.
public static async Task SaveImageAsync(string imageFileName, BitmapImage image)
{
// Get Students LocalFolder
IStorageFolder folder = await ApplicationData.Current.LocalFolder
.CreateFolderAsync("Images", CreationCollisionOption.OpenIfExists);
IStorageFile file = await folder.CreateFileAsync(
imageFileName, CreationCollisionOption.ReplaceExisting);
using (Stream stream = await file.OpenStreamForWriteAsync())
{
var wrBitmap = new WriteableBitmap(image);
wrBitmap.SaveJpeg(stream, image.PixelWidth, image.PixelHeight, 100, 100);
}
}
Read image synchronously both WP7.x WP8:
public static BitmapImage LoadImage(string imageFileName)
{
BitmapImage bitmapImage = null;
using (var isoFile = IsolatedStorageFile.GetUserStoreForApplication())
{
using (var isoStream = isoFile.OpenFile(
imageFileName, FileMode.Open, FileAccess.Read))
{
bitmapImage = new BitmapImage();
bitmapImage.SetSource(isoStream);
}
}
return bitmapImage;
}
You can find a bunch of resources online, just google it.
http://msdn.microsoft.com/en-us/library/xf96a1wz(v=vs.110).aspx
When Choosing
IsolatedStorageSettings.ApplicationSettings["backgroundImage"]=e.OriginalFileName;
On app loading
image.Source = new BitmapImage(new Uri(IsolatedStorageSettings.ApplicationSettings["backgroundImage"], UriKind.Absolute));
You can use the free EZ_Iso.dll to do this.
Just send your Bitmap off to the serializer with a name and let it handle the rest
//Saving
EZ_Iso.IsolatedStorageAccess.SaveImage(“MyImage”, YourImage);
//Retrieving
ImageControl.Source = EZ_Iso.IsolatedStroageAccess.GetImage(“MyImage”,Width,Height);
EZ_Iso.dll Download and Documentation