web-dev-qa-db-fra.com

C # Comment puis-je tester un fichier jpeg?

En utilisant C #, comment puis-je tester un fichier jpeg? Devrais-je vérifier une extension .jpg?

Merci

28
Scott

Plusieurs options:

Vous pouvez vérifier l'extension du fichier:

static bool HasJpegExtension(string filename)
{
    // add other possible extensions here
    return Path.GetExtension(filename).Equals(".jpg", StringComparison.InvariantCultureIgnoreCase)
        || Path.GetExtension(filename).Equals(".jpeg", StringComparison.InvariantCultureIgnoreCase);
}

ou recherchez le bon nombre magique dans l'en-tête du fichier:

static bool HasJpegHeader(string filename)
{
    using (BinaryReader br = new BinaryReader(File.Open(filename, FileMode.Open, FileAccess.Read)))
    {
        UInt16 soi = br.ReadUInt16();  // Start of Image (SOI) marker (FFD8)
        UInt16 marker = br.ReadUInt16(); // JFIF marker (FFE0) or EXIF marker(FFE1)

        return soi == 0xd8ff && (marker & 0xe0ff) == 0xe0ff;
    }
}

Une autre option serait de charger l'image et de vérifier le type correct. Cependant, ceci est moins efficace (sauf si vous allez charger l’image de toute façon) mais vous donnera probablement le résultat le plus fiable (Soyez conscient du coût supplémentaire du chargement et de la décompression ainsi que de la gestion des exceptions possibles):

static bool IsJpegImage(string filename)
{
    try
    {
        using (System.Drawing.Image img = System.Drawing.Image.FromFile(filename)) 
        {           
            // Two image formats can be compared using the Equals method
            // See http://msdn.Microsoft.com/en-us/library/system.drawing.imaging.imageformat.aspx
            //
            return img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Jpeg);
        }
    }
    catch (OutOfMemoryException)
    {
        // Image.FromFile throws an OutOfMemoryException 
        // if the file does not have a valid image format or
        // GDI+ does not support the pixel format of the file.
        //
        return false;
    }
}
101
Dirk Vollmar

Ouvrez le fichier en tant que flux et recherchez le nombre magique pour JPEG.

Les fichiers d’image JPEG commencent par FF D8 et Se terminent par FF D9. Les fichiers JPEG/JFIF Contiennent le code ASCII pour 'JFIF' (4A 46 49 46) sous la forme d'une chaîne terminée par un caractère nul. Les fichiers JPEG/Exif contiennent le code ASCII pour 'Exif' (45 78 69 66) est également une chaîne terminée par un zéro

28
Simon Gibbs

OMG, Bon nombre de ces exemples de code sont faux, faux faux.

Les fichiers EXIF ​​ont un marqueur de 0xff * e1 *, les fichiers JFIF ont un marqueur de 0xff * e0 *. Ainsi, tout le code reposant sur 0xffe0 pour détecter un fichier JPEG manquera tous les fichiers EXIF. 

Voici une version qui détectera les deux et qui peut facilement être modifiée pour renvoyer uniquement pour JFIF ou uniquement pour EXIF. (Utile pour tenter de récupérer les images de votre iPhone, par exemple).

    public static bool HasJpegHeader(string filename)
    {
        try
        {
            // 0000000: ffd8 ffe0 0010 4a46 4946 0001 0101 0048  ......JFIF.....H
            // 0000000: ffd8 ffe1 14f8 4578 6966 0000 4d4d 002a  ......Exif..MM.*    
            using (BinaryReader br = new BinaryReader(File.Open(filename, FileMode.Open, FileAccess.ReadWrite)))
            {
                UInt16 soi = br.ReadUInt16();  // Start of Image (SOI) marker (FFD8)
                UInt16 marker = br.ReadUInt16(); // JFIF marker (FFE0) EXIF marker (FFE1)
                UInt16 markerSize = br.ReadUInt16(); // size of marker data (incl. marker)
                UInt32 four = br.ReadUInt32(); // JFIF 0x4649464a or Exif  0x66697845

                Boolean isJpeg = soi == 0xd8ff && (marker & 0xe0ff) == 0xe0ff;
                Boolean isExif = isJpeg && four == 0x66697845;
                Boolean isJfif = isJpeg && four == 0x4649464a;

                if (isJpeg) 
                {
                    if (isExif)
                        Console.WriteLine("EXIF: {0}", filename);
                    else if (isJfif)
                        Console.WriteLine("JFIF: {0}", filename);
                    else
                        Console.WriteLine("JPEG: {0}", filename);
                }

                return isJpeg;
                return isJfif;
                return isExif;
            }
        }
        catch
        {
            return false;
        }
    }
25
Orwellophile

Vous pouvez essayer de charger le fichier dans une image, puis vérifier le format.

Image img = Image.FromFile(filePath);
bool isBitmap = img.RawFormat.Equals(ImageFormat.Jpeg);

