2013-05-07 37 views
1

我一直在尋找,現在編碼3天在這個問題上,沒有結果:(移動與加速度計球視圖內的攝像頭預覽android系統

我做了一個攝像頭覆蓋該代碼是在這裏+加速度計

public class CameraActivity extends Activity implements SurfaceHolder.Callback, SensorEventListener { 
    Camera camera; 
    SurfaceView surfaceView; 
    SurfaceHolder surfaceHolder; 
    boolean previewing = false; 
    LayoutInflater controlInflater = null; 

    static String TAG = CameraActivity.class.getSimpleName(); 

    // Accelerometer 
    private SensorManager mSensorManager; 
    private Sensor mAccelerometer; 


    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.surface_view); 
     setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); 

     surfaceView = (SurfaceView) findViewById(R.id.camerapreview); 
     surfaceHolder = surfaceView.getHolder(); 
     surfaceHolder.addCallback(this); 
     surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 

     controlInflater = LayoutInflater.from(getBaseContext()); 
     View viewControl = controlInflater.inflate(R.layout.camera_control, 
       null); 

     LayoutParams layoutParamsControl = new LayoutParams(
       LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); 

     this.addContentView(viewControl, layoutParamsControl); 


     // Accelerometer 
     mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE); 
     mAccelerometer = mSensorManager 
       .getDefaultSensor(Sensor.TYPE_ACCELEROMETER); 
     mSensorManager.registerListener(this, mAccelerometer, 
       SensorManager.SENSOR_DELAY_NORMAL); 

    } 

    @Override 
    public void onAccuracyChanged(Sensor sensor, int accuracy) { 

    } 

    @Override 
    public void onSensorChanged(SensorEvent event) { 

    } 


    @Override 
    public void surfaceChanged(SurfaceHolder holder, int format, int width, 
      int height) { 
     // TODO Auto-generated method stub 
     if (previewing) { 
      camera.stopPreview(); 
      previewing = false; 
     } 

     if (camera != null) { 
      try { 
       camera.setPreviewDisplay(surfaceHolder); 
       camera.startPreview(); 
       previewing = true; 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 

    @Override 
    public void surfaceCreated(SurfaceHolder holder) { 
     camera = Camera.open(); 
    } 

    @Override 
    public void surfaceDestroyed(SurfaceHolder holder) { 
     camera.stopPreview(); 
     camera.release(); 
     camera = null; 
     previewing = false; 
    } 
} 

然後在camera_control.xml我有這樣的:

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/layout_holder" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:background="@android:color/transparent" 
    android:gravity="bottom" > 

    <ImageView 
     android:id="@+id/imageView2" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignBottom="@+id/camera_red_button" 
     android:layout_alignLeft="@+id/camera_back_button" 
     android:layout_marginBottom="27dp" 
     android:src="@drawable/camera_accelerometer_red" /> 

</RelativeLayout> 

camera_accelerometer_red

ball

並在surface_view.xml

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="vertical" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:id="@+id/camerapreview_holder" 
    > 

<SurfaceView 
    android:id="@+id/camerapreview" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    /> 
</LinearLayout> 

的圖像視圖爲精神電平的圖像。

這個想法是用戶需要在拍攝照片之前將照相機調平。我已經清除了所有非nessessery代碼。上面的代碼是工作代碼。

問題: 我需要爲精神層面製造一個球。它並不需要成爲最流暢的精神層面。如果我能找到將球限制在水平儀內並根據加速度計結果移動它的方式,我將如拉里那樣開心:)/

如果有人請讓我在這三件事情的正確方向:

  1. 面積
  2. 限制區域內限制的動畫是圓形,如何使它

在此先感謝。 H.

回答

1

好的我已經得到了答案。希望它可以幫助某人。您需要使用計算從中間到角點(半徑)的角度偏移量。

此外,我已將Accelerometor更改爲方向傳感器,然後我可以在X和Y軸上獲取手機的3D旋轉。

下面的代碼是工作代碼,我測試了它們。我正在使用Android 2.3.3+ 球運動不是很順暢,因爲這不是應用程序的目的。

我認爲爲了平滑移動,您可能需要添加定時器和碰撞檢測。請檢查android示例。

我還沒有重構代碼。因此,這不是一個生產水平的代碼:)

代碼:

