242

I have this code, how can I allow it to accept all typical image formats? PNG, JPEG, JPG, GIF?

Here's what I have so far:

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

Notice that the filter is set to .txt files. I could change to PNG, but what of the other types?

CDspace
  • 2,551
  • 17
  • 31
  • 35
Sergio Tapia
  • 36,466
  • 70
  • 175
  • 253

12 Answers12

304

From the docs, the filter syntax that you need is as follows:

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

i.e. separate the multiple extensions with a semicolon -- thus, Image Files|*.jpg;*.jpeg;*.png;....

Sebastian Brosch
  • 37,059
  • 14
  • 61
  • 73
itowlson
  • 70,780
  • 16
  • 153
  • 151
186

Follow this pattern if you browsing for image files:

dialog.Filter =  "Image files (*.jpg, *.jpeg, *.jpe, *.jfif, *.png) | *.jpg; *.jpeg; *.jpe; *.jfif; *.png";
Devam Mehta
  • 1,911
  • 1
  • 10
  • 3
  • 9
    Probably want to get rid of the spaces before and after the pipe character and between the semi-colon and asterisk in the filter portion. But good, otherwise. – vapcguy Oct 04 '16 at 14:46
  • You can also group any file type with this way. Nice! – Alper May 21 '19 at 13:48
78

Here's an example of the ImageCodecInfo suggestion (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", "*.*")

And it looks like this:

enter image description here

StayOnTarget
  • 7,829
  • 8
  • 42
  • 59
Tom Faust
  • 1,315
  • 10
  • 11
  • Benefit of this approach: it will keep up with any future additions of supported image types to .NET. Thanks – StayOnTarget Mar 28 '19 at 12:44
  • 2
    I love this so much that I've converted it into the world's most disgusting one-liner! `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, yes. VB, I miss you sometimes – Westonsupermare May 16 '20 at 05:50
46

Complete solution in C# is here:

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  
    }
} 
DmitryBoyko
  • 32,983
  • 69
  • 281
  • 458
25

To filter images files, use this code sample.

//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
  • 251
  • 3
  • 4
15

I like Tom Faust's answer the best. Here's a C# version of his solution, but simplifying things a bit.

var codecs = ImageCodecInfo.GetImageEncoders(); 
var codecFilter = "Image Files|"; 
foreach (var codec in codecs) 
{
    codecFilter += codec.FilenameExtension + ";"; 
} 
dialog.Filter = codecFilter;
NielW
  • 3,082
  • 1
  • 25
  • 34
11

For images, you could get the available codecs from GDI (System.Drawing) and build your list from that with a little work. This would be the most flexible way to go.

ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
Muad'Dib
  • 26,680
  • 5
  • 52
  • 68
  • 5
    Thanks for this tip! I added these and it worked like a charm: `var imageExtensions = string.Join(";", ImageCodecInfo.GetImageDecoders().Select(ici => ici.FilenameExtension));` `dialog.Filter = string.Format("Images|{0}|All Files|*.*", imageExtensions);` – atlantis Feb 25 '14 at 02:21
  • ugh...not sure how to do multi-line code blocks in a comment :| – atlantis Feb 25 '14 at 02:24
  • 1
    Not the original author :) – atlantis Oct 19 '16 at 00:15
9

Just a necrocomment for using string.Join and 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

For those who don't want to remember the syntax everytime here is a simple encapsulation:

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

Usage:

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
  • 2,698
  • 2
  • 23
  • 38
4

In order to match a list of different categories of file, you can use the filter like this:

        var dlg = new Microsoft.Win32.OpenFileDialog()
        {
            DefaultExt = ".xlsx",
            Filter = "Excel Files (*.xls, *.xlsx)|*.xls;*.xlsx|CSV Files (*.csv)|*.csv"
        };
Kreshnik
  • 2,201
  • 5
  • 28
  • 37
1

This is extreme, but I built a dynamic, database-driven filter using a 2 column database table named FILE_TYPES, with field names EXTENSION and DOCTYPE:

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

Obviously I had many different types and extensions, but I'm simplifying it for this example. Here is my function:

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

Should yield a filter that looks like this:

enter image description here

vapcguy
  • 5,607
  • 1
  • 45
  • 43
  • Downvoter, care to explain? You have a better idea? Mine works, as I demonstrated through a graphic. – vapcguy Jul 19 '17 at 15:46
  • 2
    `Filter="Document files (*.doc,*.docx,*.pdf)|*.doc;*.docx,*.pdf|Image files (*.bmp,*.jpg)|*.bmp;*.jpg";` and this should yield a filter that looks like the last picture in the answer above. – mjb Oct 09 '17 at 03:21
  • @mjb If you looked at my answer, you'd see I already had that in the comment at the top of the code. If it didn't work, I wouldn't have the graphic to prove that it does. As I explained, the code takes values from a database table & concatenates them. You would just put the Doctype ("Documents", "Images", etc.) and the Extension as 2 columns on a table called "FILE_TYPES". Assuming you had a function called `DataLayer.Get_DataTable()` that would take the SQL commands I have in this code & send you back a DataTable, it would do everything for you. As I said, yes, was extreme, but it does work. – vapcguy Oct 13 '17 at 00:56
  • Yes. but em... only 10% of your post is the direct answer to the question. Other 90% is extra information which is not necessary to solve the question. The question does not request information about getting data from database and did not ask about concatenates... and bla... bla...bla.... some more SQL commands? ... DataTable? Why don't you also include pulling data from Web Services... and demonstrate JSON string parsing.. or XML data conversion to get File Types? and also from NoSQL? and Javascript calling from front end to back end for the File Types?.... no... that is out of the topic. – mjb Oct 14 '17 at 05:17
  • @mjb Point taken, but it's also to demonstrate the power of that `foreach` loop in the middle. You might have TONS of different doctypes, and extensions within them. This served as a way to organize them, then apply code to get them. For me, it was better than just assuming there were only 3 of each and giving the concatenation string. Teach a man to fish.... – vapcguy Oct 14 '17 at 07:02
0

You must include all image type extensions and allow for all files as an option.

All Files|.|All images|.jpg;.jpeg;.png;.gif;.tif;.bmp|JPEG Images|.jpg|PNG Images|.png";