tags:

views:

82

answers:

2

Does .NET Framework have a function similar to Python's imghdr.what function to determine what type of image a file (or stream) is? I can't find anything.

A: 

Just recently I needed to determine mime type used in file. I don't know the exact logic behind this windows API calls, but I suspect it goes inside the file to get idea of it's mime type. Hope this will help

using System;
using System.IO;
using System.Runtime.InteropServices;

namespace SomeNamespace
{
    /// <summary>
    /// This will work only on windows
    /// </summary>
    public class MimeTypeFinder
    {
        [DllImport(@"urlmon.dll", CharSet = CharSet.Auto)]
        private extern static UInt32 FindMimeFromData(
            UInt32 pBC,
            [MarshalAs(UnmanagedType.LPStr)] String pwzUrl,
            [MarshalAs(UnmanagedType.LPArray)] byte[] pBuffer,
            UInt32 cbSize,
            [MarshalAs(UnmanagedType.LPStr)]String pwzMimeProposed,
            UInt32 dwMimeFlags,
            out UInt32 ppwzMimeOut,
            UInt32 dwReserverd
        );

        public string GetMimeFromFile(string filename)
        {
            if (!File.Exists(filename))
                throw new FileNotFoundException(filename + " not found");

            var buffer = new byte[256];
            using (var fs = new FileStream(filename, FileMode.Open))
            {
                if (fs.Length >= 256)
                    fs.Read(buffer, 0, 256);
                else
                    fs.Read(buffer, 0, (int)fs.Length);
            }
            try
            {
                UInt32 mimetype;
                FindMimeFromData(0, null, buffer, 256, null, 0, out mimetype, 0);
                var mimeTypePtr = new IntPtr(mimetype);
                var mime = Marshal.PtrToStringUni(mimeTypePtr);
                Marshal.FreeCoTaskMem(mimeTypePtr);
                return mime;
            }
            catch (Exception)
            {
                return "unknown/unknown";
            }
        }
    }
}
Sergej Andrejev
Thanks Sergej. Was hoping I didn't have to roll my own, but it'll work!Bob
bobuva
This is not your own, but rather Windows API which is not yet mapped to .Net
Sergej Andrejev
A: 

If you can trust the file's extension, you can do something like the rails plugin mimetype-fu.

This plugin has a yaml list of extensions and their known mime types. It is fairly exhaustive. We found a yaml parser for .net and simply used mimetype-fu's yaml. This made it both fast to build and fast performing.

If you are dealing with streams only and don't have a filename, the above may work better for you.

Chad Ruppert