android camera移动方向_Android Camera SurfaceView方向

本文介绍如何在Android应用中使用Camera和SurfaceView,并根据设备的移动方向自动调整显示。通过监听设备方向变化并结合SensorManager,实现相机预览画面跟随设备方向旋转,同时在拍照时设置正确的元数据以指示旋转级别。
摘要由CSDN通过智能技术生成

我的实现方式:

private Camera mCamera;

private OrientationEventListener mOrientationEventListener;

private int mOrientation =  -1;

private static final int ORIENTATION_PORTRAIT_NORMAL =  1;

private static final int ORIENTATION_PORTRAIT_INVERTED =  2;

private static final int ORIENTATION_LANDSCAPE_NORMAL =  3;

private static final int ORIENTATION_LANDSCAPE_INVERTED =  4;

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

// force Landscape layout

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR | ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

/*

Your other initialization code here

*/

}

@Override

protected void onResume() {

super.onResume();

if (mOrientationEventListener == null) {

mOrientationEventListener = new OrientationEventListener(this, SensorManager.SENSOR_DELAY_NORMAL) {

@Override

public void onOrientationChanged(int orientation) {

// determine our orientation based on sensor response

int lastOrientation = mOrientation;

if (orientation >= 315 || orientation < 45) {

if (mOrientation != ORIENTATION_PORTRAIT_NORMAL) {

mOrientation = ORIENTATION_PORTRAIT_NORMAL;

}

}

else if (orientation < 315 && orientation >= 225) {

if (mOrientation != ORIENTATION_LANDSCAPE_NORMAL) {

mOrientation = ORIENTATION_LANDSCAPE_NORMAL;

}

}

else if (orientation < 225 && orientation >= 135) {

if (mOrientation != ORIENTATION_PORTRAIT_INVERTED) {

mOrientation = ORIENTATION_PORTRAIT_INVERTED;

}

}

else { // orientation <135 && orientation > 45

if (mOrientation != ORIENTATION_LANDSCAPE_INVERTED) {

mOrientation = ORIENTATION_LANDSCAPE_INVERTED;

}

}

if (lastOrientation != mOrientation) {

changeRotation(mOrientation, lastOrientation);

}

}

};

}

if (mOrientationEventListener.canDetectOrientation()) {

mOrientationEventListener.enable();

}

}

@Override protected void onPause() {

super.onPause();

mOrientationEventListener.disable();

}

/**

* Performs required action to accommodate new orientation

* @param orientation

* @param lastOrientation

*/

private void changeRotation(int orientation, int lastOrientation) {

switch (orientation) {

case ORIENTATION_PORTRAIT_NORMAL:

mSnapButton.setImageDrawable(getRotatedImage(android.R.drawable.ic_menu_camera, 270));

mBackButton.setImageDrawable(getRotatedImage(android.R.drawable.ic_menu_revert, 270));

Log.v("CameraActivity", "Orientation = 90");

break;

case ORIENTATION_LANDSCAPE_NORMAL:

mSnapButton.setImageResource(android.R.drawable.ic_menu_camera);

mBackButton.setImageResource(android.R.drawable.ic_menu_revert);

Log.v("CameraActivity", "Orientation = 0");

break;

case ORIENTATION_PORTRAIT_INVERTED:

mSnapButton.setImageDrawable(getRotatedImage(android.R.drawable.ic_menu_camera, 90));

mBackButton.setImageDrawable(getRotatedImage(android.R.drawable.ic_menu_revert, 90));

Log.v("CameraActivity", "Orientation = 270");

break;

case ORIENTATION_LANDSCAPE_INVERTED:

mSnapButton.setImageDrawable(getRotatedImage(android.R.drawable.ic_menu_camera, 180));

mBackButton.setImageDrawable(getRotatedImage(android.R.drawable.ic_menu_revert, 180));

Log.v("CameraActivity", "Orientation = 180");

break;

}

}

/**

* Rotates given Drawable

* @param drawableId    Drawable Id to rotate

* @param degrees       Rotate drawable by Degrees

* @return              Rotated Drawable

*/

private Drawable getRotatedImage(int drawableId, int degrees) {

Bitmap original = BitmapFactory.decodeResource(getResources(), drawableId);

Matrix matrix = new Matrix();

matrix.postRotate(degrees);

Bitmap rotated = Bitmap.createBitmap(original, 0, 0, original.getWidth(), original.getHeight(), matrix, true);

return new BitmapDrawable(rotated);

}

