Definir o filtro para um OpenFileDialog para permitir os formatos de imagem típicos?

229

Eu tenho esse código, como posso aceitar todos os formatos de imagem típicos? PNG, JPEG, JPG, GIF?

Aqui está o que eu tenho até agora:

public void EncryptFile()
{            
    OpenFileDialog dialog = new OpenFileDialog();
    dialog.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*";
    dialog.InitialDirectory = @"C:\";
    dialog.Title = "Please select an image file to encrypt.";

    if (dialog.ShowDialog() == DialogResult.OK)
    {
        //Encrypt the selected file. I'll do this later. :)
    }             
}

Observe que o filtro está definido para arquivos .txt. Eu poderia mudar para PNG, mas e os outros tipos?

Sergio Tapia
fonte

Respostas:

289

Nos documentos , a sintaxe do filtro necessária é a seguinte:

Office Files|*.doc;*.xls;*.ppt

ou seja, separe as várias extensões com ponto e vírgula - assim Image Files|*.jpg;*.jpeg;*.png;...,.

Itowlson
fonte
179

Siga este padrão se estiver navegando em arquivos de imagem:

dialog.Filter =  "Image files (*.jpg, *.jpeg, *.jpe, *.jfif, *.png) | *.jpg; *.jpeg; *.jpe; *.jfif; *.png";
Devam Mehta
fonte
6
Provavelmente, quer se livrar dos espaços antes e depois do caractere de tubo e entre o ponto e vírgula e o asterisco na parte do filtro. Mas bom, caso contrário.
fácil
Você também pode agrupar qualquer tipo de arquivo dessa maneira. Agradável!
Alper
74

Aqui está um exemplo da sugestão ImageCodecInfo (no VB):

   Imports System.Drawing.Imaging
        ...            

        Dim ofd as new OpenFileDialog()
        ofd.Filter = ""
        Dim codecs As ImageCodecInfo() = ImageCodecInfo.GetImageEncoders()
        Dim sep As String = String.Empty
        For Each c As ImageCodecInfo In codecs
            Dim codecName As String = c.CodecName.Substring(8).Replace("Codec", "Files").Trim()
            ofd.Filter = String.Format("{0}{1}{2} ({3})|{3}", ofd.Filter, sep, codecName, c.FilenameExtension)
            sep = "|"
        Next
        ofd.Filter = String.Format("{0}{1}{2} ({3})|{3}", ofd.Filter, sep, "All Files", "*.*")

E fica assim:

insira a descrição da imagem aqui

Tom Faust
fonte
Benefício dessa abordagem: acompanhará quaisquer adições futuras dos tipos de imagem suportados ao .NET. Obrigado
UuDdLrLrSs 28/03/19
Eu amo tanto isso que o convertei na frase mais nojenta do mundo! Dim ofd As New OpenFileDialog() With {.Filter = ImageCodecInfo.GetImageEncoders().Aggregate("All Files (*.*)|*.*", Function(s, c) $"{s}|{c.CodecName.Substring(8).Replace("Codec", "Files").Trim()} ({c.FilenameExtension})|{c.FilenameExtension}")}Ah sim. VB, às vezes sinto sua falta
Westonsupermare
46

A solução completa em C # está aqui:

private void btnSelectImage_Click(object sender, RoutedEventArgs e)
{
    // Configure open file dialog box 
    Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
    dlg.Filter = "";

    ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
    string sep = string.Empty;

    foreach (var c in codecs)
    {
       string codecName = c.CodecName.Substring(8).Replace("Codec", "Files").Trim();
       dlg.Filter = String.Format("{0}{1}{2} ({3})|{3}", dlg.Filter, sep, codecName, c.FilenameExtension);
       sep = "|";
    }

    dlg.Filter = String.Format("{0}{1}{2} ({3})|{3}", dlg.Filter, sep, "All Files", "*.*"); 

    dlg.DefaultExt = ".png"; // Default file extension 

    // Show open file dialog box 
    Nullable<bool> result = dlg.ShowDialog();

    // Process open file dialog box results 
    if (result == true)
    {
       // Open document 
       string fileName  = dlg.FileName;
       // Do something with fileName  
    }
} 
Desenvolvedor
fonte
23

Para filtrar arquivos de imagens, use este exemplo de código.

//Create a new instance of openFileDialog
OpenFileDialog res = new OpenFileDialog();

//Filter
res.Filter = "Image Files|*.jpg;*.jpeg;*.png;*.gif;*.tif;...";

