Save File Thumbnail as image in windows runtime - c#

I want to get Thumbnail of files stored in Videos folder and save them as image in my local folder .
here is my code to get files .
var v = await KnownFolders.VideosLibrary.GetFilesAsync();
foreach (var file in v)
{
var thumb = await file.GetScaledImageAsThumbnailAsync(Windows.Storage.FileProperties.ThumbnailMode.SingleItem);
BitmapImage Img = new BitmapImage();
Img.SetSource(thumb);
await ApplicationData.Current.LocalFolder.CreateFolderAsync("VideoThumb");
var imageFile = await ApplicationData.Current.LocalFolder.CreateFileAsync(
"VideoThumb\\" + file.Name, CreationCollisionOption.FailIfExists);
var fs = await imageFile.OpenAsync(FileAccessMode.ReadWrite);
//I don't know how to save thumbnail on this file !
}
my project is a Windows Phone 8.1 Runtime C# app .

There are couple of things you need to handle:
you don't need BitmapImage, as thumbnail provides a stream which you can write directly to file,
you are not handling the case when create file method fails (file exists),
create folder method will throw exception as the folder is created (or already exists) with the first file in foreach. Rather than that, create/open folder outside foreach,
also creating image with file.Name is not a good idea, hence those are videos and their extension will likely be mp4/mpg/other not jpg/png/other,
remember to add capabilities in packageappx.manifest file.
I think the below code should do the job:
private async Task SaveViedoThumbnails()
{
IBuffer buf;
StorageFolder videoFolder = await ApplicationData.Current.LocalFolder.CreateFolderAsync("VideoThumb", CreationCollisionOption.OpenIfExists);
Windows.Storage.Streams.Buffer inputBuffer = new Windows.Storage.Streams.Buffer(1024);
var v = await KnownFolders.VideosLibrary.GetFilesAsync();
foreach (var file in v)
{
var thumb = await file.GetScaledImageAsThumbnailAsync(Windows.Storage.FileProperties.ThumbnailMode.SingleItem);
var imageFile = await videoFolder.CreateFileAsync(file.DisplayName + ".jpg", CreationCollisionOption.ReplaceExisting);
using (var destFileStream = await imageFile.OpenAsync(FileAccessMode.ReadWrite))
while ((buf = (await thumb.ReadAsync(inputBuffer, inputBuffer.Capacity, Windows.Storage.Streams.InputStreamOptions.None))).Length > 0)
await destFileStream.WriteAsync(buf);
}
}

Related

Xamarin.Essentials Share drawable

I'm trying to share a local image loacted in my Resources/Drawables folder in Android.
I'm using Xamarin and the Xamarin.Essentials plugin.
So there is this function:
await Share.RequestAsync(new ShareFileRequest
{
Title = Title,
File = new ShareFile(file)
});
So for the File I need the Path to the File from the Drawable Folder.
I have tried so much variations.
For example:
var file = Android.Net.Uri.Parse("android.resource://" + Android.App.Application.Context.PackageName + "/" + Resource.Drawable.image).Path;
But I always get an error, that the file is not found.
What I'm doing wrong?
Thanks in advance
Because Resources don't have file paths, as #Jason said I saved the image in another accesible file.
So I don't know if this is the best solution, but it works for me:
Drawable drawable = ResourcesCompat.GetDrawable(Resources, Resource.Drawable.image, null);
Bitmap bitmap = ((BitmapDrawable)drawable).Bitmap;
byte[] imgByteArray;
using (var stream = new MemoryStream())
{
bitmap.Compress(Bitmap.CompressFormat.Png, 0, stream);
imgByteArray = stream.ToArray();
}
var file = System.IO.Path.Combine(FileSystem.CacheDirectory, "share.png");
File.WriteAllBytes(file, imgByteArray);
await Share.RequestAsync(new ShareFileRequest
{
Title = "Share",
File = new ShareFile(file)
});

Copy files to USB using C# Windows 10 iot core

