2012-04-28 6 views
1

私自身のカメラアクティビティを実装しています。 撮影した画像を回転するには、撮影時の向きを知る必要があります。 - 通常の携帯電話を保持し、肖像画
ダウントップ
右から左 - 風景トップ

トップダウン:センサーが私のデバイスがに向いている私に語ったピッチおよびロール値のため は、より高いレベルのAPIはあります電話機の上部が右側にある
左端 - 風景電話機の上部が左側にあるセンサ値の高レベルAPIピッチアンドロール

また、システムから直接gehtする方法はありますか?

+0

トップダウンではどういう意味ですか、左から右ですか? – zapl

+0

これをチェックし、必要なときにいつでも呼び出す関数を書くことができます。また、人々があなたの質問に答えるためには、回答を受け入れるべきです。あなたの古い答えを見て、最高のものを受け入れてください。ボタンは回答の評価にあります。 –

+0

アドバイスありがとう、私はその機能を見て – strangeoptics

答えて

1

悲しいことに、悲しいことに、風景モードでないときはアンドロイドのカメラは奇妙な仕方で動作します(これはアンドロイドのカメラの「自然な」向きです)。

アクティビティをランドスケープモードに設定し、現在の方向を取得するために、onConfigurationChangedイベントを追加します(マニフェストにandroid:configChanges = "orientation"を追加します)。

画像をキャプチャするときは、向きを確認し、必要なロジックに従って動作させます。

+0

良い点。 onConfigurationChangedイベントのようなものが存在するかどうかはわかりませんでした。私はそれを試してみました。私がポートレートモードかランドスケープモードであるかどうかだけを教えてくれます。カメラのセンサーには1つの方向がありますが、カメラを左右に動かすと、風景には2つの方向があります。結果をどのように回転させるべきかを判断する方法が必要です。 – strangeoptics

+0

2.2+をターゲットにしている場合は、これでうまくいくかもしれません。http://developer.android.com/reference/android/view/Display.html#getRotation%28%29 –

+0

もう1つの素晴らしいAPIの話を聞いたことがありません私はそれを試しましたが、それは常に私に0度を示しています。 int rotation = getWindowManager()。getDefaultDisplay()。getRotation();私がマニフェストで固定された方向を設定したからです。 – strangeoptics

1

[OK]を私のために働くように、特定のポイントに私の問題を解決し、私はダウントップの認識を除外しました。

public class DeviceOrientation { 

public static final int ORIENTATION_PORTRAIT = 0; 
public static final int ORIENTATION_LANDSCAPE_REVERSE = 1; 
public static final int ORIENTATION_LANDSCAPE = 2; 
public static final int ORIENTATION_PORTRAIT_REVERSE = 3; 

int smoothness = 1; 
public float averagePitch = 0; 
public float averageRoll = 0; 
public int orientation = ORIENTATION_PORTRAIT; 

private float[] pitches; 
private float[] rolls; 

public DeviceOrientation(int smoothness) { 
    this.smoothness = smoothness; 

    pitches = new float[smoothness]; 
    rolls = new float[smoothness]; 
} 

public void addSensorEvent(SensorEvent event) { 
    azimuth = event.values[0]; 

    averagePitch = addValue(event.values[1], pitches); 
    averageRoll = addValue(event.values[2], rolls); 

    orientation = calculateOrientation(); 
} 

private float addValue(float value, float[] values) { 
    float average = 0; 

    for(int i=1; i<smoothness; i++) { 
     values[i-1] = values[i]; 
     average += values[i]; 
    } 
    values[smoothness-1] = value; 
    average = (average + value)/smoothness; 

    return average; 
} 

/** handles all 4 possible positions perfectly */ 
private int calculateOrientation() { 
    // finding local orientation dip 
    if (((orientation == ORIENTATION_PORTRAIT || orientation == ORIENTATION_PORTRAIT_REVERSE) 
      && (averageRoll > -30 && averageRoll < 30))) { 
     if (averagePitch > 0) 
      return ORIENTATION_PORTRAIT_REVERSE; 
     else 
      return ORIENTATION_PORTRAIT; 
    } else { 
     // divides between all orientations 
     if (Math.abs(averagePitch) >= 30) { 
      if (averagePitch > 0) 
       return ORIENTATION_PORTRAIT_REVERSE; 
      else 
       return ORIENTATION_PORTRAIT; 
     } else { 
       if (averageRoll > 0) { 
        return ORIENTATION_LANDSCAPE_REVERSE; 
       } else { 
        return ORIENTATION_LANDSCAPE; 
       } 
     } 
    } 
} 

説明: 私はポートレートモードで午前とそれが原因コードの残りの部分に横長に切り替わります水平位置になるまで、前方モービルをtillt場合。 したがって、私はそれが肖像画であるかどうかをチェックし、このモードを切り捨てるのが難しい状態にします。 これは私が地元のディップで務めるものです。 残りは3つの方向すべてに分かれています。

1つ悪いです。デバイスがlandscape_xにあり、後方に傾きがある場合、ピッチは〜2から〜175にジャンプします。その時点で、私のコードは、風景と肖像画の間に浮かんでいます。

滑らかさは、最後のn値を組み合わせて平均を計算することによってセンサデータの値を平滑化します。それは本当に必要ではありません。

他の人に役立つことを願っています。コードをさらに改善できる場合は、私にお知らせください。

+0

親切にコードの残りの部分を入れてください...お願いしますか? –

+0

コードが更新されました。それを再生する完全なプロジェクトは、私のGoogleドライブにあります。 [SensorDemo.rar](https://docs.google.com/open?id=0B4dC-qLD0ltec3BteVNBTDB2OFU) – strangeoptics

+0

ありがとうございます。 「完璧ではないが、95%働いている」という意味は何ですか? –