フィルターをOpenFileDialogに設定して、一般的な画像形式を許可しますか?


229

私はこのコードを持っていますが、どのようにすればすべての一般的な画像フォーマットを受け入れることができますか?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に変更するが、他のタイプの何?

回答:


289

docsから必要なフィルター構文は次のとおりです。

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

つまり、複数の拡張子をセミコロンで区切りImage Files|*.jpg;*.jpeg;*.png;...ます-したがって、。


179

画像ファイルを参照する場合は、次のパターンに従います。

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

6
おそらく、パイプ文字の前後、およびフィルター部分のセミコロンとアスタリスクの間のスペースを取り除きたいでしょう。しかし、そうでなければ良い。
vapcguy 2016年

この方法で任意のファイルタイプをグループ化することもできます。いいね!
アルパー、

74

以下は、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", "*.*")

そしてそれは次のようになります:

ここに画像の説明を入力してください


このアプローチの利点:サポートされている画像タイプの.NETへの将来の追加に対応します。ありがとう
UuDdLrLrSs

私はこれが大好きなので、世界で最も嫌なワンライナーに変えました!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}")}ああ、そうです。VB、あなたがいなくて
寂しい

46

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

23

画像ファイルをフィルタリングするには、次のコードサンプルを使用します。

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

トムファウストの答えが一番好きです。これが彼のソリューションのC#バージョンですが、少し単純化しています。

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

11

画像の場合、GDI(System.Drawing)から利用可能なコーデックを取得し、そこから少しの作業でリストを作成できます。これが最も柔軟な方法です。

ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();

5
このヒントをありがとう!私はこれらを追加し、それは魅力のように機能しました: var imageExtensions = string.Join(";", ImageCodecInfo.GetImageDecoders().Select(ici => ici.FilenameExtension)); dialog.Filter = string.Format("Images|{0}|All Files|*.*", imageExtensions);
アトランティス2014

コメントで複数行のコードブロックを実行する方法がわからない:|
アトランティス2014

1
原作者ではありません:)
アトランティス

9

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

4

ここで毎回構文を覚えておきたくない人のために、簡単なカプセル化があります:

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

3

ファイルのさまざまなカテゴリのリストを照合するには、次のようなフィルタを使用できます。

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

1

これは極端ですが、フィールド名がEXTENSIONおよびDOCTYPEのFILE_TYPESという名前の2列のデータベーステーブルを使用して、動的なデータベース駆動型フィルターを作成しました。

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

次のようなフィルターが生成されます。

ここに画像の説明を入力してください


ダウンボーター、説明してもいい?あなたはより良いアイデアを持っていますか?私がグラフィックを通して示したように、鉱山は機能します。
vapcguy 2017

2
Filter="Document files (*.doc,*.docx,*.pdf)|*.doc;*.docx,*.pdf|Image files (*.bmp,*.jpg)|*.bmp;*.jpg";これにより、上記の回答の最後の画像のようなフィルターが生成されます。
mjb 2017年

@mjb私の答えを見ると、コードの上部にあるコメントにすでにそれが含まれていることがわかります。それがうまくいかない場合、私はそれがうまくいくことを証明するグラフィックを持っていません。すでに説明したように、コードはデータベーステーブルから値を取得し、それらを連結します。Doctype(「Documents」、「Images」など)とExtensionを「FILE_TYPES」というテーブルの2つの列として配置するだけです。DataLayer.Get_DataTable()このコードに含まれているSQLコマンドを受け取り、DataTableを返す関数が呼び出されたとすると、それですべてが実行されます。私が言ったように、はい、極端でしたが、それは機能します。
vapcguy 2017年

はい。しかし、em ...あなたの投稿の10%だけが質問への直接の回答です。他の90%は、質問を解決するために必要ではない追加情報です。質問は、データベースからのデータの取得に関する情報を要求せず、連結についても質問しませんでした...そしてbla ... bla ... bla ....さらにいくつかのSQLコマンド?... データ表?Webサービスからのデータのプルも含めて、JSON文字列の解析や、XMLデータ変換を実行してファイルタイプを取得してみませんか?そしてまたNoSQLから?ファイルタイプのフロントエンドからバックエンドへのJavascript呼び出し?....いいえ...それはトピック外です。
mjb 2017年

@mjbポイントを取るが、それはまた、そのforeachループの真ん中の力を示すためでもある。さまざまなdoctypeのTONSがあり、その中に拡張機能がある場合があります。これは、それらを整理し、コードを適用して取得する方法として機能しました。私にとっては、それぞれ3つしかないと想定して連結文字列を提供するよりも優れていました。男に釣りを教える...
vapcguy 2017年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.