//When the user select the file
if (res.ShowDialog() == DialogResult.OK)
{
   //Get the file's path
   var filePath = res.FileName;
   //Do something
   ....
}
HermF
fonte
14

Eu gosto da resposta de Tom Faust da melhor maneira. Aqui está uma versão em C # de sua solução, mas simplificando um pouco as coisas.

var codecs = ImageCodecInfo.GetImageEncoders(); 
var codecFilter = "Image Files|"; 
foreach (var codec in codecs) 
{
    codecFilter += codec.FilenameExtension + ";"; 
} 
dialog.Filter = codecFilter;
NielW
fonte
11

Para imagens, você pode obter os codecs disponíveis no GDI (System.Drawing) e criar sua lista com um pouco de trabalho. Este seria o caminho mais flexível a seguir.

ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
Muad'Dib
fonte
5
Obrigado por esta dica! Eu adicionei estes e funcionou como um encanto: var imageExtensions = string.Join(";", ImageCodecInfo.GetImageDecoders().Select(ici => ici.FilenameExtension)); dialog.Filter = string.Format("Images|{0}|All Files|*.*", imageExtensions);
atlantis
ugh ... não sei como fazer blocos de código com várias linhas em um comentário: |
atlantis
1
Não é o autor original :)
atlantis
9

Apenas um necrocomment para usar string.Join e LINQ.

ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
dlgOpenMockImage.Filter = string.Format("{0}| All image files ({1})|{1}|All files|*", 
    string.Join("|", codecs.Select(codec => 
    string.Format("{0} ({1})|{1}", codec.CodecName, codec.FilenameExtension)).ToArray()),
    string.Join(";", codecs.Select(codec => codec.FilenameExtension).ToArray()));
Anthony L. Gershman
fonte
4

Para quem não quer se lembrar da sintaxe toda vez, aqui está um encapsulamento simples:

public class FileDialogFilter : List<string>
{
    public string Explanation { get; }

    public FileDialogFilter(string explanation, params string[] extensions)
    {
        Explanation = explanation;
        AddRange(extensions);
    }

    public string GetFileDialogRepresentation()
    {
        if (!this.Any())
        {
            throw new ArgumentException("No file extension is defined.");
        }

        StringBuilder builder = new StringBuilder();

        builder.Append(Explanation);

        builder.Append(" (");
        builder.Append(String.Join(", ", this));
        builder.Append(")");

        builder.Append("|");
        builder.Append(String.Join(";", this));

        return builder.ToString();
    }
}

public class FileDialogFilterCollection : List<FileDialogFilter>
{
    public string GetFileDialogRepresentation()
    {
        return String.Join("|", this.Select(filter => filter.GetFileDialogRepresentation()));
    }
}

Uso:

FileDialogFilter filterImage = new FileDialogFilter("Image Files", "*.jpeg", "*.bmp");
FileDialogFilter filterOffice = new FileDialogFilter("Office Files", "*.doc", "*.xls", "*.ppt");

FileDialogFilterCollection filters = new FileDialogFilterCollection
{
    filterImage,
    filterOffice
};

OpenFileDialog fileDialog = new OpenFileDialog
{
    Filter = filters.GetFileDialogRepresentation()
};

fileDialog.ShowDialog();
Yusuf Tarık Günaydın
fonte
3

Para corresponder a uma lista de diferentes categorias de arquivo, você pode usar o filtro assim:

        var dlg = new Microsoft.Win32.OpenFileDialog()
        {
            DefaultExt = ".xlsx",
            Filter = "Excel Files (*.xls, *.xlsx)|*.xls;*.xlsx|CSV Files (*.csv)|*.csv"
        };
Kreshnik
fonte
1

Isso é extremo, mas criei um filtro dinâmico orientado a banco de dados usando uma tabela de banco de dados de 2 colunas denominada FILE_TYPES, com os nomes de campo EXTENSION e DOCTYPE:

---------------------------------
| EXTENSION  |  DOCTYPE         |
---------------------------------
|   .doc     |  Document        |
|   .docx    |  Document        |
|   .pdf     |  Document        |
|   ...      |  ...             |
|   .bmp     |  Image           |
|   .jpg     |  Image           |
|   ...      |  ...             |
---------------------------------

