Save image in windows phone 8.1 using FileSavePicker - c#

I want to save an image using File Save Picker . I am using this link to save but it is only for text , how I modify it to save an image?

As you have provided the link then I assume that you managed to get StorageFile after Continuation (this is how it works at WP8.1 Runtime).
I also assume that you have a Stream with your image or you know how to obtain such a one. Basing on those two, you can save your image in png format to a file selected by picker for example like this:
public async Task SaveStreamAsync(IRandomAccessStream streamToSave, StorageFile destination)
{
BitmapDecoder bmpDecoder = await BitmapDecoder.CreateAsync(streamToSave);
PixelDataProvider pixelData = await bmpDecoder.GetPixelDataAsync(BitmapPixelFormat.Rgba8, BitmapAlphaMode.Straight, null, ExifOrientationMode.RespectExifOrientation, ColorManagementMode.DoNotColorManage);
using (var destFileStream = await destination.OpenAsync(FileAccessMode.ReadWrite))
{
BitmapEncoder bmpEncoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, destFileStream);
uint yourWidthAndOrHeight = 1024;
bmpEncoder.SetPixelData(BitmapPixelFormat.Rgba8, BitmapAlphaMode.Straight, yourWidthAndOrHeight, yourWidthAndOrHeight, 300, 300, pixelData.DetachPixelData());
await bmpEncoder.FlushAsync();
}
}
Also please remember to Dispose your streamToSave (and other resources) after finishing working with them.
If you take a look at BitmapEncoder and BitmapDecoder classes, then you will see more options including transformation and various properties.
(I've not tested the code above rough, but hopefully it will work fine)

Related

Can you get a video thumbnail using MediaToolkit without reading/writing to disk?

I have a video file that's already loaded in memory (an IFormFile that's converted to a byte[]).
I've been trying to figure out how to take that video and get a thumbnail image from it, without having to read/write to disk.
I found use cases for MediaToolkit and FFmpeg here, and Movie Thumbnailer here, but from what I can find, those require the video already be saved to disk and have write access to output the thumbnail to a file.
Is there any way I can take either an IFormFile or byte[] and do something similar to what MediaToolkit is doing while being able to keep the result in memory?
I know a lot of folks are saying byte[] isn't the way to go. In that case, I'm more than happy to convert from IFormFile to a Stream, but I still need a way to do that and keep it in memory.
please try this with Windows.Media.Editing should work, not fully tested..
int frameHeight; // you can set the height
int frameWidth; // ...
TimeSpan getFrameInTime = new TimeSpan(0, 0, 1);
//Using Windows.Media.Editing get your ImageStream
var yourClip = await MediaClip.CreateFromFileAsync(someFile);
var composition = new MediaComposition();
// add the section of the video as needed
composition.Clips.Add(yourClip);
// Answer - now that your have your imageStream, get the thumbnail
var yourImageStream = await composition.GetThumbnailAsync(
getFrameInTime,
Convert.ToInt32(frameWidth),
Convert.ToInt32(frameHeight),
VideoFramePrecision.NearestFrame);
//now create your thumbnail bitmap
var yourThumbnailBitmap = new WriteableBitmap(
Convert.ToInt32(frameWidth),
Convert.ToInt32(frameHeight)
);
yourThumbnailBitmap.SetSource(yourImageStream);

Saving Image In UWP Then Loading In WinForms

Good morning StackOverflow,
I come to you today with a scenario that is driving me slowly insane. Im hopeful you can aid me with this, as I’m certain this must be possible but I can’t solve it myself.
My issue is that I’m working on two different applications at present. The first is a UWP application to deliver packages for an internal mail system. The idea here is that upon receipt of the package the person will sign the application using a InkCanvas signature. This should then be saved to the database as a byte array, and then reloaded in either a WinForm or WebForm app (I’m currently doing the WinForm one first) as a regular old image file. However, I’m absolutely stuck on converting between the WriteableBitmap that I get from UWP and the regular Bitmap I need to load in WinForms. Any ideas?
Here’s what I’m doing presently:
Saving the UWP image:
private byte[] SaveImage()
{
var canvasStrokes = SignatureCanvas.InkPresenter.StrokeContainer.GetStrokes();
if (canvasStrokes.Count > 0)
{
var width = (int) SignatureCanvas.ActualWidth;
var height = (int) SignatureCanvas.ActualHeight;
var device = CanvasDevice.GetSharedDevice();
var renderTarget = new CanvasRenderTarget(device, width, height, 96);
using (var drawingSession = renderTarget.CreateDrawingSession())
{
drawingSession.Clear(Colors.White);
drawingSession.DrawInk(SignatureCanvas.InkPresenter.StrokeContainer.GetStrokes());
}
return renderTarget.GetPixelBytes();
}
return null;
}
Then I save the bytes to the database, and pull them from the database in the WinForms app... so am I making some boneheaded mistake here? Am I reading the signature in the wrong format? Or do I need to do something more to convert the formats from one to the other?
I’m stumped, after trying many different results from StackOverflow pages I don’t know what I’m doing wrong.
Any help would be amazing! And sorry if I’ve done something dumb.
You're actually saving raw bitmap data to your database.
I don't remember well how the Winform importer was working but I doubt it can import raw bitmap data.
You should encode your raw data to a PNG or JPEG image first and save the result. You will end with a regular old image file that should be readable from Winform.
using (IRandomAccessStream stream = /* the stream where you want to save the data */)
{
byte[] bytes = renderTarget.GetPixelBytes();
var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, stream);
encoder.SetPixelData(BitmapPixelFormat.Bgra8,
BitmapAlphaMode.Ignore,
(uint)canvas.Width, (uint)canvas.Height,
96, 96, bytes);
await encoder.FlushAsync();
}

