StorageFile.GetImagePropertiesAsyn c () дает неверные результаты при использовании StorageFileQueryResult с метаданными изображения - PullRequest
2 голосов
/ 28 января 2020

К сожалению, если я не ошибаюсь, кажется, что в API-интерфейсе StorageFile Query есть ошибка, которая делает его ненадежным.

Следующий пример прост. Чтобы воспроизвести его, выполните следующие действия:

- возьмите папку и поместите только одно изображение, поскольку в приведенном ниже примере предполагается, что у вас будет только один файл.

- это изображение должно быть в формате PEF , взято из Pentax 645Z. Вы можете найти весь проект, а также изображение PEF здесь. https://github.com/Ponant/StorageFileQueryResultBug. Поместите образец изображения в одну папку в индексированном месте, например, на рабочем столе.

-Установите Raw Image Extension из Microsoft Store, https://www.microsoft.com/en-us/p/raw-image-extension/9nctdw2w1bh8?activetab=pivot: Overviewtab . Это расширение основано на https://www.libraw.org/, и они поддерживают эту камеру https://www.libraw.org/supported-cameras

Запустите приложение, вы увидите две кнопки:

1) Кнопка 1 запускает средство выбора папки, создает StorageFileQueryResult, который позволяет получить единственный файл в папке. Затем он вызывает API для свойств изображения

                var imageProperties = await file.Properties.GetImagePropertiesAsync();

2) Кнопка 2 запускает FilePicker, поэтому вы переходите к папке, выбираете тот же файл и затем выполняете тот же метод

                var imageProperties = await file.Properties.GetImagePropertiesAsync();

Два результата отображаются в двух текстовых блоках. Они должны быть идентичны, они не являются. Запрос папки возвращает пустые значения.

enter image description here

Как мы можем решить эту проблему? Почему Filepicker дает правильный результат на том же StorageFile? Может ли кто-нибудь подтвердить, является ли это известной ошибкой, можем ли мы помочь в ее устранении?

Мы в значительной степени полагаемся на StorageFileQueryResult, чтобы создать приложение, которое позволяет людям просматривать изображения и отображать метаданные. Эта проблема надежности пугает, мягко говоря, и мы не можем предложить пользователю использовать FilePicker на изображениях 10k:).

Дополнительное примечание: Проводник файлов, как и FilePicker, дает правильный ответ. Мы также нашли в Интернете приложение для просмотра файлов UWP, которое можно запустить с Win+R, и оно дает правильную информацию.

shell:AppsFolder\c5e2524a-ea46-4f67-841f-6a9465d9d515_cw5n1h2txyewy!App

Это дает надежду, что UWP может отображать правильную информацию без использования средства выбора файлов. а скорее путем запроса папки. Мы можем добиться этого, выбрав

                IndexerOption = IndexerOption.DoNotUseIndexer,

в параметрах запроса, следовательно, не полагаясь на индексатор, но очень жаль, что сделает приложение менее производительным и, кроме того, заставит нас добавлять дополнительный код, так как мы используем индексатор сильно.

Спасибо

public sealed partial class Scenario4 : Page
{
    public Scenario4()
    {
        this.InitializeComponent();
    }
    private async void FolderPickerButton_Click(object sender, RoutedEventArgs e)
    {
        var folderPicker = new FolderPicker
        {
            SuggestedStartLocation = PickerLocationId.Desktop,
            ViewMode = PickerViewMode.Thumbnail
        };
        folderPicker.FileTypeFilter.Add("*");
        var folder = await folderPicker.PickSingleFolderAsync();
        if (folder == null)
        {
            return;
        }

        var queryOptions = new QueryOptions
        {
            IndexerOption = IndexerOption.UseIndexerWhenAvailable,
        };
        var query = folder.CreateFileQueryWithOptions(queryOptions);

        var files = (await query.GetFilesAsync());
        foreach (var file in files)
        {
            var imageProperties = await file.Properties.GetImagePropertiesAsync();
            folderThenQueryMethodTextBlock.Text =
                $"Dimensions {imageProperties.Width}x{imageProperties.Height} DateTaken {imageProperties.DateTaken}";
        }
    }
    private async void OpenFileAppBarButton_Click(object sender, RoutedEventArgs e)
    {
        FileOpenPicker picker = new FileOpenPicker();
        picker.FileTypeFilter.Add("*");
        picker.SuggestedStartLocation = PickerLocationId.Desktop;

        var file = await picker.PickSingleFileAsync();
        if (file != null)
        {
            var imageProperties = await file.Properties.GetImagePropertiesAsync();
            filePickerMethodTextBlock.Text =
                $"Dimensions {imageProperties.Width}x{imageProperties.Height} DateTaken {imageProperties.DateTaken}";
        }
    }
}

XAML

<Page
x:Class="Virtualization.Scenario4"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="using:Virtualization"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="auto"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <StackPanel Orientation="Horizontal" HorizontalAlignment="Center"
                BorderBrush="Blue" BorderThickness="2" Margin="0,8,0,0">
        <Button x:Name="FolderPickerButton" Content="Query folder with one file"
                      Click="FolderPickerButton_Click"/>
        <Button Content="File picker"  Click="OpenFileAppBarButton_Click" Margin="16,0,0,0"/>
        <AppBarSeparator/>
    </StackPanel>
    <StackPanel Grid.Row="1" HorizontalAlignment="Center">
        <TextBlock Text="Using Query after Folder Picker"/>
        <TextBlock x:Name="folderThenQueryMethodTextBlock"/>
        <TextBlock Text="Using File Picker"/>
        <TextBlock x:Name="filePickerMethodTextBlock"/>
    </StackPanel>
</Grid>

1 Ответ

1 голос
/ 29 января 2020

Я потратил время, установил расширение и опробовал ваш код. Все, что вы сказали, правильно. StorageFile при получении из StorageFileQueryResult приводит к использованию по умолчанию (неправильных) свойств изображения для файла PEF, но отлично работает с файлами jpg. Это явно ошибка. Является ли ошибка в рамках или в расширении изображения RAW, я не знаю. Обратите внимание, что расширение имеет множество негативных отзывов в Windows Store.

Существует разумное решение. Вам не нужно делать один файл за раз. Вместо использования запроса вы можете сделать это:

var files = await folder.GetFilesAsync();
foreach (var file in files)
{
    var imageProperties = await file.Properties.GetImagePropertiesAsync();
    folderThenQueryMethodTextBlock.Text =
        $"Dimensions {imageProperties.Width}x{imageProperties.Height} DateTaken {imageProperties.DateTaken}";
}

Я могу подтвердить, что это работает.

Если вам нужна мощность запроса, вы можете использовать его просто для получения списка имена файлов, затем используйте «StorageFolder.GetFileAsyn c (fileName)» в foreach l oop. Пока StorageFile поставляется из StorageFolder.GetXXX, он, кажется, работает нормально.

...