Vraag bepalen of bestand een afbeelding is


Ik loop door een map en kopieer alle bestanden. Op dit moment ben ik aan het doen string.EndsWith controleert voor ".jpg" of ".png", enz . .

Is er een elegantere manier om te bepalen of een bestand een afbeelding is (elk afbeeldingstype) zonder de hacky-check zoals hierboven?


34
2018-03-22 04:17


oorsprong


antwoorden:


Controleer het bestand voor een bekende header. (Info van link ook genoemd in dit antwoord)

De eerste acht bytes van een PNG-bestand bevatten altijd de volgende (decimale) waarden: 137 80 78 71 13 10 26 10


28
2018-03-22 04:22



Uitchecken System.IO.Path.GetExtension

Hier is een snel voorbeeld.

public static readonly List<string> ImageExtensions = new List<string> { ".JPG", ".JPE", ".BMP", ".GIF", ".PNG" };

private void button_Click(object sender, RoutedEventArgs e)
{
    var folder = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
    var files = Directory.GetFiles(folder);
    foreach(var f in files)
    {
        if (ImageExtensions.Contains(Path.GetExtension(f).ToUpperInvariant()))
        {
            // process image
        }
    }
}

22
2018-03-22 04:23



Hiermee worden de eerste paar bytes van een bestand bekeken en wordt bepaald of het een afbeelding is.

using System.Collections.Generic;
using System.IO;
using System.Linq;

public static class Extension
{
    public static bool IsImage(this Stream stream)
    {
        stream.Seek(0, SeekOrigin.Begin);

        List<string> jpg = new List<string> { "FF", "D8" };
        List<string> bmp = new List<string> { "42", "4D" };
        List<string> gif = new List<string> { "47", "49", "46" };
        List<string> png = new List<string> { "89", "50", "4E", "47", "0D", "0A", "1A", "0A" };
        List<List<string>> imgTypes = new List<List<string>> { jpg, bmp, gif, png };

        List<string> bytesIterated = new List<string>();

        for (int i = 0; i < 8; i++)
        {
            string bit = stream.ReadByte().ToString("X2");
            bytesIterated.Add(bit);

            bool isImage = imgTypes.Any(img => !img.Except(bytesIterated).Any());
            if (isImage)
            {
                return true;
            }
        }

        return false;
    }
}

Bewerk

Ik heb een paar wijzigingen aangebracht in het bovenstaande om u toe te staan ​​uw eigen afbeeldingen toe te voegen als dat nodig was, verwijderde ook verzamelingen die niet noodzakelijk waren om mee te beginnen. Ik heb ook een overbelasting toegevoegd die een accepteert out parameter van het type string, de waarde instellen op het type afbeelding waaruit de stream bestaat.

public static class Extension
{
    static Extension()
    {
        ImageTypes = new Dictionary<string, string>();
        ImageTypes.Add("FFD8","jpg");
        ImageTypes.Add("424D","bmp");
        ImageTypes.Add("474946","gif");
        ImageTypes.Add("89504E470D0A1A0A","png");
    }

    /// <summary>
    ///     <para> Registers a hexadecimal value used for a given image type </para>
    ///     <param name="imageType"> The type of image, example: "png" </param>
    ///     <param name="uniqueHeaderAsHex"> The type of image, example: "89504E470D0A1A0A" </param>
    /// </summary>
    public static void RegisterImageHeaderSignature(string imageType, string uniqueHeaderAsHex)
    {
        Regex validator = new Regex(@"^[A-F0-9]+$", RegexOptions.CultureInvariant);

        uniqueHeaderAsHex = uniqueHeaderAsHex.Replace(" ", "");

        if (string.IsNullOrWhiteSpace(imageType))         throw new ArgumentNullException("imageType");
        if (string.IsNullOrWhiteSpace(uniqueHeaderAsHex)) throw new ArgumentNullException("uniqueHeaderAsHex");
        if (uniqueHeaderAsHex.Length % 2 != 0)            throw new ArgumentException    ("Hexadecimal value is invalid");
        if (!validator.IsMatch(uniqueHeaderAsHex))        throw new ArgumentException    ("Hexadecimal value is invalid");

        ImageTypes.Add(uniqueHeaderAsHex, imageType);
    }

