web-dev-qa-db-ja.com

C#ファイルをjpegでテストするにはどうすればよいですか?

C#を使用して、ファイルがjpegであることをテストするにはどうすればよいですか? .jpg拡張子を確認する必要がありますか?

ありがとう

29
Scott

いくつかのオプション:

ファイル拡張子を確認できます。

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

または、ファイルのヘッダーで正しい マジックナンバー を確認します。

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

別のオプションは、イメージをロードして正しいタイプを確認することです。ただし、これは効率的ではありません(とにかく画像を読み込む場合を除く)。おそらく最も信頼できる結果が得られます(読み込みと解凍の追加コスト、および例外処理の可能性に注意してください)。

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

ファイルをストリームとして開き、JPEGの マジックナンバー を探します。

JPEG画像ファイルはFF D8で始まり、FF D9で終わります。 JPEG/JFIFファイルには、ASCII 'JFIF'(4A 46 49 46)のコードがnullで終了する文字列として含まれています。JPEG/ ExifファイルにはASCIIコードが含まれています'Exif'(45 78 69 66)の場合もnullで終了する文字列

28
Simon Gibbs

OMG、これらのコード例の多くは間違っています。

EXIFファイルには0xff * e1 *のマーカーがあり、JFIFファイルには0xff * e *のマーカーがあります。したがって、JPEGファイルを検出するために0xffe0に依存するすべてのコードは、すべてのEXIFファイルを見逃します。

これは両方を検出するバージョンで、JFIFのみまたはEXIFのみを返すように簡単に変更できます。 (たとえば、iPhoneの写真を復元するときに便利です)。

    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;
        }
    }
26
Orwellophile

ファイルを画像にロードしてから、フォーマットを確認してみてください

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

または、ファイルを開いてヘッダーを確認し、タイプを取得することもできます

13
Lee

Jpegファイル形式、特にヘッダー情報に関するドキュメントを見つけることができます。次に、この情報をファイルから読み取って、予想されるjpegヘッダーバイトと比較します。

4
Brian Ensink

ヘッダーバイトを読み取ります。この記事には、JPEGを含むいくつかの一般的な画像形式に関する情報が含まれています。

画像ファイルヘッダーを使用した画像形式の確認

JPEGヘッダー情報

3
Mitch Wheat

拡張機能を取得したら、正規表現を使用して検証できます。

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

これにより、現在のディレクトリ内の各ファイルがループされ、JPGまたはJPEG拡張子が付いたファイルが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

このファイルを見ている状況に応じて、次のことを覚えておく必要があります ユーザーが開くように指示するまで、ファイルを開くことはできません。

(リンクはRaymond Chenブログエントリへのリンクです。)

1
Dave Webb

Path.GetExtensionメソッド を使用できます。

0
Galwegian

ここのコード:

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

メタデータを取得する方法を示します。画像が有効なJPEGでない場合、例外がスローされると思います。

0
Program.X

ファイル名が嘘である可能性があるため、ファイル拡張子を確認するだけでは不十分です。

すばやく簡単な方法は、Imageクラスを使用して画像をロードし、例外をキャッチすることです。

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

OutOfMemoryException、FileNotFoundExceptionなど、あらゆる種類の例外が発生する可能性があるため、これは理想的ではありません。

最も徹底的な方法は、ファイルをバイナリとして扱い、ヘッダーがJPG形式に一致するようにすることです。どこかで説明されていると思います。

0
Steve Dunn

最善の方法は、Drawing.Bitmap(string)コンストラクターを使用して画像を作成し、作成に失敗したり、例外をスローしたりすることを確認することです。いくつかの答えの問題はこれです:まず、拡張子は純粋に任意であり、jpg、jpeg、jpe、bob、timなどです。次に、ヘッダーを使用するだけでは100%確実であるとは言えません。ファイルがjpegではないことを明確に判別できますが、ファイルがjpegであることを保証することはできません。任意のバイナリファイルは、最初に同じバイトシーケンスを持つことができます。

0
Skizz

ファイルのメディアタイプを取得して確認するだけです。

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

このように画像の最初の4バイトと画像の最後の2バイトを読み取るファイルの拡張をチェックした後、値255の最後の2バイトに対してそれを行い、他のファイルに対して217はそれを行うことができます 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