public class CameraActivity extends Activity implements SurfaceHolder.Callback, 
     SensorEventListener { 

    // Accelerometer 
    private SensorManager mSensorManager; 
    private Sensor mAccelerometer; 

    /** Called when the activity is first created. */ 
    public static float x; 
    public static float y; 

    FrameLayout layout_holder; 
    FrameLayout ball_holder; 

    // private float hOriginSize; 
    float halfOfWidth; 
    int centerYOnImage; 
    private Sensor mOrientation; 

     // float viewInset = 14.0f; // I remove this simply to make the code cleaner. I used this to calculate the radius and the offset later on 

    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.surface_view); 
     setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); 

     surfaceView = (SurfaceView) findViewById(R.id.camerapreview); 
     surfaceHolder = surfaceView.getHolder(); 
     surfaceHolder.addCallback(this); 
     surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 

     controlInflater = LayoutInflater.from(getBaseContext()); 
     View viewControl = controlInflater.inflate(R.layout.camera_control, 
       null); 

     LayoutParams layoutParamsControl = new LayoutParams(
       LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); 

     this.addContentView(viewControl, layoutParamsControl); 

     // Accelerometer 
     mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE); 
     mOrientation = mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION); 
     mSensorManager.registerListener(this, mAccelerometer, 
       SensorManager.SENSOR_DELAY_NORMAL); 

     Bitmap bitmap = BitmapFactory.decodeResource(getResources(), 
       R.drawable.ball); 
     CustomDrawableView mCustomDrawableView = new CustomDrawableView(this, 
       bitmap); 

     ball_holder = (FrameLayout) findViewById(R.id.ball_holder); 
     ball_holder.addView(mCustomDrawableView); 

     halfOfWidth = 40; // You can calculate this, I just put this so I can test it. This is the half of the width of target image - attached in the question 

     centerYOnImage = 40; // Not important :) 

    } 

    @Override 
    public void onAccuracyChanged(Sensor sensor, int accuracy) { 

    } 

    // This method will update the UI on new sensor events 
    public void onSensorChanged(SensorEvent event) { 

     // float azimuth_angle = event.values[0]; 
     x = event.values[1]; 
     y = event.values[2]; 

     // FIXME: Fine tune this for the image taking part 
     float ratio = 70.0f/25.0f; 
     x = x * ratio; 
     y = y * ratio; 

     Log.d(TAG, "x and y: " + x + " " + y); 

     float maxDistance = 35; // To calculate this halfOfWidth - viewInset; 

       // to calculate between 2 distances 
     float distance = (float) Math.sqrt(((x) * (x)) + ((y) * (y))); 

     if (distance > maxDistance) { 

      float angle = (float) Math.atan2(x, y); 

      /Get new point on the edge of the circle 
      y = (float) (Math.cos(angle) * maxDistance); 
      x = (float) (Math.sin(angle) * maxDistance); 
     } 

     x = x + 40; // 40 is the half od the distance of the full width 
     y = (y * -1.0f) + 40; // -1.0f is so orientation works like the actual spirit level 

     canUserTakePhoto(distance); 

    } 

    // Change the background 
    public void canUserTakePhoto(float treshold) { 
     if (treshold > 10) { 
      // Not Yet 
     } else { 
      // take it 
     } 
    } 


    @Override 
    protected void onResume() { 
     super.onResume(); 
     mSensorManager.registerListener(this, mOrientation, 
       SensorManager.SENSOR_DELAY_NORMAL); 
    } 

    @Override 
    protected void onPause() { 
     super.onPause(); 
     mSensorManager.unregisterListener(this); 
    } 

    public class CustomDrawableView extends ImageView { 

     Bitmap b; 

     public CustomDrawableView(Context context, Bitmap bitmap) { 
      super(context); 

      this.b = bitmap; 
     } 

     @Override 
     protected void onDraw(Canvas canvas) { 

      canvas.drawBitmap(this.b, x, y, null); 

      invalidate(); 
     } 
    } 

    @Override 
    public void onDestroy() // main thread stopped 
    { 
     super.onDestroy(); 
     // wait for threads to exit before clearing app 
     System.runFinalizersOnExit(true); 
     // remove app from memory 
     android.os.Process.killProcess(android.os.Process.myPid()); 
    } 

    @Override 
    public void surfaceChanged(SurfaceHolder holder, int format, int width, 
      int height) { 
     // TODO Auto-generated method stub 
     if (previewing) { 
      camera.stopPreview(); 
      previewing = false; 
     } 

     if (camera != null) { 
      try { 

       camera.setPreviewDisplay(surfaceHolder); 
       camera.startPreview(); 
       previewing = true; 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 
    } 

    @Override 
    public void surfaceCreated(SurfaceHolder holder) { 
     // TODO Auto-generated method stub 
     camera = Camera.open(); 
    } 

    @Override 
    public void surfaceDestroyed(SurfaceHolder holder) { 
     // TODO Auto-generated method stub 
     camera.stopPreview(); 
     camera.release(); 
     camera = null; 
     previewing = false; 
    } 

} 

乾杯。

相關問題