相机:setDisplayOrientation 功能不适用于搭载 Android 2.3.6 的三星 Galaxy ACE [英] Camera : setDisplayOrientation function is not working for Samsung Galaxy ACE with Android 2.3.6
问题描述
我试图创建一个用于研究的简单相机应用程序.我阅读了 Android Camera 官方文档,然后开始编码.所以我做了一些步骤来让它工作
I was trying to create a simple camera application for research. I Read Android Camera Official Document and then started coding. so I did some steps to get it work
1.在应用中添加了相机功能所需的权限.
1.Added required permissions for Camera feature in app.
2.将我的活动锁定为仅肖像模式.
2.locked my activity to PORTRAIT mode only.
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
3.添加了几个相机回调来让我的相机正常工作.
3.Added several camera callbacks to get my camera works.
- SurfaceHolder.Callback,
- Camera.PreviewCallback
- 自动对焦回调
- ShutterCallback
- 用于 RAW 图像数据的 PictureCallback
- JPG 图片数据的 PictureCallback
4.在 surfaceChanged 方法中,我正在自定义相机设置.到目前为止,我已经为几乎所有的 android 设备工作了这个
4.In surfaceChanged method I am customizing camera settings. and so far I got working this for almost all android devices
- LG
- 香料
- 三星
- 宏达电
- Micromax
- 索尼
- 摩托罗拉
- Google Nexus 系列.
但是然后我在 Samsung Galaxy ACE 上使用 Android 版本 2.3.6 进行了测试并发现相机显示预览已旋转为横向模式.
But then I tested on Samsung Galaxy ACE with Android Version 2.3.6 and found Camera Display Preview is Rotated to landscape mode.
所以在放置 log-cat/break 点后,我知道以下方法不适用于这个特定的模型
So after putting log-cat/break points I come to know that below methods are not working for this particular model
//This method is not working for Samsung Galaxy ACE
camera.setDisplayOrientation(90);
//or
parameters.set("orientation", "portrait");
//or
parameters.setRotation(90);
注意: 我也在 Google 和 SO 上寻找了一堆解决方案,但到目前为止没有任何运气
- Issus 报告了这里
- 安卓相机surfaceview方向
- Android 人像锁定相机预览
- Android - 相机预览是横向的
- Android 相机旋转
- Android:相机预览已旋转
- 如何正确设置Android相机方向?
供您参考我的示例代码如下
For your reference My sample code is below
@Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
Log.v(TAG, "surfaceChanged get called");
if (previewing) {
camera.stopPreview();
previewing = false;
}
if (camera != null) {
try {
Camera.Parameters parameters = camera.getParameters();
List<Size> sizes = parameters.getSupportedPictureSizes();
Camera.Size result = null;
for (int i = 0; i < sizes.size(); i++) {
result = (Size) sizes.get(i);
Log.i("PictureSize", "Supported Size. Width: "
+ result.width + "height : " + result.height);
if (result.width == 640) {
parameters.setPreviewSize(result.width, result.height);// 640*480
parameters.setPictureSize(result.width, result.height);
} else {
}
}
//**************************************************************//
/*
* Here is the logic I have added to Manage Camera Display Orientation
* It checks Current Orientation and SDK and then rotate display to make it Portrait view.
*/
int currentSDKVersion = android.os.Build.VERSION.SDK_INT;
Log.d(TAG, "currentVersion " + currentSDKVersion);
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
if (currentSDKVersion != 7) {
camera.setDisplayOrientation(90);
parameters.setRotation(90);
} else {
parameters.setRotation(90);
/*
* params.set("orientation", "portrait");
* params.set("rotation",90);
*/
}
} else if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
if (currentSDKVersion != 7) {
camera.setDisplayOrientation(0);
} else {
parameters.set("orientation", "landscape");
parameters.set("rotation", 90);
}
}
//**************************************************************//
camera.setParameters(parameters);
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
camera.autoFocus(myAutoFocusCallback);
camera.setOneShotPreviewCallback(cameraPreviewCallback);
previewing = true;
} catch (IOException e) {
e.printStackTrace();
}
}
}
我的相机活动(MainActivity.java)完整代码是:
My Camera Activity (MainActivity.java) Full code is:
public class MainActivity extends Activity implements SurfaceHolder.Callback,
OnClickListener {
public static final String TAG = "CameraActivity";
private Context context = null;
Camera camera = null;
private SurfaceView surfaceView = null;
private SurfaceHolder surfaceHolder = null;
boolean previewing = false;
private LayoutInflater controlInflater = null;
private Button buttonTakePicture = null;
//private TextView textViewResultInfo = null;
@SuppressWarnings("deprecation")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Log.v(TAG, "onCreate get called");
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
//textViewResultInfo = (TextView) findViewById(R.id.textViewResultInfo);
context = this;
getWindow().setFormat(PixelFormat.UNKNOWN);
surfaceView = (SurfaceView) findViewById(R.id.surfaceview);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
controlInflater = LayoutInflater.from(getBaseContext());
View viewControl = controlInflater.inflate(R.layout.control, null);
LayoutParams layoutParamsControl = new LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
this.addContentView(viewControl, layoutParamsControl);
buttonTakePicture = (Button) findViewById(R.id.takepicture);
buttonTakePicture.setOnClickListener(this);
}
@Override
public void surfaceCreated(SurfaceHolder arg0) {
Log.v(TAG, "surfaceCreated get called");
camera = Camera.open();
if (camera != null) {
try {
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
previewing = true;
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
Log.v(TAG, "surfaceChanged get called");
if (previewing) {
camera.stopPreview();
previewing = false;
}
if (camera != null) {
try {
//new MainActivity().setCameraDisplayOrientation();
Camera.Parameters parameters = camera.getParameters();
// List<String> focusModes =
// parameters.getSupportedFocusModes();
// if (focusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO))
// {
// parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
// }
List<Size> sizes = parameters.getSupportedPictureSizes();
Camera.Size result = null;
for (int i = 0; i < sizes.size(); i++) {
result = (Size) sizes.get(i);
Log.i("PictureSize", "Supported Size. Width: "
+ result.width + "height : " + result.height);
if (result.width == 640) {
parameters.setPreviewSize(result.width, result.height);// 640*480
parameters.setPictureSize(result.width, result.height);
} else {
}
}
//**************************************************************//
Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
int rotation = display.getRotation();
Log.v(TAG, "Current Device Orientation is ="+rotation);
/*
* Here is the logic I have added to Manage Camera Display Orientation
* It checks Current Orientation and SDK and then rotate display to make it Portrait view.
*/
int currentSDKVersion = android.os.Build.VERSION.SDK_INT;
Log.d(TAG, "currentVersion " + currentSDKVersion);
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
if (currentSDKVersion != 7) {
Log.i(TAG, "ORIENTATION_PORTRAIT +SDK is: " + currentSDKVersion
+ "rotate 90");
camera.setDisplayOrientation(90);
parameters.setRotation(90);
} else {
Log.i(TAG, "ORIENTATION_PORTRAIT +SDK is: " + currentSDKVersion
+ "rotate 90");
parameters.setRotation(90);
/*
* params.set("orientation", "portrait");
* params.set("rotation",90);
*/
}
} else if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
if (currentSDKVersion != 7) {
Log.i(TAG, "ORIENTATION_LANDSCAPE +SDK is: " + currentSDKVersion
+ "rotate 90");
camera.setDisplayOrientation(0);
} else {
Log.i(TAG, "ORIENTATION_LANDSCAPE +SDK is: " + currentSDKVersion
+ "rotate 90");
parameters.set("orientation", "landscape");
parameters.set("rotation", 90);
}
}
//**************************************************************//
camera.setParameters(parameters);
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
camera.autoFocus(myAutoFocusCallback);
camera.setOneShotPreviewCallback(cameraPreviewCallback);
previewing = true;
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
public void surfaceDestroyed(SurfaceHolder arg0) {
Log.v(TAG, "surfaceDestroyed get called");
camera.stopPreview();
camera.release();
camera = null;
previewing = false;
}
public void setCameraDisplayOrientation()
{
Log.v(TAG, "setCameraDisplayOrientation get called");
if (camera == null)
{
Log.d(TAG,"setCameraDisplayOrientation - camera null");
return;
}
Camera.CameraInfo info = new Camera.CameraInfo();
Camera.getCameraInfo(1, info);
WindowManager winManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
int rotation = winManager.getDefaultDisplay().getRotation();
int degrees = 0;
switch (rotation)
{
case Surface.ROTATION_0: degrees = 0; break;
case Surface.ROTATION_90: degrees = 90; break;
case Surface.ROTATION_180: degrees = 180; break;
case Surface.ROTATION_270: degrees = 270; break;
}
int result;
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT)
{
result = (info.orientation + degrees) % 360;
result = (360 - result) % 360; // compensate the mirror
} else { // back-facing
result = (info.orientation - degrees + 360) % 360;
}
camera.setDisplayOrientation(result);
}
@Override
public void onClick(View v) {
Log.v(TAG, "onClick get called");
if (v == buttonTakePicture) {
camera.takePicture(myShutterCallback, myPictureCallback_RAW,
myPictureCallback_JPG);
}
}
private Camera.PreviewCallback cameraPreviewCallback = new Camera.PreviewCallback() {
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
Log.i(TAG, "onPreviewFrame size=" + data.length);
}
};
AutoFocusCallback myAutoFocusCallback = new AutoFocusCallback() {
@Override
public void onAutoFocus(boolean arg0, Camera arg1) {
Log.v(TAG, "onAutoFocus get called");
buttonTakePicture.setEnabled(true);
}
};
ShutterCallback myShutterCallback = new ShutterCallback() {
@Override
public void onShutter() {
Log.v(TAG, "onShutter get called");
}
};
PictureCallback myPictureCallback_RAW = new PictureCallback() {
@Override
public void onPictureTaken(byte[] arg0, Camera arg1) {
Log.v(TAG, "onPictureTaken-RAW get called");
}
};
public static Bitmap RotateBitmap(Bitmap source, float angle) {
Matrix matrix = new Matrix();
matrix.postRotate(angle);
return Bitmap.createBitmap(source, 0, 0, source.getWidth(),
source.getHeight(), matrix, true);
}
PictureCallback myPictureCallback_JPG = new PictureCallback() {
@Override
public void onPictureTaken(byte[] arg0, Camera arg1) {
Bitmap rawImage = BitmapFactory.decodeByteArray(arg0, 0,
arg0.length);
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
Log.v(TAG, "##### ORIENTATION_PORTRAIT ####");
rawImage = MainActivity.RotateBitmap(rawImage, 90);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
rawImage.compress(Bitmap.CompressFormat.JPEG, 100, stream);
arg0 = stream.toByteArray();
} else if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
Log.v(TAG, "##### ORIENTATION_LANDSCAPE #####");
}
Intent intent = new Intent(MainActivity.this, ResultActivity.class);
intent.putExtra("picture", arg0);
startActivity(intent);
Log.v(TAG, "onPictureTaken-JPG get called");
}
};
/**
* Get the size in bitmap.
*
* @param bitmap
* @return size in bytes
*/
@TargetApi(12)
public static int getBitmapSize(Bitmap bitmap) {
if (MainActivity.hasHoneycombMR1()) {
return bitmap.getByteCount();
}
// Pre HC-MR1
return bitmap.getRowBytes() * bitmap.getHeight();
}
public static boolean hasHoneycombMR1() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1;
}
}
编辑:我已在 开发者论坛但没有回应.
Edit : I have posted Comment on Developer forum but no response.
请!!有人对此问题有任何想法.
Please!! Someone have any Idea regarding this problem.
如果您能提出任何建议,我将不胜感激.
I would really appreciate for any kind of suggestion.
推荐答案
当我在运行 2.2.1 的原始 Galaxy Tab 时遇到类似问题时,我能够通过以下方式解决:
When I had a similar problem with the original Galaxy Tab running 2.2.1, I was able to solve it by doing the following:
Camera.Parameters parameters = camera.getParameters();
parameters.set("orientation", "portrait");
parameters.setRotation(90);
camera.setParameters(parameters);
但是,您似乎可能已经尝试过这种确切的组合,因为您在上面有相同(但被注释掉)的代码.但是,按照您现在拥有代码的方式,Ace 将绕过您拥有注释代码的位置,因为它是 API 级别 (10).在此块内专门尝试一下:
However, it looks like you may have already tried that exact combination, given that you have identical (but commented out) code above. However, the way you have the code right now, the Ace is going to bypass where you have that commented code because of it's API level (10). Try it specifically inside this block:
if (currentSDKVersion != 7) { }
如果它有效,请告诉我.谢谢!
And let me know if it works, please. Thanks!
这篇关于相机:setDisplayOrientation 功能不适用于搭载 Android 2.3.6 的三星 Galaxy ACE的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!