I am trying to copy .csv files created in the local folder in Windows 10 iot core. I have tried few ways but no luck. My latest code is as follows:
string aqs = UsbDevice.GetDeviceSelector(0x045E, 0x0611);
var myDevices = await Windows.Devices.Enumeration.DeviceInformation.FindAllAsync(aqs);
UsbDevice usbDevice;
try
{
if(myDevices == null)
{
return;
}
usbDevice = await UsbDevice.FromIdAsync(myDevices[0].Id);
StorageFolder localFolder = Windows.Storage.ApplicationData.Current.LocalFolder;
StorageFolder sourcef = await localFolder.CreateFolderAsync("My Data", CreationCollisionOption.OpenIfExists);
IReadOnlyList<StorageFile> filel = await sourcef.GetFilesAsync();
StorageFolder removableDevices = KnownFolders.RemovableDevices;
//var externalDrives = await removableDevices.GetFoldersAsync();
//var drive0 = externalDrives[0];
//var destFolder = await removableDevices.CreateFolderAsync("My Data", CreationCollisionOption.GenerateUniqueName);
foreach (StorageFile file in filel)
{
await file.CopyAsync(removableDevices);
}
}
In the above i get an exception on:
usbDevice = await UsbDevice.FromIdAsync(myDevices[0].Id);
'myDevices[0].Id' threw an exception of type 'System.ArgumentOutOfRangeException'
I have tried checking if this is null and it is not null.
The aim of this is to basically copy few text files from Local Folder to the USB drive.
The usb storage can not be found by using UsbDevice.GetDeviceSelector, the methods in Windows.Devices.Usb namespace are used for valid WinUSB device which has a compatible id of USB\MS_COMP_WINUSB, but a usb storage will not include compatible id.In fact, KnownFolders.RemovableDevices is enough to access the device.

UWP image picker not working for image source

I'm trying to get image picker to work, and it does, but for some reason it won't populate as an image.
var openPicker = new FileOpenPicker
{
ViewMode = PickerViewMode.Thumbnail,
SuggestedStartLocation = PickerLocationId.PicturesLibrary
};
openPicker.FileTypeFilter.Add(".jpg");
openPicker.FileTypeFilter.Add(".jpg");
openPicker.FileTypeFilter.Add(".jpeg");
openPicker.FileTypeFilter.Add(".png");
var file = await openPicker.PickSingleFileAsync();
if (file != null)
{
//Image img = new Image();
userImage.Source = new BitmapImage(new Uri(file.Path));
//await ProcessFile(file);
}
and the image is just simply:
<image name="userImage" height="500px" width="500px"/>
This isn't work because the UWP applications have permissions only for some users folders and even you need to browse their files, you need to specify it in the package.manifest of your application which folders you want to access. For simplification, you could create a copy of the file inside the application data folder and get the path from there or set the image source from the stream of the file, but be careful, the second option maybe lead some high memory usage and leaks. You can find how to avoid this here.
You can set stream as source instead of path.
var result = new BitmapImage();
using (var randomAccessStream = await file.OpenAsync(FileAccessMode.Read))
{
await result.SetSourceAsync(randomAccessStream);
}

How to add folder to StorageLibrary without RequestAddFolderAsync in C#

