2013-07-19 10 views
18

Ich habe diese Dateitypen Filters:gute Möglichkeit zu überprüfen, ob Dateierweiterung eines Bildes ist oder nicht

public const string Png = "PNG Portable Network Graphics (*.png)|" + "*.png"; 
    public const string Jpg = "JPEG File Interchange Format (*.jpg *.jpeg *jfif)|" + "*.jpg;*.jpeg;*.jfif"; 
    public const string Bmp = "BMP Windows Bitmap (*.bmp)|" + "*.bmp"; 
    public const string Tif = "TIF Tagged Imaged File Format (*.tif *.tiff)|" + "*.tif;*.tiff"; 
    public const string Gif = "GIF Graphics Interchange Format (*.gif)|" + "*.gif"; 
    public const string AllImages = "Image file|" + "*.png; *.jpg; *.jpeg; *.jfif; *.bmp;*.tif; *.tiff; *.gif"; 
    public const string AllFiles = "All files (*.*)" + "|*.*"; 

    static FilesFilters() 
    { 
     imagesTypes = new List<string>(); 
     imagesTypes.Add(Png); 
     imagesTypes.Add(Jpg); 
     imagesTypes.Add(Bmp); 
     imagesTypes.Add(Tif); 
     imagesTypes.Add(Gif); 
    } 

OBS: Gibt es eine Standardfilter in .NET oder eine freie Bibliothek für das?

Ich brauche eine statische Methode, die überprüft, ob eine Zeichenfolge ein Bild ist oder nicht. Wie würdest du das lösen?

//ext == Path.GetExtension(yourpath) 
    public static bool IsImageExtension(string ext) 
    { 
     return (ext == ".bmp" || .... etc etc...) 
    } 

Lösung mit Jeroen Vannevel EndsWith. Ich denke es ist ok.

public static bool IsImageExtension(string ext) 
    { 
     return imagesTypes.Contains(ext); 
    } 
+3

