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
Related
I am making a UWP app where i want to pick a user signature scanned by the user and make the picture transparent.
now first things first:
I am using FileOpenPicker to pick the storage file.
Work tried by me
public async void Button_AddSign_Click(object sender, RoutedEventArgs e)
{
try
{
var _filePicker = new FileOpenPicker();
_filePicker.SuggestedStartLocation = PickerLocationId.Desktop;
_filePicker.ViewMode = PickerViewMode.Thumbnail;
_filePicker.FileTypeFilter.Add(".png");
IStorageFile _file = await _filePicker.PickSingleFileAsync();
StorageFolder storageFolder = await ApplicationData.Current.LocalFolder.GetFolderAsync(CurrentUser);
if (_file != null)
{
StorageFile storageFile = await _file.CopyAsync(storageFolder, "Signature.png");
await MakeSignTransparentAsync(storageFile);
}
}
catch{Exception ex}
}
public static async Task MakeSignTransparentAsync(StorageFile Inputfile)
{
var memStream = new InMemoryRandomAccessStream();
using (IRandomAccessStream fileStream = await Inputfile.OpenAsync(FileAccessMode.ReadWrite))
{
BitmapDecoder decoder = await BitmapDecoder.CreateAsync(fileStream);
BitmapEncoder encoder = await BitmapEncoder.CreateForTranscodingAsync(memStream, decoder);
encoder.BitmapTransform.ScaledWidth = 600;
encoder.BitmapTransform.ScaledHeight = 200;
await encoder.FlushAsync();
memStream.Seek(0);
fileStream.Seek(0);
fileStream.Size = 0;
await RandomAccessStream.CopyAsync(memStream, fileStream);
memStream.Dispose();
}
Bitmap bmp;
using (MemoryStream ms = new MemoryStream(memStream)) //Getting an error at this line
{
bmp = new Bitmap(ms);
}
bmp.MakeTransparent();
bmp.Save(bmpInput.Path + "test.png", ImageFormat.Png);
}
Error:
Argument 1: cannot convert from 'Windows.Storage.Streams.InMemoryRandomAccessStream' to 'byte[]
Any help is appreciated.
If there is another way around other than this that is also appreciated.
Found a solution using a library ImageMagick
using ImageMagick;
public static async Task MakeSignTransparentAsync(StorageFile bmpInput)
{
using (var img = new MagickImage(bmpInput.Path))
{
// -fuzz XX%
img.ColorFuzz = new Percentage(10);
// -transparent white
img.Transparent(MagickColors.White);
img.Write(bmpInput.Path);
}
}
I cant seem to implement a Drag and Drop Function for video files (.mp4), only images. Everytime I try to drag a video, the program crashed. Here is the drop canvas I had:
private async void mainCanvas_Drop(object sender, DragEventArgs e)
{
Image img = new Image();
img.Width = 200;
img.Height = 150;
BitmapImage bm = new BitmapImage();
if (e.DataView.Contains(StandardDataFormats.StorageItems))
{
var storageItems = await e.DataView.GetStorageItemsAsync();
foreach (StorageFile file in storageItems)
{
var stream = await
file.OpenAsync(Windows.Storage.FileAccessMode.Read);
await bm.SetSourceAsync(stream);
img.Source = bm;
}
img.RenderTransform = new CompositeTransform();
img.ManipulationMode = ManipulationModes.All;
img.ManipulationStarted += mPlayer_ManipulationStarted;
img.ManipulationCompleted += mPlayer_ManipulationCompleted;
img.ManipulationDelta += mPlayer_ManipulationDelta;
mainCanvas.Children.Add(img);
Canvas.SetLeft(img, e.GetPosition(mainCanvas).X);
Canvas.SetTop(img, e.GetPosition(mainCanvas).Y);
}
}
You cant set a video as a source to BitmapImage.
BitmapImage bm = new BitmapImage();
await bm.SetSourceAsync(stream);
You need to use MediaPlayerElement to play a video. Have a look at the example.
Edit
I have to delete the drag and drop for image. Is there a way to detect
whether the item Im dropping is image or video?
private async void mainGrid_Drop(object sender, DragEventArgs e)
{
Image img = new Image();
img.Width = 200;
img.Height = 150;
BitmapImage bm = new BitmapImage();
MediaPlayerElement mediaPlayerElement = new MediaPlayerElement();
if (e.DataView.Contains(StandardDataFormats.StorageItems))
{
var storageItems = await e.DataView.GetStorageItemsAsync();
foreach (StorageFile file in storageItems)
{
if (file.FileType == ".mp4")
{
mediaPlayerElement.Source = MediaSource.CreateFromStorageFile(file);
mainGrid.Children.Add(mediaPlayerElement);
}
else
{
var stream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read);
await bm.SetSourceAsync(stream);
img.Source = bm;
mainGrid.Children.Add(img);
}
}
}
}
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 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.
For the past week I've been researching as much as i can on how to add the ability to crop a profile image in my windows store app. So far I have looked at the Microsoft solution to this but have decided to go a different route. I downloaded a control from NuGet called XamlCropControl. It works pretty well for the UI and even give me information like Original Height/Width The position of the cropped top/bottom/left/right/width/height all within the xaml control. my question is as how to take that information and crop the the image using WriteableBitmapEx. So far this is my code and i'm having a problem.
private async void ProfilePhotoImageClick(object sender, TappedRoutedEventArgs 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)
{
using (Windows.Storage.Streams.IRandomAccessStream fileStream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read))
{
Windows.UI.Xaml.Media.Imaging.BitmapImage bitmapImage = new BitmapImage();
bitmapImage.SetSource(fileStream);
BackgroundLogo.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
PhotoUploadCropper.Opacity = 1;
PhotoUploadCropper.ImageSource = bitmapImage;
ProfileSetupStackPanel.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
imagetoResize = bitmapImage;
}
}
}
BitmapImage imagetoResize;
private void AcceptPhotoImageCropClick(object sender, RoutedEventArgs e)
{
WriteableBitmap bmp = new WriteableBitmap(0,0).FromContent(imagetoResize);
var croppedBmp = bmp.Crop(0, 0, bmp.PixelWidth / 2, bmp.PixelHeight / 2);
croppedBmp.SaveToMediaLibrary("ProfilePhoto.jpg");
}
PhotoUploadCropper is the xamlcropcontrol.
This is the information from xamlcropcontrol
This is the problem im having
It tells me there is no deffinition for FromContent if i have the (imagetoResize) there but if i remove it i get no error. After all the cropping is done it will be uploading to azure blob storage which i have already setup.
Edit: Works like this.
private async void ProfilePhotoImageClick(object sender, TappedRoutedEventArgs 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)
{
using (IRandomAccessStream fileStream = await file.OpenAsync(FileAccessMode.Read))
{
BitmapImage bitmapImage = new BitmapImage();
await bitmapImage.SetSourceAsync(fileStream);
fileclone = file;
BackgroundLogo.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
PhotoUploadCropper.IsEnabled = true;
PhotoUploadCropper.Opacity = 1;
PhotoUploadCropper.ImageSource = bitmapImage;
ProfileSetupStackPanel.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
}
}
}
StorageFile fileclone;
async Task<WriteableBitmap> LoadBitmap(StorageFile file)
{
int cropx = PhotoUploadCropper.CropTop;
int cropy = PhotoUploadCropper.CropLeft;
int cropW = PhotoUploadCropper.CropWidth;
int cropH = PhotoUploadCropper.CropHeight;
using (IRandomAccessStream fileStream = await file.OpenAsync(FileAccessMode.Read))
{
var bmp = await BitmapFactory.New(1, 1).FromStream(fileStream);
var croppedBmp = bmp.Crop(cropy, cropx, cropW, cropH);
var resizedcroppedBmp = croppedBmp.Resize(200, 200, WriteableBitmapExtensions.Interpolation.Bilinear);
return resizedcroppedBmp;
}
}
private async void AcceptPhotoImageCropClick(object sender, RoutedEventArgs e)
{
var CroppedBMP = await CropBitmap(fileclone);
using (IRandomAccessStream fileStream = new InMemoryRandomAccessStream())
{
string filename = Path.GetRandomFileName() + ".JPG";
var file = await Windows.Storage.ApplicationData.Current.TemporaryFolder.CreateFileAsync(filename, CreationCollisionOption.GenerateUniqueName);
using (IRandomAccessStream stream = await file.OpenAsync(FileAccessMode.ReadWrite))
{
BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, stream);
Stream pixelStream = CroppedBMP.PixelBuffer.AsStream();
byte[] pixels = new byte[pixelStream.Length];
await pixelStream.ReadAsync(pixels, 0, pixels.Length);
encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Ignore, (uint)CroppedBMP.PixelWidth, (uint)CroppedBMP.PixelHeight, 96.0, 96.0, pixels);
await encoder.FlushAsync();
}
ProfilePhotoButtonsGrid.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
BackgroundLogo.Visibility = Windows.UI.Xaml.Visibility.Visible;
PhotoUploadCropper.IsEnabled = false;
PhotoUploadCropper.Opacity = 0;
ProfileSetupStackPanel.Visibility = Windows.UI.Xaml.Visibility.Visible;
if (fileStream != null)
{
UploadFile(file);
}
}
}
You will have to use the WBX WinRT APIs for this. Looks like you are trying the WP / Silverlight methods.
Try this:
async Task<WriteableBitmap> LoadBitmap(string path)
{
Uri imageUri = new Uri(BaseUri, path);
var bmp = await BitmapFactory.New(1, 1).FromContent(imageUri);
return bmp;
}
Note it takes an URI. In your case you can rather use the IRandomAccessStream directly:
var bmp = await BitmapFactory.New(1, 1).FromStream(fileStream);