Search code examples
c#xamluwpfileopenpicker

Open multiple files by selecting single file in a sequence - Generate file name from multiple files


I have a UWP app that has an option to open an Image Sequence. Typically image sequences are named as follows:

MyImageSequence_00001.png, MyImageSequence_00002.png, ... MyImageSequence_01024.png, MyImageSequence_01025.png,

Generally, these image sequences will be named something like "UniqueFileName_v06" with a frame number like "_0004" following. In a lot of cases you could have multiple image sequences in the same folder but they will have different leading names such as "UniqueFileName_v04_Reflections" or "UniqueFileName_v04_Depth". The starting frame number could be any number and the frame number will increase sequentially to the last frame of the sequence.

I'm currently having the user select all of the files manually as follows:

        FileOpenPicker filePicker = new FileOpenPicker();
        filePicker.ViewMode = PickerViewMode.List:
        filePicker.FileTypeFilter.Add(".png");
        filePicker.FileTypeFilter.Add(".jpg");
        filePicker.FileTypeFilter.Add(".tif");

        files = await filePicker.PickMultipleFilesAsync();

What I am hoping to do is allow a user to open their image sequence by selecting a single image from the sequence in a file picker. So if they were to select "MyImageSequence_00003.png" the app will find and select the rest of the files in the sequence (MyImageSequence 00001-01025) and add them to the filePickerSelectedFilesArray variable files.

Secondly, I'd like to generate a composite string name from the list of files. So, generate a name like "MyImageSequence_00001-01025" to identify the image sequence.

Any thoughts on the best way to go about this? Seems like I should use something like the StorageItemsQuery class but unsure if that is the best method nor how to go about it.

Thanks for any help you can provide!

I'm using the following to get the Image sequence name without frame numbers:

File path to input C:\Users\Me\Desktop\MyImageSequenceFolder\MyImageSequence_00001.png

string input = Path.GetFileNameWithoutExtension(fileFromImageSequence.Path);
string pattern = @"\d+$";
string replacement = "";
Regex rgx = new Regex(pattern);
string result = rgx.Replace(input, replacement);

sequenceName = result.TrimEnd('_');

sequenceName output is "MyImageSequence"


Solution

  • At present, native UWP applications cannot access files through paths (permission restrictions).

    According to your description, the picture sequences are all placed in the one folder. Then before selecting a file through FileOpenPicker, we can first obtain access to the folder and add it to the future access list.

    public async Task<StorageFolder> GetImageFolderAsync(string token = "")
    {
        StorageFolder folder;
        if (string.IsNullOrEmpty(token))
        {
            var folderPicker = new FolderPicker();
            folderPicker.SuggestedStartLocation = PickerLocationId.Desktop;
            folderPicker.FileTypeFilter.Add("*");
            folder = await folderPicker.PickSingleFolderAsync();
            if (folder != null)
            {
                string folderToken = StorageApplicationPermissions.FutureAccessList.Add(folder);
                // save token to LocalSettings or other location.
                // ...
            }
        }
        else
        {
            folder = await StorageApplicationPermissions.FutureAccessList.GetFolderAsync(token);
        }
        return folder;
    }
    

    After adding the folder to FutureAccessList, we will get a Token. In the future, we can get the folder directly through Token without opening FolderPicker. This is equivalent to the user authorizing the application to access the folder.

    Then, when the user selects the file through FileOpenPicker, you can obtain the folder by the above method, and find the same type of image sequence in the folder according to the rules you set (like StorageItemsQuery).

    public async Task<IReadOnlyList<StorageFile>> SearchSameImages(StorageFile fileFromImageSequence)
    {
        string input = Path.GetFileNameWithoutExtension(fileFromImageSequence.Path);
        string pattern = @"\d+$";
        string replacement = "";
        Regex rgx = new Regex(pattern);
        string result = rgx.Replace(input, replacement);
        sequenceName = result.TrimEnd('_');
    
        var queryOptions = new QueryOptions();
        queryOptions.ApplicationSearchFilter = $"\"{sequenceName}\"";
        string token = GetToken(); // From LocalSettings or other place.
        var folder = await GetImageFolderAsync(token);
    
        var queryResult = folder.CreateFileQueryWithOptions(queryOptions);
        var files = await queryResult.GetFilesAsync();
        return files;
    }
    

    In this way, you can ask the user to specify a folder to store the sequence of pictures when the application first starts, and retain access to the folder after that. Use the method provided above to query the sequence of pictures in a folder based on a single file.

    Thanks.