Vielleicht wollen Sie auch [MIME-Typ Erkennung] tun es zu prüfen, durch (http://stackoverflow.com/questions/15300567/ alternative-to-findmimefromdata-methode-in-urlmon-dll-one-die-hat-mehr-mime-type), es ist mehr "vertrauenswürdig", dass die Dateierweiterung, –

Antwort

12

Sie könnten .endsWith(ext) verwenden. Es ist jedoch keine sehr sichere Methode: Ich könnte "bla.jpg" in "bla.png" umbenennen und es wäre immer noch eine jpg-Datei.

public static bool HasImageExtension(this string source){ 
return (source.EndsWith(".png") || source.EndsWith(".jpg")); 
} 

This bietet eine sichere Lösung:

string InputSource = "mypic.png"; 
System.Drawing.Image imgInput = System.Drawing.Image.FromFile(InputSource); 
Graphics gInput = Graphics.fromimage(imgInput); 
Imaging.ImageFormat thisFormat = imgInput.rawformat; 
+0

"Ich könnte" bla.jpg "in" bla umbenennen .png 'und es wäre immer noch eine jpg-Datei "Ja, ich weiß das, aber das führt zu einem anderen Problem ... Ich denke, ich werde damit gehen, weil alle Bilder als Bitmap-Objekt geladen werden. endsWith ist schön. – Pedro77

+0

Schauen Sie mein Was denkst du? – Pedro77

+0

Wenn du eine Liste der erlaubten Bildtypen hast, benutze 'return imageTypes.Contains (ext);' in Übereinstimmung mit @ Alejandros Beispiel. –

4

Eine Option, um eine Liste aller möglichen gültigen Bild Erweiterungen zu haben wäre, dann würde das Verfahren nur prüfen, ob die mitgelieferte Verlängerung ist innerhalb dieser Sammlung :

private static readonly HashSet<string> validExtensions = new HashSet<string>() 
{ 
    "png", 
    "jpg", 
    "bmp" 
    // Other possible extensions 
}; 

Dann in der Validierung prüfen Sie nur gegen das:

public static bool IsImageExtension(string ext) 
{ 
    return validExtensions.Contains(ext); 
} 
+0

Gute zusätzliche Informationen finden Sie hier http://StackOverflow.com/Questions/4558754/define-what-is-Ahashset –

+0

Beachten Sie, dass dies nur mit allen Kleinbuchstaben Erweiterungen funktioniert - denken Sie daran, dass Windows-Dateisystem Groß-und Kleinschreibung, aber Der String-Vergleich von C# (standardmäßig) ist nicht möglich. Es ist nicht ungewöhnlich, dass Erweiterungen alle Großbuchstaben sind, z. B. somefile.PNG. Erwägen Sie, 'StringComparer.OrdinalIgnoreCase' zu ​​Ihrem' HashSet' hinzuzufügen, wie es Oliver in [seiner Antwort] getan hat (https://Stackoverflow.com/a/21835675/4975230). – jrh

13
private static readonly string[] _validExtensions = {"jpg","bmp","gif","png"}; // etc 

public static bool IsImageExtension(string ext) 
{ 
    return _validExtensions.Contains(ext); 
} 

Wenn Sie wollen, ohne neu zu kompilieren die Liste konfigurierbar zur Laufzeit machen zu können, fügen Sie so etwas wie:

private static string[] _validExtensions; 

private static string[] ValidExtensions() 
{ 
    if(_validExtensions==null) 
    { 
     // load from app.config, text file, DB, wherever 
    } 
    return _validExtensions 
} 

public static bool IsImageExtension(string ext) 
{ 
    return ValidExtensions().Contains(ext); 
} 
+2

Stellen Sie sicher, dass Sie 'using System.Linq;' verwenden, um Zugriff auf die Erweiterungsmethode 'Contains' zu erhalten. – daniellmb

+0

Beachten Sie, dass dies nur mit allen Erweiterungen in Kleinbuchstaben funktioniert. Denken Sie daran, dass das Dateisystem von Windows nicht zwischen Groß- und Kleinschreibung unterscheidet, der String-Vergleich von C# jedoch nicht. Es ist nicht ungewöhnlich, dass Erweiterungen alle Großbuchstaben sind, z. B. somefile.PNG. [Diese Überladung von Contains kann diese Einschränkung beheben.] (Https://msdn.microsoft.com/en-us/library/bb339118 (v = vs.110) .aspx) Verwenden Sie zum Beispiel 'ValidExtensions(). Enthält (ext, StringComparer.OrdinalIgnoreCase); ', beachten Sie, dass Sie' using System.Linq; 'benötigen, um diese 'Contains'-Überladung auszunutzen. – jrh

+0

@daniellmb nitpicking: Technisch gesehen brauchen Sie LINQ nicht für [List.Contains (T)] (https://msdn.microsoft.com/en-us/library/bhkz42b3 (v = vs.110) .aspx), aber Sie brauchen LINQ für [Enumerable.Contains (diese IEnumerable , T, Comparer)] (https://msdn.microsoft.com/en-us/library/bb339118 (v = vs.110) .aspx), die Die Überladung der letzten Erweiterung würde helfen, einige Probleme im Code in diesem Beitrag zu lösen. – jrh

5

Diese Methode erstellt automatisch einen Filter für die OpenFileDialog. Es verwendet die Informationen der Bild-Decoder, die von Windows unterstützt werden. Es fügt auch Informationen von "unbekannten" Bildformaten hinzu (siehe default Fall der switch Anweisung).

private static string SupportedImageDecodersFilter() 
{ 
    ImageCodecInfo[] encoders = ImageCodecInfo.GetImageEncoders(); 

    string allExtensions = encoders 
     .Select(enc => enc.FilenameExtension) 
     .Aggregate((current, next) => current + ";" + next) 
     .ToLowerInvariant(); 
    var sb = new StringBuilder(500) 
     .AppendFormat("Image files ({0})|{1}", allExtensions.Replace(";", ", "), 
         allExtensions); 
    foreach (ImageCodecInfo encoder in encoders) { 
     string ext = encoder.FilenameExtension.ToLowerInvariant(); 
     // ext = "*.bmp;*.dib;*.rle"   descr = BMP 
     // ext = "*.jpg;*.jpeg;*.jpe;*.jfif" descr = JPEG 
     // ext = "*.gif"      descr = GIF 
     // ext = "*.tif;*.tiff"    descr = TIFF 
     // ext = "*.png"      descr = PNG 

     string caption; 
     switch (encoder.FormatDescription) { 
      case "BMP": 
       caption = "Windows Bitmap"; 
       break; 
      case "JPEG": 
       caption = "JPEG file"; 
       break; 
      case "GIF": 
       caption = "Graphics Interchange Format"; 
       break; 
      case "TIFF": 
       caption = "Tagged Image File Format"; 
       break; 
      case "PNG": 
       caption = "Portable Network Graphics"; 
       break; 
      default: 
       caption = encoder.FormatDescription; 
       break; 
     } 
     sb.AppendFormat("|{0} ({1})|{2}", caption, ext.Replace(";", ", "), ext); 
    } 
    return sb.ToString(); 
} 

es wie folgt verwendet:

var dlg = new OpenFileDialog { 
    Filter = SupportedImageDecodersFilter(), 
    Multiselect = false, 
    Title = "Choose Image" 
}; 

Der obige Code (leicht modifiziert) verwendet werden können, zur Verfügung Bilddateierweiterungen zu finden. Um zu testen, ob eine Dateierweiterung ein Bild bezeichnet, würde ich die gültige Erweiterung in eine HashSet setzen. HashSets haben eine
O (1) Zugriffszeit! Stellen Sie sicher, dass Sie einen Zeichenfolgenvergleich ohne Berücksichtigung der Groß- und Kleinschreibung auswählen. Da die Dateierweiterungen keine akzentuierten oder nicht lateinischen Buchstaben enthalten, kann die Kultur sicher ignoriert werden. Daher verwende ich einen ordinalen Stringvergleich.

var imageExtensions = new HashSet<string>(StringComparer.OrdinalIgnoreCase); 
imageExtensions.Add(".png"); 
imageExtensions.Add(".bmp"); 
... 

und testen, ob ein Dateiname ist ein Bild:

string extension = Path.GetExtension(filename); 
bool isImage = imageExtensions.Contains(extension);