    private static Dictionary<string, string> ImageTypes;

    public static bool IsImage(this Stream stream)
    {
        string imageType;
        return stream.IsImage(out imageType);
    }

    public static bool IsImage(this Stream stream, out string imageType)
    {
        stream.Seek(0, SeekOrigin.Begin);
        StringBuilder builder = new StringBuilder();
        int largestByteHeader = ImageTypes.Max(img => img.Value.Length);

        for (int i = 0; i < largestByteHeader; i++)
        {
            string bit = stream.ReadByte().ToString("X2");
            builder.Append(bit);

            string builtHex = builder.ToString();
            bool isImage = ImageTypes.Keys.Any(img => img == builtHex);
            if (isImage)
            {
                imageType = ImageTypes[builder.ToString()];
                return true;
            }
        }
        imageType = null;
        return false;
    }
}

14
2017-08-26 15:19



We kunnen image- en grafische klassen gebruiken vanuit de namespace System.Drawing; om ons werk te doen. Als de code zonder fouten werkt, is het een afbeelding, anders niet. Dat wil zeggen, laat het DotNet-framework het werk voor ons doen. De code -

public string CheckFile(file)
{
    string result="";
    try
    {
        System.Drawing.Image imgInput = System.Drawing.Image.FromFile(file);
        System.Drawing.Graphics gInput = System.Drawing.Graphics.fromimage(imgInput);  
        Imaging.ImageFormat thisFormat = imgInput.RawFormat;   
        result="It is image";        
    }
    catch(Exception ex)
    {
        result="It is not image"; 
    }
    return result;
}

11
2017-07-05 11:40



System.Web.MimeMapping.GetMimeMapping(filename).StartsWith("image/");

MimeMapping.GetMimeMapping produceert deze resultaten:

  • file.jpg: image / jpeg
  • bestand.gif: afbeelding / gif
  • file.jpeg: image / jpeg
  • file.png: image / png
  • file.bmp: image / bmp
  • file.tiff: afbeelding / tiff
  • file.svg: application / octet-stream

file.svg geen afbeelding retourneert / MIME-type werkt in de meeste gevallen omdat u waarschijnlijk geen vectorafbeelding gaat verwerken zoals een scalaire afbeelding. Let er bij het controleren van het MIME-type op dat SVG het standaard MIME-type image / svg + xml heeft, ook als GetMimeMapping retourneert het niet.


10
2018-06-08 23:36



Kijken of deze helpt.

EDIT: Ook Image.FromFile (....). RawFormat kan helpen. Het kan een uitzondering opleveren als het bestand geen afbeelding is.


5
2018-03-22 04:36



Ik gebruik de volgende methode. Het gebruikt de ingebouwde Image-decoder om een ​​lijst met extensies op te halen die door het systeem worden herkend als afbeeldingsbestanden en vergelijkt vervolgens die extensies met de extensie van de bestandsnaam die u doorgeeft. Retourneert een eenvoudig WAAR / ONWAAR.

public static bool IsRecognisedImageFile(string fileName)
{
    string targetExtension = System.IO.Path.GetExtension(fileName);
    if (String.IsNullOrEmpty(targetExtension))
        return false;
    else
        targetExtension = "*" + targetExtension.ToLowerInvariant();

    List<string> recognisedImageExtensions = new List<string>();

    foreach (System.Drawing.Imaging.ImageCodecInfo imageCodec in System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders())
        recognisedImageExtensions.AddRange(imageCodec.FilenameExtension.ToLowerInvariant().Split(";".ToCharArray()));

    foreach (string extension in recognisedImageExtensions)
    {
        if (extension.Equals(targetExtension))
        {
            return true;
        }
    }
    return false;
}

4
2018-06-05 08:21