Can't display image from Removeable SD - UWP W

2019-08-25 13:02发布

问题:

I have done all of the things necessary to gaining access to the files located on the SD card of my IOT device (DragonBoard 410c).

I have all of the FileTypeAssociations

    <Capability Name="internetClient" />
    <Capability Name="privateNetworkClientServer" />
    <Capability Name="internetClientServer" />
    <uap:Capability Name="userAccountInformation" />
    <uap:Capability Name="removableStorage" />
    <uap:Capability Name="enterpriseAuthentication" />

I CAN see and iterate over the files on the SD card

StorageFolder removablelDevices = Windows.Storage.KnownFolders.RemovableDevices;
StorageFolder sdCard = (await removablelDevices.GetFoldersAsync()).FirstOrDefault();
var files = await nm.GetFilesAsync();

foreach (var file in files)
{
    DebugText(file.Path);
    //E:\Photo1.jpg
    //E:\Photo2.jpg
}

I am setting the ImageSource of the ImageBrush of the Background to these pictures in a slideshow.

private ImageSource _CurrentPicture;
public ImageSource CurrentPicture { get { return _CurrentPicture; } set { Set(ref _CurrentPicture, value); } }

<ImageBrush  Stretch="UniformToFill" ImageSource="{x:Bind ViewModel.CurrentPicture, Mode=OneWay}"/>

The pictures do not show up (E:\Photo1.jpg etc)

I AM able to iterate over fileshares on a local server during development mode, so my pictures do show on my Background in that scenario.


I am updating the background with a DispatchTimer.
Now that file access is async, I am running into async hell.

public void TimerSetup()
{
    SlideShowTimer = new DispatcherTimer();
    SlideShowTimer.Tick += SlideShowTimer_Tick;
    SlideShowTimer.Interval = new TimeSpan(0, 0, SlideShowChangeIntervalSeconds);
    SlideShowTimer.Start();

}
void SlideShowTimer_Tick(object sender, object e)
{
    ChangeBackground();
}
public async Task ChangeBackground()
{
    var nextIndex = RandomGenerator.Next(0, SlideShowFiles.Length);
    var fileName = SlideShowFiles[nextIndex];
    var file = await StorageFile.GetFileFromPathAsync(fileName);
    var stream = await file.OpenAsync(FileAccessMode.Read);
    await CurPicImage.SetSourceAsync(stream);
    await Task.CompletedTask;
}

回答1:

The ImageSource property on ImageBrush doesn't automatically convert file paths to ImageSource object. You will have to do the conversion in your code:

var file = await StorageFile.GetFileFromPathAsync(@"E:\Photo1.jpg");
var stream = await file.OpenAsync(FileAccessMode.Read);
var bitmapImage = new Windows.UI.Xaml.Media.Imaging.BitmapImage();
imageBrush.ImageSource = bitmapImage;
await bitmapImage.SetSourceAsync(stream);

The above is the simple (quick & dirty) way to set an imagebrush from file path in code. The more elegant way will be to implement an IValueConverter to be used in your data binding. Since you want the data binding to be async and not block the UI thread there is a little bit more coding required. The details of how to implement an async IValueConverter can be found in this excellent answer: Async Implementation of IValueConverter