2012-07-12T22:48:21の更新内容

programming/tips/rotate_image_by_exif_info/index.wiki.txt

current previous
1,186 1,36
 
${smdncms:title,EXIFの情報に基づいて画像を回転する}
${smdncms:title,EXIFの情報に基づいて画像を回転する}
 
${smdncms:keywords,EXIF,画像,回転,方向}
${smdncms:keywords,EXIF,画像,回転,方向}
~
${smdncms:tags,lang/c#,lang/vb,api/.net}
${smdncms:tags,lang/c#,api/.net}
+
${smdncms:document_versions,codelang=cs,codelang=vb}
+

          
 
EXIFのOrientationタグの値に基づいて画像を回転し、適切な方向に戻す方法。 この例では、値がリトルエンディアンで格納されていることを前提としている。 また、左右反転・上下反転している画像については考慮していない。
EXIFのOrientationタグの値に基づいて画像を回転し、適切な方向に戻す方法。 この例では、値がリトルエンディアンで格納されていることを前提としている。 また、左右反転・上下反転している画像については考慮していない。
 

        

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

        

        
 
#googleadunit
#googleadunit
 

        

        
+
#tabpage(C#)
 
#code(cs){{
#code(cs){{
~
using System;
using (var origin = new Bitmap("origin.jpg")) {
~
using System.Drawing;
  var rotation = RotateFlipType.RotateNoneFlipNone;
~
using System.Drawing.Imaging;

          
~

          
  foreach (var item in origin.PropertyItems) {
~
class Sample {
    if (item.Id != 0x0112)
~
  public static void Main()
      continue;
~
  {

          
~
    // 元の画像を開く
    // IFD0 0x0112; Orientation
~
    using (var origin = new Bitmap("origin.jpg")) {
    switch (item.Value[0]) {
~
      var rotation = RotateFlipType.RotateNoneFlipNone;
      case 3: rotation = RotateFlipType.Rotate180FlipNone; break;
~

          
      case 6: rotation = RotateFlipType.Rotate90FlipNone; break;
~
      foreach (var item in origin.PropertyItems) {
      case 8: rotation = RotateFlipType.Rotate270FlipNone; break;
+
        if (item.Id != 0x0112)
+
          continue;
+

          
+
        // IFD0 0x0112; Orientationの値を調べる
+
        switch (item.Value[0]) {
+
          case 3:
+
            // 時計回りに180度回転しているので、180度回転して戻す
+
            rotation = RotateFlipType.Rotate180FlipNone;
+
            break;
+
          case 6:
+
            // 時計回りに270度回転しているので、90度回転して戻す
+
            rotation = RotateFlipType.Rotate90FlipNone;
+
            break;
+
          case 8:
+
            // 時計回りに90度回転しているので、270度回転して戻す
+
            rotation = RotateFlipType.Rotate270FlipNone;
+
            break;
+
        }
+
      }
+

          
+
      // 元の画像を複製する
+
      using (var rotated = (Bitmap)origin.Clone()) {
+
        // 指定された角度だけ画像を回転する
+
        rotated.RotateFlip(rotation);
+

          
+
        // BMP形式で保存
+
        rotated.Save("rotated.bmp", ImageFormat.Bmp);
+
      }
 
    }
    }
 
  }
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+
Imports System.Drawing
+
Imports System.Drawing.Imaging
+

          
+
Class MainClass
+
  Public Shared Sub Main()
+
    ' 元の画像を開く
+
    Using origin As New Bitmap("origin.jpg")
+
      Dim rotation As RotateFlipType = RotateFlipType.RotateNoneFlipNone
+

          
+
      For Each item As PropertyItem In origin.PropertyItems
+
        If item.Id <> &H0112 Then Continue For
+

          
+
        ' IFD0 0x0112; Orientationの値を調べる
+
        Select Case item.Value(0)
+
          Case 3
+
            ' 時計回りに180度回転しているので、180度回転して戻す
+
            rotation = RotateFlipType.Rotate180FlipNone
+
          Case 6
+
            ' 時計回りに270度回転しているので、90度回転して戻す
+
            rotation = RotateFlipType.Rotate90FlipNone
+
          Case 8
+
            ' 時計回りに90度回転しているので、270度回転して戻す
+
            rotation = RotateFlipType.Rotate270FlipNone
+
        End Select
+
      Next
+

          
+
      ' 元の画像を複製する
+
      Using rotated As Bitmap = DirectCast(origin.Clone(), Bitmap)
+
        ' 指定された角度だけ画像を回転する
+
        rotated.RotateFlip(rotation)
+

          
+
        ' BMP形式で保存
+
        rotated.Save("rotated.bmp", ImageFormat.Bmp)
+
      End Using
+
    End Using
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
逆に、Orientationタグを設定して画像を保存する方法。 &msdn(netfx,type,System.Drawing.dll,System.Drawing.Imaging.EncoderParameter){EncoderParameter};を使って&msdn(netfx,member,System.Drawing.dll,System.Drawing.Imaging.Encoder.Transformation){Encoder.Transformation};と以下の値を指定することで、画像を回転(もしくは反転)された状態で表示されるように指定することが出来る。
 

        

        
~
|*Encoder.Transformationで指定できる値と画像の回転・反転方向
  using (var rotated = (Bitmap)origin.Clone()) {
~
|~指定する値|~画像の回転・反転方向|h
    rotated.RotateFlip(rotation);
~
|&msdn(netfx,member,System.Drawing.dll,System.Drawing.Imaging.EncoderValue.TransformRotate90){EncoderValue.TransformRotate90};|時計回りに90度回転するようにする|
    rotated.Save("rotated.bmp", ImageFormat.Bmp);
+
|&msdn(netfx,member,System.Drawing.dll,System.Drawing.Imaging.EncoderValue.TransformRotate180){EncoderValue.TransformRotate180};|時計回りに180度回転するようにする|
+
|&msdn(netfx,member,System.Drawing.dll,System.Drawing.Imaging.EncoderValue.TransformRotate270){EncoderValue.TransformRotate270};|時計回りに270度回転するようにする|
+
|&msdn(netfx,member,System.Drawing.dll,System.Drawing.Imaging.EncoderValue.TransformRotate90){EncoderValue.TransformFlipHorizontal};|水平方向に反転するようにする|
+
|&msdn(netfx,member,System.Drawing.dll,System.Drawing.Imaging.EncoderValue.TransformRotate90){EncoderValue.TransformFlipVertical};|垂直方向に反転するようにする|
+

          
+
#tabpage(C#)
+
#code(cs){{
+
using System;
+
using System.Drawing;
+
using System.Drawing.Imaging;
+

          
+
class Sample {
+
  public static void Main()
+
  {
+
    // 元の画像を開く
+
    using (var origin = new Bitmap("origin.jpg")) {
+
      // JPEGのコーデック情報(ImageCodecInfo)を取得
+
      ImageCodecInfo jpegCodecInfo = null;
+

          
+
      foreach (var codecInfo in ImageCodecInfo.GetImageEncoders()) {
+
        // FormatIdがJpegのものを探す
+
        if (codecInfo.FormatID == ImageFormat.Jpeg.Guid) {
+
          jpegCodecInfo = codecInfo;
+
          break;
+
        }
+
      }
+

          
+
      // エンコーダに渡すパラメータを設定する
+
      var parameters = new EncoderParameters(1);
+

          
+
      // 画像を270度回転する
+
      parameters.Param[0] = new EncoderParameter(Encoder.Transformation, (long)EncoderValue.TransformRotate270);
+

          
+
      // コーデック情報とパラメータを指定して保存
+
      origin.Save("transformed.jpg", jpegCodecInfo, parameters);
+
    }
 
  }
  }
 
}
}
 
}}
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+
Imports System.Drawing
+
Imports System.Drawing.Imaging
+

          
+
Class Sample
+
  Public Shared Sub Main()
+
    ' 元の画像を開く
+
    Using origin As Image = Bitmap.FromFile("origin.jpg")
+
      ' JPEGのコーデック情報(ImageCodecInfo)を取得
+
      Dim jpegCodecInfo As ImageCodecInfo = Nothing
+

          
+
      For Each codecInfo As ImageCodecInfo In ImageCodecInfo.GetImageEncoders()
+
        ' FormatIdがJpegのものを探す
+
        If codecInfo.FormatID = ImageFormat.Jpeg.Guid Then
+
          jpegCodecInfo = codecInfo
+
          Exit For
+
        End If
+
      Next
+

          
+
      ' エンコーダに渡すパラメータを設定する
+
      Dim parameters As New EncoderParameters(1)
+

          
+
      ' 画像を270度回転する
+
      parameters.Param(0) = New EncoderParameter(Encoder.Transformation, CLng(EncoderValue.TransformRotate270))
+

          
+
      ' コーデック情報とパラメータを指定して保存
+
      origin.Save("transformed.jpg", jpegCodecInfo, parameters)
+
    End Using
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
なお、この方法を使ってもロスレスでの回転とはならない模様。
+

          
 

        

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

programming/netfx/embeddedresource/index.wiki.txt

current previous
191,154 191,4
 
テキストファイル以外のものも、同様の手順で埋め込み・読み込みすることが出来ます。
テキストファイル以外のものも、同様の手順で埋め込み・読み込みすることが出来ます。
 

        

        
 

        

        
+
*コマンドラインコンパイラでのリソースの埋め込み
+
ここではコマンドラインコンパイラでのリソースの埋め込み方法を解説します。 MicrosoftのC#コンパイラであるcsc.exeとVisual Basicコンパイラvbc.exe、およびMonoのC#コンパイラmcs、同Visual Basicコンパイラvbncはいずれも同じ方法でリソースを埋め込むことが出来ます。
+

          
+
リソースを埋め込むためにはコンパイルオプション/resourceを使います。 /resourceオプションの省略形である/resを使うことも出来ます。 /resourceオプションは以下の形式で指定します。
+

          
+
:/resource:&var{ファイル名};|&var{ファイル名};で指定されたファイルをリソースとして埋め込む。 参照する際のリソース名は"&var{ファイル名};"となる。
+
:/resource:&var{ファイル名};,&var{リソース名};|&var{ファイル名};で指定されたファイルをリソースとして埋め込む。 参照する際のリソース名は、ここで指定した"&var{リソース名};"となる。
+

          
+
これを埋め込みたいリソースの数だけ指定します。 &var{リソース名};を省略した場合は埋め込むファイルの名前がリソース名となります。 プロジェクトファイルに追加する場合とは異なり、/resourceオプションでリソース名を省略した場合では、リソース名にはプロジェクト名やexe名などのプレフィックスは前置されません。
+

          
+
例として、コンパイル時にテキストファイルsample.txtをリソースとして埋め込むには次のようにします。 なお、このファイルに与えるリソース名は"message"としています。
+

          
+
#tabpage(csc)
+
#prompt{{
+
csc sample.cs /resource:sample.txt,message
+
}}
+
#tabpage(vbc)
+
#prompt{{
+
vbc sample.vb /resource:sample.txt,message
+
}}
+
#tabpage(mcs)
+
#prompt{{
+
mcs sample.cs /resource:sample.txt,message
+
}}
+
#tabpage(vbnc)
+
#prompt{{
+
vbnc sample.vb /resource:sample.txt,message
+
}}
+
#tabpage-end
+

          
+
これを次のようなコードとともにコンパイル・実行すると、埋め込んだテキストファイルの内容が表示されるはずです。
+

          
+
#code(,sample.txtの内容){{
+
sample.txt
+
これはリソースとして埋め込まれたテキストファイルです。
+
}}
+

          
+
#tabpage(C#)
+
#code(cs,sample.cs){{
+
using System;
+
using System.IO;
+
using System.Reflection;
+

          
+
class Sample {
+
  public static void Main()
+
  {
+
    var assm = Assembly.GetExecutingAssembly();
+

          
+
    using (var stream = assm.GetManifestResourceStream("message")) {
+
      var reader = new StreamReader(stream);
+

          
+
      Console.WriteLine(reader.ReadToEnd());
+
    }
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb,sample.vb){{
+
Imports System
+
Imports System.IO
+
Imports System.Reflection
+

          
+
Class MainClass
+
  Public Shared Sub Main()
+
    Dim assm As Assembly = Assembly.GetExecutingAssembly()
+

          
+
    Using stream As Stream = assm.GetManifestResourceStream("message")
+
      Dim reader As New StreamReader(stream)
+

          
+
      Console.WriteLine(reader.ReadToEnd())
+
    End Using
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
sample.txt
+
これはリソースとして埋め込まれたテキストファイルです。
+
}}
+

          
+

          
+
*すべてのリソースの取得・リソース情報の取得
+
&msdn(netfx,member,System.Reflection.Assembly.GetManifestResourceNames){Assembly.GetManifestResourceNamesメソッド};を使うとアセンブリに含まれているすべてのリソースの名前を取得することが出来ます。 リソースの名前が予め決まっていない・予測できない場合や、名前からリソースを検索したい場合などはこのメソッドを使うことが出来ます。
+

          
+
また、&msdn(netfx,member,System.Reflection.Assembly.GetManifestResourceInfo){Assembly.GetManifestResourceInfoメソッド};を使うとリソースに関する情報を取得することが出来ます。 リソースの情報は&msdn(netfx,type,System.Reflection.ManifestResourceInfo){ManifestResourceInfo};として取得され、このクラスを通してファイル名(リソースがマニフェストファイル以外に格納されている場合)やリソースが格納されている場所・アセンブリなどを知ることが出来ます。
+

          
+
次の例では、アセンブリに含まれている全てのリソースの名前を取得し、個々のリソースに対してを取得してリソースの情報を表示しています。
+

          
+
#tabpage(C#)
+
#code(cs,sample.cs){{
+
using System;
+
using System.IO;
+
using System.Reflection;
+

          
+
class Sample {
+
  public static void Main()
+
  {
+
    // 現在実行中のアセンブリに含まれるすべてのリソースの名前を取得する
+
    var assm = Assembly.GetExecutingAssembly();
+

          
+
    foreach (var name in assm.GetManifestResourceNames()) {
+
      // リソース名からリソースに関する情報を取得する
+
      var info = assm.GetManifestResourceInfo(name);
+

          
+
      Console.WriteLine("{0}: {1}, {2}", name, info.FileName, info.ResourceLocation);
+
    }
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb,sample.vb){{
+
Imports System
+
Imports System.IO
+
Imports System.Reflection
+

          
+
Class MainClass
+
  Public Shared Sub Main()
+
    ' 現在実行中のアセンブリに含まれるすべてのリソースの名前を取得する
+
    Dim assm As Assembly = Assembly.GetExecutingAssembly()
+

          
+
    For Each name As String In assm.GetManifestResourceNames()
+
      ' リソース名からリソースに関する情報を取得する
+
      Dim info As ManifestResourceInfo = assm.GetManifestResourceInfo(name)
+

          
+
      Console.WriteLine("{0}: {1}, {2}", name, info.FileName, info.ResourceLocation)
+
    Next
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#tabpage(コマンドラインオプションの指定例: csc)
+
#prompt{{
+
csc sample.cs /resource:message1.txt,msg1 /resource:message2.txt,msg2 /resource:message3.txt,errmsg
+
}}
+
#tabpage(コマンドラインオプションの指定例: vbc)
+
#prompt{{
+
vbc sample.vb /resource:message1.txt,msg1 /resource:message2.txt,msg2 /resource:message3.txt,errmsg
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果の例){{
+
msg1: , Embedded, ContainedInManifestFile
+
msg2: , Embedded, ContainedInManifestFile
+
errmsg: , Embedded, ContainedInManifestFile
+
}}
+

          
+

          
+