将过滤器设置为OpenFileDialog以允许典型的图像格式?

我有这个代码,我怎么能让它接受所有典型的图像格式?Png, jpeg, jpg, gif ?

以下是我目前所了解到的:

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

注意,过滤器被设置为.txt文件。我可以更改为PNG,但其他类型呢?

465348 次浏览

的文档中,你需要的过滤器语法如下:

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

即,用分号分隔多个扩展名——因此为Image Files|*.jpg;*.jpeg;*.png;...

对于图像,您可以从GDI (System.Drawing)获得可用的编解码器,并通过一些工作来构建您的列表。这将是最灵活的方式。

ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();

下面是一个ImageCodecInfo建议的例子(在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", "*.*")

它是这样的:

enter image description here

完整的c#解决方案在这里:

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

要过滤图像文件,请使用下面的代码示例。

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

只是一个关于使用字符串的necrocomment。Join和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()));

对于那些不想每次都记住语法的人,这里有一个简单的封装:

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

用法:

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

我最喜欢汤姆·浮士德的回答。下面是他的解决方案的c#版本,但简化了一些事情。

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

这是极端的,但是我使用名为FILE_TYPES的2列数据库表构建了一个动态的、数据库驱动的过滤器,字段名为EXTENSION和DOCTYPE:

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

显然,我有许多不同的类型和扩展,但在本例中我将其简化。这是我的函数:

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

应该生成如下所示的过滤器:

enter image description here

为了匹配一个由不同类别的文件组成的列表,你可以像这样使用过滤器:

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

必须包含所有图像类型扩展名,并允许将所有文件作为一个选项。

||所有图片|jpg;.jpeg;. png。.gif;.tif;.bmp|JPEG图片|jpg | | PNG图像.png";

使用此方法返回一个与Filter兼容的字符串,该字符串由ImageCodecInfo构建,支持当前系统能够理解的图像格式。

        /// <summary>
/// Get the Filter string for all supported image types.
/// To be used in the FileDialog class Filter Property.
/// </summary>
/// <returns></returns>
public static string GetImageFilter()
{
string imageExtensions = string.Empty;
string separator = "";
ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
Dictionary<string, string> imageFilters = new Dictionary<string, string>();
foreach (ImageCodecInfo codec in codecs)
{
imageExtensions = $"{imageExtensions}{separator}{codec.FilenameExtension.ToLower()}";
separator = ";";
imageFilters.Add($"{codec.FormatDescription} files ({codec.FilenameExtension.ToLower()})", codec.FilenameExtension.ToLower());
}
string result = string.Empty;
separator = "";
foreach (KeyValuePair<string, string> filter in imageFilters)
{
result += $"{separator}{filter.Key}|{filter.Value}";
separator = "|";
}
if (!string.IsNullOrEmpty(imageExtensions))
{
result += $"{separator}Image files|{imageExtensions}";
}
return result;
}

结果如下所示:

Dialog Filter

写出应用程序需要的类型。(ref FileDialog。过滤器)。这里是所有的最常见的图像格式

private static string GetImageFilter()
{
return
"All Files (*.*)|*.*" +
"|All Pictures (*.emf;*.wmf;*.jpg;*.jpeg;*.jfif;*.jpe;*.png;*.bmp;*.dib;*.rle;*.gif;*.emz;*.wmz;*.tif;*.tiff;*.svg;*.ico)" +
"|*.emf;*.wmf;*.jpg;*.jpeg;*.jfif;*.jpe;*.png;*.bmp;*.dib;*.rle;*.gif;*.emz;*.wmz;*.tif;*.tiff;*.svg;*.ico" +
"|Windows Enhanced Metafile (*.emf)|*.emf" +
"|Windows Metafile (*.wmf)|*.wmf" +
"|JPEG File Interchange Format (*.jpg;*.jpeg;*.jfif;*.jpe)|*.jpg;*.jpeg;*.jfif;*.jpe" +
"|Portable Network Graphics (*.png)|*.png" +
"|Bitmap Image File (*.bmp;*.dib;*.rle)|*.bmp;*.dib;*.rle" +
"|Compressed Windows Enhanced Metafile (*.emz)|*.emz" +
"|Compressed Windows MetaFile (*.wmz)|*.wmz" +
"|Tag Image File Format (*.tif;*.tiff)|*.tif;*.tiff" +
"|Scalable Vector Graphics (*.svg)|*.svg" +
"|Icon (*.ico)|*.ico";
}

示例使用

设置FilterIndex = 2预选“所有图片”。设置openFileDialog.InitialDirectory,除非你有一个很好的理由。

void OpenImageFile()
{
var openFileDialog  = new OpenFileDialog
{
Filter = GetImageFilter(),
FilterIndex = 2,
RestoreDirectory = true
};
DialogResult result = openFileDialog.ShowDialog();


// do something with your file
// bool resultOk = (result == System.Windows.Forms.DialogResult.OK);
// string filePath = openFileDialog.FileName;
// ...
}