ラベル 写真 の投稿を表示しています。 すべての投稿を表示
ラベル 写真 の投稿を表示しています。 すべての投稿を表示

2016年1月29日金曜日

スマホで写真を投稿したら・・・ひっくり返って表示された!

「スマホで写真を投稿したら・・・ひっくり返って表示された!」



なんてことに出会ったことはありますか?

写真のデータの中には、写真の情報はもちろんですが、
どういう風に写真を撮ったのか、というデータも持っています。

-スマホを縦にして写真を撮ったのか、横にして写真を撮ったのか。

といった情報です。

この情報を正しく扱ってあげないと、Web上で写真を表示するときに、
ひっくり返ったり、横向きになったりしてしまうのです。

デジカメ画像の規格として、Exif(イグジフ)というものがあります。
※詳しくは、http://e-words.jp/w/Exif.html

この規格を採用しているカメラ(スマホカメラ含む)の場合、
写真以外に様々なデータが、付加情報として記録されます。

この付加情報を持っている写真データの場合は、
その情報を考慮し、写真を保存してあげないと、ひっくり返ったり、横向きになったりしてしまうのです。

iPhoneのカメラで採用されていることもあり、開発する際に遭遇することもあると思うので、
付加情報の確認とその修正のサンプルを載せておきます。

もちろん、C#です。

private void CheckProperties(string _path)
{
 // 対象の写真を開きます
 System.Drawing.Bitmap origin = new System.Drawing.Bitmap(_path);

 // 画像の回転度合の設定用
 System.Drawing.RotateFlipType rotation = System.Drawing.RotateFlipType.RotateNoneFlipNone;
 // 開いた写真の情報を順に確認します。
 foreach (System.Drawing.Imaging.PropertyItem item in origin.PropertyItems) {

  // 写真の向きの情報は、0x0112というIDに割り振られているので、このID以外はすっ飛ばします
  if (item.Id != 0x0112)
  {
   continue;
  }

  // IDが0x0112の時なので、向きの情報が取れる場所
  switch(item.Value[0])
  {
   case 1:// 不要(回転・反転なし)
    break;

   case 2:// 水平方向に反転
    break;

   case 3:// 時計回りに180度回転
    // 時計回りに180度回転しているので、180度回転して戻す
    rotation = System.Drawing.RotateFlipType.Rotate180FlipNone;
    break;

   case 4:// 垂直方向に反転
    break;

   case 5:// 水平方向に反転+時計回りに270度回転
    break;

   case 6:// 時計回りに90度回転
    // 時計回りに270度回転しているので、90度回転して戻す
    rotation = System.Drawing.RotateFlipType.Rotate90FlipNone;

    break;

   case 7:// 水平方向に反転+時計回りに90度回転
    break;

   case 8:// 時計回りに270度回転
    // 時計回りに90度回転しているので、270度回転して戻す

    rotation = System.Drawing.RotateFlipType.Rotate270FlipNone;

    break;

   default:    break;

  }

  // といった感じで、item.Value[0]の値で、どんな状態なのかが分かるのです。
  // あとは、この値を元に処理をしてあげればOK
  // 上記の3、6、8には正しくする処理を記載しましたので、参考にしてみてください

 }



 // 画像を複製して、回転を正す
 System.Drawing.Image rotated_image = (System.Drawing.Image)origin.Clone();

 // 複製する際のフォーマット(元の画像と一緒にする)
 System.Drawing.Imaging.ImageFormat format = origin.RawFormat;

 // オリジナルの画像から、欲しいものは奪えたので、閉じちゃう
 origin.Dispose();

 // 指定された角度だけ画像を回転する
 rotated_image.RotateFlip(rotation);

 // 回転を正したものを、指定のパスに保存
 try
 {
  rotated_image.Save("新たな保存先", format);
 }
 catch(Exception ex)
 {
  rotated_image.Dispose();
 }
 finally
 {
  rotated_image.Dispose();
 }
}