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