はじめに
- THETA Vの静止画から角度情報を取得して画像を正しい向きにする(天頂補正)際に実施した内容(取得編)
- こちらの方法では取得できなくなっていたので新規に作成しました
- Unityアプリでの使用を前提としています
作業方針
- THETA Vの静止画には角度情報がxmpとして入っているためその情報を取得する
- 以前の方法では、リコー固有ブロックのExif情報を取得していました
- 必要な部分だけ取り出す
- XMLパーサなどを使用せずに軽量化
コード
XmpReader.cs
using UnityEngine;
using System.Collections;
using System.IO;
using System;
public class XmpReader
{
public static void SerchAngle(string filePath)
{
BinaryReader br = new BinaryReader(new FileStream(filePath, FileMode.Open));
byte [] buf = br.ReadBytes((int)br.BaseStream.Length);
br.Close();
br = null;
float pitch = getPitch(buf);
float roll = getRoll(buf);
Debug.Log("filePath : " + filePath);
Debug.Log("pitch : " + pitch + ", roll : " + roll);
}
public static float getPitch(byte[] buf) {
string pitchStr = getXMLTagData(buf, "GPano:PosePitchDegrees");
float pitch = 0.0f;
if (pitchStr != "") {
pitch = float.Parse(pitchStr);
}
return pitch;
}
public static float getRoll(byte[] buf) {
string rollStr = getXMLTagData(buf, "GPano:PoseRollDegrees");
float roll = 0.0f;
if (rollStr != "") {
roll = float.Parse(rollStr);
}
return roll;
}
static string getXMLTagData(byte[] buf, string xmlTagName) {
string strStart = String.Format("<{0}>", xmlTagName);
byte[] byteStart = System.Text.Encoding.ASCII.GetBytes(strStart);
int xmp_start = findData(buf, byteStart);
if (xmp_start < 0) {
return "";
}
string strEnd = String.Format("</{0}>", xmlTagName);
byte[] byteEnd = System.Text.Encoding.ASCII.GetBytes(strEnd);
int xmp_end = findData(buf, byteEnd);
if (xmp_end < 0) {
return "";
}
xmp_end = xmp_end - strEnd.Length;
byte[] buf_get = new byte[255];
int copy_idx = 0;
for (int i=xmp_start;i<xmp_end; i++) {
buf_get[copy_idx] = buf[i];
copy_idx++;
}
string result = System.Text.Encoding.ASCII.GetString(buf_get);
return result;
}
static int findData(byte[] buf, byte[] pattern)
{
int max = buf.Length;
if (max > 64*1000) {
max = 64*1000;
}
for (int i = 0; i < max; i++) {
int iTemp = i;
for (int p = 0; p < pattern.Length ; p++, iTemp++) {
if (pattern[p] != buf[iTemp] || iTemp >= max) {
break;
}
if (p == pattern.Length - 1) {
return iTemp + 1;
}
}
}
return -1;
}
}
さいごに
- この角度情報を実際に利用する方法はこちらに書きました
- 他のアプリ(OculusGoのギャラリーなど)は、このXMPがあるためVR表示しますが天頂補正はしませんでした