2009-06-14T00:31:57の更新内容

programming/tips/rotate_image_by_exif_info/index.wiki.txt

current previous
1,32 0,0
+
${smdncms:keywords,EXIF,画像,回転,方向}
+
${smdncms:tags,lang/c#,api/.net}
+
*EXIFの情報に基づいて画像を回転する
+
EXIFのOrientationタグの値に基づいて画像を回転し、適切な方向に戻す方法。 この例では、値がリトルエンディアンで格納されていることを前提としている。 また、左右反転・上下反転している画像については考慮していない。
+
#googleadunit
+

          
+
#code(cs){{
+
using {
+
  var rotation = RotateFlipType.RotateNoneFlipNone;
+

          
+
  foreach {
+
    if
+
      continue;
+

          
+
    // IFD0 0x0112; Orientation
+
    switch {
+
      case 3: rotation = RotateFlipType.Rotate180FlipNone; break;
+
      case 6: rotation = RotateFlipType.Rotate90FlipNone; break;
+
      case 8: rotation = RotateFlipType.Rotate270FlipNone; break;
+
    }
+
  }
+

          
+
  using {
+
    rotated.RotateFlip(rotation);
+
    rotated.Save("rotated.bmp", ImageFormat.Bmp);
+
  }
+
}
+
}}
+

          
+
-参考
+
--[[Exif Orientation Page:http://sylvana.net/jpegcrop/exif_orientation.html]] Orientationタグの値と回転方向の対応表
+
--[[Exif形式の画像ファイル解説:http://park2.wakwak.com/~tsuruzoh/Computer/Digicams/exif.html]]

programming/tips/findmimetype/index.wiki.txt

current previous
1,159 0,0
+
${smdncms:keywords,MIME,タイプ,判定,拡張子}
+
${smdncms:tags,lang/c#,plat/win,api/win32,api/.net}
+
*MIMEタイプの取得・判定
+
#googleadunit
+

          
+
**拡張子からのMIMEタイプの取得
+
Windowsの場合、レジストリのHKEY_CLASSES_ROOTに、拡張子毎にアプリケーションの関連付けなどの情報が格納されている。 目的の拡張子をキーとしたノードにContent Typeの値が登録されている場合は、その値を使用できる。
+
#code(cs){{
+
private static string GetMimeTypeByExtension(string extension)
+
{
+
  const string @default = "application/octet-stream";
+

          
+
  var key = Registry.ClassesRoot.OpenSubKey(extension);
+

          
+
  if
+
    return @default;
+

          
+
  var mimeType = key.GetValue("Content Type");
+

          
+
  if
+
    return @default;
+
  else
+
    returnmimeType;
+
}
+

          
+
public static void Main(string[] args)
+
{
+
  var extensions = new[] {
+
    ".txt", ".eml", ".html",
+
    ".jpg", ".bmp", ".wav",
+
    ".mp4",
+
    ".exe", ".dll", ".bin",
+
    ".zip", ".tar.gz",
+
  };
+

          
+
  foreach {
+
    Console.WriteLine("{0} => {1}", extension, GetMimeTypeByExtension(extension));
+
  }
+
}
+
}}
+

          
+
#prompt(実行結果){{
+
.txt => text/plain
+
.eml => message/rfc822
+
.html => text/html
+
.jpg => image/jpeg
+
.bmp => image/bmp
+
.wav => audio/wav
+
.mp4 => video/mp4
+
.exe => application/x-msdownload
+
.dll => application/x-msdownload
+
.bin => application/octet-stream
+
.zip => application/x-zip-compressed
+
.tar.gz => application/octet-stream
+
}}
+

          
+
**データストリームからのMIMEタイプの判定
+
[[FindMimeFromData関数:http://msdn.microsoft.com/en-us/library/ms775107(VS.85).aspx]]を用いることで、データストリームからMIMEタイプを推定することが出来る。
+

          
+
(この項の内容は検証が不十分です。 適用に際してはリンク先のドキュメントを参照してください。)
+

          
+
#code(cs){{
+
private enum FMFD : uint {
+
  FMFD_DEFAULT              = 0,
+
  FMFD_URLASFILENAME        = 1 << 0,
+
  FMFD_ENABLEMIMESNIFFING   = 1 << 1,
+
  FMFD_IGNOREMIMETEXTPLAIN  = 1 << 2,
+
  FMFD_SERVERMIME           = 1 << 3, // ?
+
}
+

          
+
[DllImport("urlmon")] private static extern
+
uint FindMimeFromData(IntPtr pBC,
+
                     IntPtr pwzUrl,
+
                     byte[] buffer,
+
                     int cbSize,
+
                     [In, MarshalAs(UnmanagedType.LPWStr)] string pwzMimeProposed,
+
                     FMFD dwMimeFlags,
+
                     [MarshalAs(UnmanagedType.LPWStr)] out string ppwzMimeOut,
+
                     uint dwReserved);
+

          
+
private static string GetMimeTypeByMagic(byte[] magic, string mimeProposed)
+
{
+
  const uint E_INVALIDARG = 0x80070057;
+
  string mime;
+

          
+
  var ret = FindMimeFromData(IntPtr.Zero, IntPtr.Zero, magic, magic.Length, mimeProposed, FMFD.FMFD_DEFAULT, out mime, 0);
+

          
+
  if
+
    return mime;
+
  else if
+
    throw new ArgumentException();
+
  else
+
    return null;
+
}
+

          
+
public static void Main()
+
{
+
  var image = new Bitmap(8, 8);
+

          
+
  // イメージ
+
  foreach (var format in new[] {
+
    System.Drawing.Imaging.ImageFormat.Bmp,
+
    System.Drawing.Imaging.ImageFormat.Jpeg,
+
    System.Drawing.Imaging.ImageFormat.Png,
+
  }) {
+
    using {
+
      image.Save(stream, format);
+

          
+
      Console.WriteLine("{0} => {1}", format, GetMimeTypeByMagic(stream.ToArray(), null));
+
    }
+
  }
+

          
+
  // プレーンテキスト
+
  var text = "Hello, world.\r\n";
+

          
+
  Console.WriteLine("plain text => {0}", GetMimeTypeByMagic(Encoding.Default.GetBytes(text), "text/plain"));
+

          
+
  // XML
+
  text = @"<?xml version=""1.0"">
+
<feed xmlns=""http://www.w3.org/2005/Atom"">
+
</feed>
+
</xml>";
+

          
+
  Console.WriteLine("XML => {0}", GetMimeTypeByMagic(Encoding.Default.GetBytes(text), "text/plain"));
+

          
+
  // HTML
+
  text = @"<html><body>HTML</body></html>";
+

          
+
  Console.WriteLine("HTML => {0}", GetMimeTypeByMagic(Encoding.Default.GetBytes(text), "text/plain"));
+

          
+
  // 256バイトのランダムなストリーム
+
  var random = new Random();
+

          
+
  for {
+
    var stream = new byte[0x100];
+

          
+
    random.NextBytes(stream);
+

          
+
    Console.WriteLine("random => {0}", GetMimeTypeByMagic(stream, "application/octet-stream"));
+
  }
+
}
+
}}
+

          
+
#prompt(実行結果){{
+
Bmp => image/bmp
+
Jpeg => image/pjpeg
+
Png => image/x-png
+
plain text => text/plain
+
XML => text/xml
+
HTML => text/html
+
random => application/octet-stream
+
random => application/octet-stream
+
random => application/octet-stream
+
}}
+

          
+
FindMimeFromDataは、渡されたデータストリームをスキャンして[[MIME Type Detection in Internet Explorer:http://msdn.microsoft.com/en-us/library/ms775147(VS.85).aspx]]のKnown MIME Typesにあるタイプかどうかテストする。 このページには判定方法についての詳細が書かれている。
+

          
+
FindMimeFromDataは、通常最初の256バイトの内容を重視するとしているので、例えば256バイトを越えるファイルの内容をすべて渡すのは無駄と思われる。
+