Vous pouvez également ouvrir le fichier et vérifier l’en-tête pour obtenir le type.

13
Lee

Vous pouvez trouver de la documentation sur le format de fichier jpeg, en particulier les informations d'en-tête. Essayez ensuite de lire ces informations à partir du fichier et de les comparer aux octets d’en-tête jpeg attendus.

4
Brian Ensink

Lire les octets d'en-tête. Cet article contient des informations sur plusieurs formats d'image courants, notamment JPEG:

Utilisation des en-têtes de fichier image pour vérifier le format de l'image

Informations d'en-tête JPEG

3
Mitch Wheat

Une fois que vous avez l'extension, vous pouvez utiliser une expression régulière pour la valider.

^.*\.(jpg|JPG)$
1
Shaun Humphries

Cela fera une boucle sur chaque fichier du répertoire courant et sortira si tous les fichiers trouvés avec l'extension JPG ou JPEG sont des images Jpeg.

      foreach (FileInfo f in new DirectoryInfo(".").GetFiles())
        {
            if (f.Extension.ToUpperInvariant() == ".JPG"
                || f.Extension.ToUpperInvariant() == ".JPEG")
            {
                Image image = Image.FromFile(f.FullName);

                if (image.RawFormat == ImageFormat.Jpeg)
                {
                    Console.WriteLine(f.FullName + " is a Jpeg image");
                }
            }
        }
1
Armbrat

En fonction du contexte dans lequel vous consultez ce fichier, vous devez vous rappeler que vous ne pouvez pas l'ouvrir avant que l'utilisateur vous l'ait dit.

(Le lien est vers une entrée de blog de Raymond Chen.)

1
Dave Webb

Vous pouvez utiliser la méthode Path.GetExtension .

0
Galwegian

Le code ici:

http://mark.michaelis.net/Blog/RetrievingMetaDataFromJPEGFilesUsingC.aspx

Vous montre comment obtenir les métadonnées. Je suppose que cela jetterait une exception si votre image n'était pas un JPEG valide.

0
Program.X

Vérifier l'extension du fichier n'est pas suffisant car le nom du fichier est peut-être en train de mentir.

Une méthode rapide et délicate consiste à charger l'image à l'aide de la classe Image et d'attraper les exceptions suivantes:

Image image = Image.FromFile(@"c:\temp\test.jpg");

Ce n'est pas idéal car vous pouvez obtenir n'importe quel type d'exception, telle que OutOfMemoryException, FileNotFoundException, etc., etc.

Le moyen le plus complet consiste à traiter le fichier en tant que fichier binaire et à vous assurer que l'en-tête correspond au format JPG. Je suis sûr que c'est décrit quelque part.

0
Steve Dunn

La meilleure façon d'essayer de créer une image à partir de celle-ci à l'aide du constructeur Drawing.Bitmap (string) et de voir s'il échoue ou génère une exception. Le problème avec certaines des réponses est le suivant: premièrement, l’extension est purement arbitraire, elle peut être jpg, jpeg, jpe, bob, tim, peu importe. Deuxièmement, utiliser l'en-tête ne suffit pas pour être sûr à 100%. Il peut certainement déterminer qu'un fichier n'est pas un fichier jpeg, mais ne peut pas garantir qu'un fichier est un fichier jpeg. Un fichier binaire arbitraire pourrait avoir la même séquence d'octets au début. 

0
Skizz

Il suffit de prendre le type de support du fichier et de vérifier:

private bool isJpeg()
        {
string p = currFile.Headers.ContentType.MediaType;
            return p.ToLower().Equals("image/jpeg") || p.ToLower().Equals("image/pjpeg") || p.ToLower().Equals("image/png");
        }
0
mns
System.Web.MimeMapping.GetMimeMapping(filename).StartsWith("image/");
MimeMapping.GetMimeMapping produces these results:

file.jpg: image/jpeg
file.gif: image/gif
file.jpeg: image/jpeg
file.png: image/png
file.bmp: image/bmp
file.tiff: image/tiff
file.svg: application/octet-stream
0
user3387978

après vérification de l'extension du fichier lu, lire les quatre premiers octets de l'image et les deux derniers octets de l'image, faites-le pour les deux derniers octets de la valeur 255, 217 pour les autres fichiers, vous pouvez le faire Validez l'image du fichier en C #http://www.garykessler.net/library/file_sigs.html

// after check extention of file
byte[] ValidFileSignture = new byte[] { 255, 216, 255, 224 };
byte[] bufferforCheck = new byte[ValidFileSignture.Length];
Stream _inputStream = file.InputStream;
byte[] bufferforCheck1 = new byte[] { 255, 216, 255, 224 };
_inputStream.Read(bufferforCheck, 0, ValidFileSignture.Length);
if (!Enumerable.SequenceEqual(bufferforCheck, ValidFileSignture))
{
    //file OK
}
0
hmfarimani