Loading image from picture library to image source

I am capturing an image . Project places the image in picture library that is C:\...\Pictures\PreviewFrame.jpg.
I have an image tag
<Image Name="ClinicImage"></Image>
Now i want to load that PreviewFrame.jpg in this tag.
I tried this
ClinicImage.Source=new BitmapImage(new Uri(path));
where
path is a string variable containing image path.
But it is not getting loaded. How should i do it?
Thanks in advance.
There is some retrictions about what the universal applications can access.
You need first to be sure that the picture library capability is properly added in your application manifest.
Then, you can open the image using GetFileFromPathAsync() and provide the stream to the BitmapSource using SetSourceAsync()
var file = await StorageFile.GetFileFromPathAsync("c:\\users\\me\\images\\a.png");
var stream = await file.OpenReadAsync();
var imageSource = new BitmapImage();
await imageSource.SetSourceAsync(stream);
Make sure your slashes are set correctly. If I remember correctly, you need to work with double backslash instead of single.

Save PDF to file

I am working on a Windows Store app for Windows 8.1, and I can't find anything that addresses what I need to do. I am trying to save an image of a pdf page to my local app data storage. I have the following:
private async void GetFirstPage()
{
// Retrieve file from FutureAccessList
StorageFile file = await Windows.Storage.AccessCache.StorageApplicationPermissions.FutureAccessList.GetFileAsync(token);
// Truncate last 4 chars; ex: '.pdf'
FileName = file.Name.Substring(0, file.Name.Length - 4);
// Get access to pdf functionality from file
PdfDocument doc = await PdfDocument.LoadFromFileAsync(file);
// Get a copy of the first page
PdfPage page = doc.GetPage(0);
// Below could be used to tweak render options for optimizations later
//PdfPageRenderOptions options = new PdfPageRenderOptions();
// Render the first page to the BitmapImage
InMemoryRandomAccessStream stream = new InMemoryRandomAccessStream();
await page.RenderToStreamAsync(stream);
// Common code
Cover.SetSource(stream);
// Convert the active BitmapImage Cover to a storage file to be stored locally
// ???
}
The variable, Cover, is a BitmapImage that is bound in XAML to display the image to the user. I want to save this image to my local app data so that I don't have to re-render it through the PDF library every time my app opens! The problem is I can't save anything in a Windows Store app from a stream unless it is text to my knowledge, (no filestream or fileoutputstreams for me), and Cover's URI source is null, since it was sourced from a stream, making it difficult to get my BitmapImage, Cover, to a StorageFile for proper Windows Store saving.
Everything works for me currently, I'm just upset about re-rendering the pdf page to my bitmapimage from scratch every time my app opens. Thanks in advance for any input!
You need to save the image from the PdfPage directly rather than from the BitmapImage since you can't get the data out of the BitmapImage. The PdfPage.RenderToStreamAsync already encodes the stream as a bitmap so you don't need to do any manipulation beyond sending it to the file. This is essentially the same as what you are doing to save to the InMemoryRandomAccessStream, except to a file based stream:
//We need a StorageFile to save into.
StorageFile saveFile = await ApplicationData.Current.LocalFolder.CreateFileAsync("safedPdf.png",CreationCollisionOption.GenerateUniqueName);
using (var saveStream = await saveFile.OpenAsync(FileAccessMode.ReadWrite))
{
await page.RenderToStreamAsync(saveStream);
}

Get stream from path wp8

I want to set an image choosen from picture library as background. So I take the originalname of the choosen photo in IsolatedStorageSetting. But later i do not manage to get the stream of the file from the path.. here the code:
bitmapimage.UriSource = new Uri(Settings.BackgroundPhotoUrl, UriKind.Absolute);
BackgroundImg.ImageSource = bitmapimage;
But this code does not work. No exception. Just the background is black.
So I have tried to save the Stream in IsolatedStorageSetting (I do not relly like this solution!!) but in this case I obtain an exception:
Operation denied
Here the code:
Settings.MyStream = e.ChosenPhoto
In the end, I have tried to save the image in isolated storage:
using (System.IO.IsolatedStorage.IsolatedStorageFile isf = System.IO.IsolatedStorage.IsolatedStorageFile.GetUserStoreForApplication())
{
isf.CopyFile(e.OriginalFileName, "background" + System.IO.Path.GetExtension(e.OriginalFileName), true);
}
But also in this case i obtain an operation denied exception
How can I solve the problem?? Thanx
It seems you are misunderstanding streams. A stream is a pointer to a position in a file you can read from or write to. If you are you are using a photo chooser then the result will give you a stream to the file. You need to read the bytes from that at stream and save then you your local storage. Then you can access the image from there.
In my Live Countdown app I use the WriteableBitmap class to save the Jpeg to a stream. Something along the lines of this:
var store =
System.IO.IsolatedStorage.IsolatedStorageFile.GetUserStoreForApplication();
var newPath = "MyFileName.png";
if (store.FileExists(newPath)) store.DeleteFile(newPath);
var stream = store.CreateFile(newPath);
BitmapImage i = new BitmapImage();
i.SetSource(photoResult.ChosenPhoto);
WriteableBitmap imageToSave = new WriteableBitmap(i);
imageToSave.SaveJpeg(stream, 173, 173, 0, 100);
stream.Flush();
stream.Close();
That is kind of the flow. I had to take parts from different functions and put them together as the app allows the user to scale the app first. There is scaling the SaveJpeg method parameters as I am saving the image for a tile.

Categories