然后在PictureCallback中设置元数据以指示旋转级别:

private Camera.PictureCallback mJpegCallback = new Camera.PictureCallback() {

@Override

public void onPictureTaken(byte[] data, Camera camera) {

try {

// Populate image metadata

ContentValues image = new ContentValues();

// additional picture metadata

image.put(Media.DISPLAY_NAME, [picture name]);

image.put(Media.MIME_TYPE, "image/jpg");

image.put(Media.TITLE, [picture title]);

image.put(Media.DESCRIPTION, [picture description]);

image.put(Media.DATE_ADDED, [some time]);

image.put(Media.DATE_TAKEN, [some time]);

image.put(Media.DATE_MODIFIED, [some time]);

// do not rotate image, just put rotation info in

switch (mOrientation) {

case ORIENTATION_PORTRAIT_NORMAL:

image.put(Media.ORIENTATION, 90);

break;

case ORIENTATION_LANDSCAPE_NORMAL:

image.put(Media.ORIENTATION, 0);

break;

case ORIENTATION_PORTRAIT_INVERTED:

image.put(Media.ORIENTATION, 270);

break;

case ORIENTATION_LANDSCAPE_INVERTED:

image.put(Media.ORIENTATION, 180);

break;

}

// store the picture

Uri uri = getContentResolver().insert(

Media.EXTERNAL_CONTENT_URI, image);

try {

Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0,

data.length);

OutputStream out = getContentResolver().openOutputStream(

uri);

boolean success = bitmap.compress(

Bitmap.CompressFormat.JPEG, 75, out);

out.close();

if (!success) {

finish(); // image output failed without any error,

// silently finish

}

} catch (Exception e) {

e.printStackTrace();

// handle exceptions

}

mResultIntent = new Intent();

mResultIntent.setData(uri);

} catch (Exception e) {

e.printStackTrace();

}

finish();

}

};

希望对您有所帮助。

更新现在,当基于景观的设备出现时,在OrientationEventListener中需要对其进行附加检查。

Display display = ((WindowManager)getSystemService(WINDOW_SERVICE)).getDefaultDisplay();

if (display.getOrientation() == Surface.ROTATION_0) {

// landscape oriented devices

} else {

// portrait oriented device

}

完整代码(LC有点浪费,但可以轻松演示该方法)

@Override

public void onOrientationChanged(int orientation) {

// determine our orientation based on sensor response

int lastOrientation = mOrientation;

Display display = ((WindowManager)getSystemService(WINDOW_SERVICE)).getDefaultDisplay();

if (display.getOrientation() == Surface.ROTATION_0) {   // landscape oriented devices

if (orientation >= 315 || orientation < 45) {

if (mOrientation != ORIENTATION_LANDSCAPE_NORMAL) {

mOrientation = ORIENTATION_LANDSCAPE_NORMAL;

}

} else if (orientation < 315 && orientation >= 225) {

if (mOrientation != ORIENTATION_PORTRAIT_INVERTED) {

mOrientation = ORIENTATION_PORTRAIT_INVERTED;

}

} else if (orientation < 225 && orientation >= 135) {

if (mOrientation != ORIENTATION_LANDSCAPE_INVERTED) {

mOrientation = ORIENTATION_LANDSCAPE_INVERTED;

}

} else if (orientation <135 && orientation > 45) {

if (mOrientation != ORIENTATION_PORTRAIT_NORMAL) {

mOrientation = ORIENTATION_PORTRAIT_NORMAL;

}

}

} else {  // portrait oriented devices

if (orientation >= 315 || orientation < 45) {

if (mOrientation != ORIENTATION_PORTRAIT_NORMAL) {

mOrientation = ORIENTATION_PORTRAIT_NORMAL;

}

} else if (orientation < 315 && orientation >= 225) {

if (mOrientation != ORIENTATION_LANDSCAPE_NORMAL) {

mOrientation = ORIENTATION_LANDSCAPE_NORMAL;

}

} else if (orientation < 225 && orientation >= 135) {

if (mOrientation != ORIENTATION_PORTRAIT_INVERTED) {

mOrientation = ORIENTATION_PORTRAIT_INVERTED;

}

} else if (orientation <135 && orientation > 45) {

if (mOrientation != ORIENTATION_LANDSCAPE_INVERTED) {

mOrientation = ORIENTATION_LANDSCAPE_INVERTED;

}

}

}

if (lastOrientation != mOrientation) {

changeRotation(mOrientation, lastOrientation);

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值