Obviamente, eu tinha muitos tipos e extensões diferentes, mas estou simplificando para este exemplo. Aqui está a minha função:

    private static string GetUploadFilter()
    {
        // Desired format:
        // "Document files (*.doc, *.docx, *.pdf)|*.doc;*.docx;*.pdf|"
        // "Image files (*.bmp, *.jpg)|*.bmp;*.jpg|"

        string filter = String.Empty;
        string nameFilter = String.Empty;
        string extFilter = String.Empty;

        // Used to get extensions
        DataTable dt = new DataTable();
        dt = DataLayer.Get_DataTable("SELECT * FROM FILE_TYPES ORDER BY EXTENSION");

        // Used to cycle through doctype groupings ("Images", "Documents", etc.)
        DataTable dtDocTypes = new DataTable();
        dtDocTypes = DataLayer.Get_DataTable("SELECT DISTINCT DOCTYPE FROM FILE_TYPES ORDER BY DOCTYPE");

        // For each doctype grouping...
        foreach (DataRow drDocType in dtDocTypes.Rows)
        {
            nameFilter = drDocType["DOCTYPE"].ToString() + " files (";

            // ... add its associated extensions
            foreach (DataRow dr in dt.Rows)
            {
                if (dr["DOCTYPE"].ToString() == drDocType["DOCTYPE"].ToString())
                {
                    nameFilter += "*" + dr["EXTENSION"].ToString() + ", ";
                    extFilter += "*" + dr["EXTENSION"].ToString() + ";";
                }                    
            }

            // Remove endings put in place in case there was another to add, and end them with pipe characters:
            nameFilter = nameFilter.TrimEnd(' ').TrimEnd(',');
            nameFilter += ")|";
            extFilter = extFilter.TrimEnd(';');
            extFilter += "|";

            // Add the name and its extensions to our main filter
            filter += nameFilter + extFilter;

            extFilter = ""; // clear it for next round; nameFilter will be reset to the next DOCTYPE on next pass
        }

        filter = filter.TrimEnd('|');
        return filter;
    }

    private void UploadFile(string fileType, object sender)
    {            
        Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
        string filter = GetUploadFilter();
        dlg.Filter = filter;

        if (dlg.ShowDialog().Value == true)
        {
            string fileName = dlg.FileName;

            System.IO.FileStream fs = System.IO.File.OpenRead(fileName);
            byte[] array = new byte[fs.Length];

            // This will give you just the filename
            fileName = fileName.Split('\\')[fileName.Split('\\').Length - 1];
            ...

Deve gerar um filtro parecido com este:

insira a descrição da imagem aqui

vapcguy
fonte
Downvoter, gostaria de explicar? Você tem uma ideia melhor? Os meus trabalhos, como demonstrei através de um gráfico.
vapcguy
2
Filter="Document files (*.doc,*.docx,*.pdf)|*.doc;*.docx,*.pdf|Image files (*.bmp,*.jpg)|*.bmp;*.jpg";e isso deve gerar um filtro parecido com a última imagem na resposta acima.
Mjb # 9/17
@ mjb Se você olhasse para a minha resposta, veria que eu já tinha isso no comentário na parte superior do código. Se não desse certo, eu não teria o gráfico para provar que funciona. Como expliquei, o código pega valores de uma tabela de banco de dados e os concatena. Você apenas colocaria o Doctype ("Documents", "Images" etc.) e a Extension como 2 colunas em uma tabela chamada "FILE_TYPES". Supondo que você tivesse uma função chamada DataLayer.Get_DataTable()que pegaria os comandos SQL que eu tenho neste código e lhe enviaria uma DataTable, ela faria tudo por você. Como eu disse, sim, foi extremo, mas funciona.
vapcguy
Sim. mas em ... apenas 10% da sua postagem é a resposta direta à pergunta. Outros 90% são informações extras que não são necessárias para resolver a questão. A pergunta não solicita informações sobre como obter dados do banco de dados e não solicita concatenações ... e bla ... bla ... bla .... mais alguns comandos SQL? ... Tabela de dados? Por que você também não inclui extrair dados dos Serviços da Web ... e demonstrar a análise de string JSON .. ou a conversão de dados XML para obter tipos de arquivo? e também do NoSQL? e Javascript chamando de front-end para back-end para os Tipos de arquivo? .... não ... isso está fora do tópico.
Mjb # 14/17
@ mjb Ponto tomado, mas também para demonstrar o poder desse foreachloop no meio. Você pode ter toneladas de diferentes tipos de documento e extensões dentro deles. Isso serviu como uma maneira de organizá-los e, em seguida, aplique o código para obtê-los. Para mim, era melhor do que apenas supor que havia apenas 3 de cada e fornecer a seqüência de concatenação. Ensine um homem a peixes ....
vapcguy