I need to save app files to plugged SD card. I'm using UWP and Windows 10.
MSDN tells how to do it with Windows Libraries.
var myPicsLibrary = await Windows.Storage.StorageLibrary.GetLibraryAsync(Windows.Storage.KnownLibraryId.Pictures);
await myPicsLibrary.RequestAddFolderAsync();
RequestAddFolderAsync() shows file picker, where user can choose folder to add into Pictures. In my case it's a folder, created on SD card.
Is there a way to do this thing without file picker dialog?
I'm trying to do like this:
var myPicsLibrary = await Windows.Storage.StorageLibrary.GetLibraryAsync(Windows.Storage.KnownLibraryId.Pictures);
// Get the logical root folder for all external storage devices.
StorageFolder externalDevices = Windows.Storage.KnownFolders.RemovableDevices;
// Get the first child folder, which represents the SD card.
StorageFolder sdCard = (await externalDevices.GetFoldersAsync()).FirstOrDefault();
var folder = await sdCard.CreateFolderAsync("MySDCardFolder");
myPicsLibrary.Folders.Insert(myDocs.Folders.Count+1, folder); // NotImplementedException: 'The method or operation is not implemented.'
myPicsLibrary.Folders.Add(folder); // NotImplementedException: 'The method or operation is not implemented.'
Or maybe I can do the same without using Windows Libraries directly working with SDCard?
Thanks a lot!
EDIT:
In the another hand my question sounds like "How to save files to plugged SD card?"
The StorageLibrary.Folders gets the folders in the current library, it return the IObservableVector of the StorageFolder. When we add the folder into the IObservableVector, it will not change the folder in files system. It will throw the "The method or operation is not implemented." exception.
We should be able to get the name of the folder, and create the folder uses that name. Then we can StorageFile.CopyAsync method to copy the file that in your folder.
For example:
public static async Task CopyFolderAsync(StorageFolder source, StorageFolder destinationContainer, string desiredName = null)
{
StorageFolder destinationFolder = null;
destinationFolder = await destinationContainer.CreateFolderAsync(
desiredName ?? source.Name, CreationCollisionOption.ReplaceExisting);
foreach (var file in await source.GetFilesAsync())
{
await file.CopyAsync(destinationFolder, file.Name, NameCollisionOption.ReplaceExisting);
}
foreach (var folder in await source.GetFoldersAsync())
{
await CopyFolderAsync(folder, destinationFolder);
}
}
Then we can use the CopyFolderAsync method to copy the folder in the Picture Library.
var myPicsLibrary = await Windows.Storage.StorageLibrary.GetLibraryAsync(Windows.Storage.KnownLibraryId.Pictures);
var myfolder = myPicsLibrary.Folders[0];
StorageFolder externalDevices = Windows.Storage.KnownFolders.RemovableDevices;
StorageFolder sdCard = (await externalDevices.GetFoldersAsync()).FirstOrDefault();
var folder = await sdCard.CreateFolderAsync("MySDCardFolder");
await CopyFolderAsync(folder, myfolder);
As I get from your question you need to create a Folder in PicturesLibrary .
You can use the code below to add a folder into PicturesLibrary
await Windows.Storage.KnownFolders.PicturesLibrary.CreateFolderAsync("MySDCardFolder");
if you want to make it on SD Card only Maybe KnownFolders.RemovableDevices Should be helpful . I didn't used KnownFolders.RemovableDevices yet but if you have any issue let me know to test it on my phone directly

How do I save an image url to a local file in Windows 8 c#

Basically, the app displays images, and I want the user to be able to select an image for download and store it locally.
I have the URL, but I don't know how to use that url in conjunction with the filepicker.
You can use the following method to download the file from a given Uri to a file selected with a file picker:
private async Task<StorageFile> SaveUriToFile(string uri)
{
var picker = new FileSavePicker();
// set appropriate file types
picker.FileTypeChoices.Add(".jpg Image", new List<string> { ".jpg" });
picker.DefaultFileExtension = ".jpg";
var file = await picker.PickSaveFileAsync();
using (var fileStream = await file.OpenStreamForWriteAsync())
{
var client = new HttpClient();
var httpStream = await client.GetStreamAsync(uri);
await httpStream.CopyToAsync(fileStream);
fileStream.Dispose();
}
return file;
}
I think you can always read the file as a stream and save it bit by bit on the local machine. But I need to say that I've done this many times in JAVA, I never needed to check this in C# :)
SaveFileDialog myFilePicker = new SaveFileDialog();
//put options here like filters or whatever
if (myFilePicker.ShowDialog() == DialogResult.OK)
{
WebClient webClient = new WebClient();
webClient.DownloadFile("http://example.com/picture.jpg", myFilePicker.SelectedFile);
}

Categories

Resources