2013-07-19 6 views
18

ho questo tipi di file Filtri:buon modo per verificare se l'estensione del file è di un'immagine o no

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: C'è qualche filtri predefiniti in .NET o una libreria libera per questo?

Ho bisogno di un metodo statico che controlli se una stringa è un'immagine o meno. Come risolverebbe questo?

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

Soluzione con Jeroen Vannevel EndsWith. Penso che sia ok.

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

si potrebbe anche prendere in considerazione di farlo entro il [rilevare il tipo MIME] (http://stackoverflow.com/questions/15300567/ alternative-to-findmimefromdata-method-in-urlmon-dll-one-which-has-more-mime-typ), è più "degna di fiducia" che estensione del file, –

risposta

12

È possibile utilizzare .endsWith(ext). Tuttavia, non è un metodo molto sicuro: potrei rinominare "bla.jpg" in "bla.png" e sarebbe comunque un file jpg.

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

This fornisce una soluzione più sicura:

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

"Potrei rinominare 'bla.jpg' in 'bla .png 'e sarebbe ancora un file jpg "Sì, lo so, ma questo porta ad un altro problema ... Penso che lascerò questo perché tutte le immagini verranno caricate come oggetti Bitmap. endsWith è bello. – Pedro77

+0

Look my edit. Cosa ne pensi? – Pedro77

+0

Se hai un elenco di tipi di immagine permessi usa semplicemente 'return imageTypes.Contains (ext);' secondo l'esempio di @ Alejandro. –

4

Un'opzione sarebbe quella di avere un elenco di tutte le possibili estensioni di immagini valide, allora quel metodo sarebbe solo verificare se la prolunga in dotazione è all'interno di tale raccolta :

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

Poi nella convalida basta controllare che contro:

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

Le buone informazioni extra sono qui http://stackoverflow.com/questions/4558754/define-what-is-a-hashset –

+0

Si noti che questo funziona solo con tutte le estensioni minuscole - ricorda che il file system di Windows non fa distinzione tra maiuscole e minuscole, ma Il confronto delle stringhe di C# (di default) non lo è. Non è raro che le estensioni siano tutte maiuscole, ad esempio somefile.PNG. Considera l'aggiunta di 'StringComparer.OrdinalIgnoreCase' al tuo' HashSet' come ha fatto Oliver in [la sua risposta] (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); 
} 

Se si vuole essere in grado di fare l'elenco configurabile in fase di esecuzione senza ricompilare, aggiungere qualcosa come:

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

Assicurati di includere 'using System.Linq;' per accedere al metodo di estensione 'Contains'. – daniellmb

+0

Si noti che questo funziona solo con tutte le estensioni minuscole - ricorda che il file system di Windows non fa distinzione tra maiuscole e minuscole, ma il confronto tra stringhe di C# non lo è. Non è raro che le estensioni siano tutte maiuscole, ad esempio somefile.PNG. [Questo sovraccarico di Contiene può risolvere questa limitazione.] (Https://msdn.microsoft.com/en-us/library/bb339118 (v = vs.110) .aspx) Ad esempio, usare 'ValidExtensions(). Contiene (ext, StringComparer.OrdinalIgnoreCase); ', si noti che è necessario' using System.Linq; 'per trarre vantaggio dall'overload' Contains'. – jrh

+0

@daniellmb nitpicking: tecnicamente non è necessario LINQ per [List.Contains (T)] (https://msdn.microsoft.com/en-us/library/bhkz42b3 (v = vs.110) .aspx), ma è necessario LINQ per [Enumerable.Contains (questo IEnumerable , T, Comparer)] (https://msdn.microsoft.com/en-us/library/bb339118 (v = vs.110) .aspx), il il sovraccarico del metodo di estensione di quest'ultimo potrebbe aiutare a risolvere alcuni problemi nel codice in questo post. – jrh

5

questo metodo crea automaticamente un filtro per la OpenFileDialog. Utilizza le informazioni dei decodificatori di immagine supportati da Windows. Aggiunge inoltre informazioni su formati di immagine "sconosciuti" (vedere il caso default dell'istruzione switch).

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

usare in questo modo:

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

Il codice di cui sopra (leggermente modificato) può essere utilizzato per trovare le estensioni dei file immagine disponibili. Per verificare se una determinata estensione di file denota un'immagine, inserisco l'estensione valida in HashSet. Gli hash hanno un tempo di accesso O (1)! Assicurati di scegliere un comparatore di stringhe senza distinzione tra maiuscole e minuscole. Poiché le estensioni di file non contengono lettere accentate o non latine, la cultura può essere tranquillamente ignorata. Pertanto io uso un confronto di stringhe ordinali.

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

e verificare se il nome del file è l'immagine:

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