Impostare il filtro su OpenFileDialog per consentire i formati di immagine tipici?


229

Ho questo codice, come posso consentirgli di accettare tutti i formati di immagine tipici? PNG, JPEG, JPG, GIF?

Ecco cosa ho finora:

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. :)
    }             
}

Si noti che il filtro è impostato su file .txt. Ho potuto cambiare in PNG, ma quello degli altri tipi?

Risposte:


289

Dai documenti , la sintassi del filtro che ti serve è la seguente:

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

cioè separare più estensioni con una virgola - quindi, Image Files|*.jpg;*.jpeg;*.png;....


179

Segui questo schema se cerchi file di immagini:

dialog.Filter =  "Image files (*.jpg, *.jpeg, *.jpe, *.jfif, *.png) | *.jpg; *.jpeg; *.jpe; *.jfif; *.png";

6
Probabilmente vuoi sbarazzarti degli spazi prima e dopo il carattere pipe e tra il punto e virgola e l'asterisco nella porzione di filtro. Ma bene, altrimenti.
vapcguy,

Puoi anche raggruppare qualsiasi tipo di file in questo modo. Bello!
Alper,

74

Ecco un esempio del suggerimento ImageCodecInfo (in 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 sembra così:

inserisci qui la descrizione dell'immagine


Vantaggi di questo approccio: sarà al passo con eventuali aggiunte future di tipi di immagini supportate a .NET. Grazie
UuDdLrLrSs

Lo adoro così tanto che l'ho convertito nel one-liner più disgustoso del mondo! 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 sì. VB, mi manchi qualche volta
Westonsupermare

46

La soluzione completa in C # è qui:

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  
    }
} 

23

Per filtrare i file di immagini, utilizzare questo esempio di codice.

//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
   ....
}

14

Mi piace la risposta di Tom Faust al meglio. Ecco una versione C # della sua soluzione, ma semplifica un po 'le cose.

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

11

Per le immagini, potresti ottenere i codec disponibili da GDI (System.Drawing) e creare la tua lista da quello con un po 'di lavoro. Questo sarebbe il modo più flessibile di andare.

ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();

5
Grazie per questo consiglio! Ho aggiunto questi e ha funzionato come per incanto: var imageExtensions = string.Join(";", ImageCodecInfo.GetImageDecoders().Select(ici => ici.FilenameExtension)); dialog.Filter = string.Format("Images|{0}|All Files|*.*", imageExtensions);
atlantis,

ugh ... non so come fare blocchi di codice multilinea in un commento: |
atlantis,

1
Non l'autore originale :)
atlantis,

9

Solo un necrocomment per l'utilizzo di 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()));

4

Per coloro che non vogliono ricordare la sintassi ogni volta ecco un semplice incapsulamento:

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();

3

Per abbinare un elenco di diverse categorie di file, è possibile utilizzare il filtro in questo modo:

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

1

Questo è estremo, ma ho creato un filtro dinamico basato su database usando una tabella di database a 2 colonne denominata FILE_TYPES, con i nomi dei campi EXTENSION e DOCTYPE:

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

Ovviamente avevo molti tipi ed estensioni diversi, ma lo sto semplificando per questo esempio. Ecco la mia funzione:

    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];
            ...

Dovrebbe produrre un filtro simile al seguente:

inserisci qui la descrizione dell'immagine


Downvoter, ti interessa spiegare? Hai un'idea migliore? Il mio funziona, come ho dimostrato attraverso una grafica.
vapcguy,

2
Filter="Document files (*.doc,*.docx,*.pdf)|*.doc;*.docx,*.pdf|Image files (*.bmp,*.jpg)|*.bmp;*.jpg";e questo dovrebbe produrre un filtro che assomiglia all'ultima immagine nella risposta sopra.
mjb,

@mjb Se guardassi la mia risposta, vedresti che l'avevo già nel commento nella parte superiore del codice. Se non funzionasse, non avrei la grafica per dimostrare che funziona. Come ho spiegato, il codice prende i valori da una tabella del database e li concatena. Inseriresti Doctype ("Documenti", "Immagini", ecc.) E l'estensione come 2 colonne su una tabella chiamata "FILE_TYPES". Supponendo che tu avessi una funzione chiamata DataLayer.Get_DataTable()che prendesse i comandi SQL che ho in questo codice e ti rispedisse una DataTable, farebbe tutto per te. Come ho detto, sì, è stato estremo, ma funziona.
vapcguy,

Sì. ma em ... solo il 10% dei tuoi post è la risposta diretta alla domanda. Altro 90% sono informazioni aggiuntive che non sono necessarie per risolvere la domanda. La domanda non richiede informazioni su come ottenere dati dal database e non ha chiesto informazioni sui concatenati ... e bla ... bla ... bla .... qualche altro comando SQL? ... Tabella dati? Perché non includere anche l'estrazione di dati dai servizi Web ... e dimostrare l'analisi delle stringhe JSON ... o la conversione di dati XML per ottenere i tipi di file? e anche da NoSQL? e Javascript che chiama dal front-end al back-end per i tipi di file? .... no ... questo è fuori tema.
mjb,

@mjb Punto preso, ma è anche per dimostrare la potenza di quel foreachloop nel mezzo. Potresti avere tonnellate di diversi tipi di documento ed estensioni al loro interno. Questo è servito come un modo per organizzarli, quindi applicare il codice per ottenerli. Per me, era meglio che supporre che ce ne fossero solo 3 per ciascuno e dare la stringa di concatenazione. Insegna a un uomo a pescare ....
vapcguy,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.