1

私はこの問題について3日間検索してコーディングしてきましたが、結果はありません:(

コードがここにある+加速度計のカメラオーバーレイを作成しました

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

玉

および 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>

Image View は水準器のイメージです。

アイデアは、ユーザーが写真を撮る前にカメラを水平にする必要があるということです。不必要なコードをすべてクリアしました。上記のコードは作業コードです。

質問: 水準器用のボールを作る必要があります。最も滑らかな水準器である必要はありません。ボールを水準器内に閉じ込めて、加速度計の結果に基づいて動かす方法を見つけることができれば、ラリーと同じくらい幸せです :)/

誰かが私をこれらの3つのことに関して正しい方向に向けてください:

  1. アニメーションを領域内に限定する
  2. サークルになる監禁エリア、作り方

前もって感謝します。H.

4

1 に答える 1

1

わかりました私は答えを得ました。それが誰かを助けることを願っています。中央から角までの距離 (半径) を計算して、角をオフセットする必要があります。

また、加速度計を方向センサーに変更しました。これにより、X 軸と Y 軸で電話の 3D 回転を取得できます。

次のコードは動作するコードであり、私はそれらをテストしました。私は Android 2.3.3+ を使用しています。これはアプリケーションの目的ではないため、ボールの動きはあまりスムーズではありません。

動きを滑らかにするために、タイマーと衝突検出も追加する必要があると思います。アンドロイドのサンプルを確認してください。

コードもまだリファクタリングしていません。したがって、これは製品レベルのコードではありません:)

コード:

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;
    }

}

乾杯。

于 2013-05-08T06:51:16.770 に答える