我正在使用预览来显示相机在屏幕上看到的内容。
我可以使一切工作正常,表面创建,表面设置并显示表面。
然而,在纵向模式下,它始终以不正确的90度角显示图片。
如图所示:
我知道使用以下代码将直接设置图片:
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
但是我在Activity中有预览,其中包含其他元素,并且我的Activity在横向模式下显示没有意义。 (默认禁用)
所以我想知道是否只是改变预览的方向?并在“纵向”模式下正确显示我的其余活动?
或者无论如何旋转预览以便正确显示?
答案 0 :(得分:142)
这个问题似乎是作为某些硬件see here的错误开始的,但可以通过使用API 8中可用的mCamera.setDisplayOrientation(度)调用来克服。所以这就是我实现它的方法:
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
if (isPreviewRunning) {
mCamera.stopPreview();
}
Parameters parameters = mCamera.getParameters();
Display display = ((WindowManager)getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
if(display.getRotation() == Surface.ROTATION_0) {
parameters.setPreviewSize(height, width);
mCamera.setDisplayOrientation(90);
}
if(display.getRotation() == Surface.ROTATION_90) {
parameters.setPreviewSize(width, height);
}
if(display.getRotation() == Surface.ROTATION_180) {
parameters.setPreviewSize(height, width);
}
if(display.getRotation() == Surface.ROTATION_270) {
parameters.setPreviewSize(width, height);
mCamera.setDisplayOrientation(180);
}
mCamera.setParameters(parameters);
previewCamera();
}
And the previewCamera method :
public void previewCamera() {
try {
mCamera.setPreviewDisplay(mSurfaceHolder);
mCamera.startPreview();
isPreviewRunning = true;
} catch(Exception e) {
Log.d(APP_CLASS, "Cannot start preview", e);
}
}
这是在HTC Desire上我不得不首先在每个旋转检查中输入记录语句来说明旋转是什么,然后在设备上调试并在旋转设备时观察logCat输出。对于HTC Desire来说,0就是你想象中的手机(人像),90度正在将手机转动90度(逆时针)(我原以为它是顺时针方向)。在代码中你会看到当手机处于90度或180度时我不需要进行任何显示旋转 - 设备似乎自己处理了这个问题。只有一个点不能正常工作:270度旋转是指您将设备顺时针旋转90度并且显示旋转计数器正常,但如果您将设备逆时针旋转270度,它似乎无法正确补偿。 / p>
P.S。请注意在适当的旋转中宽度和高度的交换。
答案 1 :(得分:16)
尝试设置显示方向。它解决了我的问题。
mCamera.setDisplayOrientation(90);
答案 2 :(得分:13)
public void surfaceCreated(SurfaceHolder holder) {
mCamera = Camera.open();
mCamera.setDisplayOrientation(90);
try {
mCamera.setPreviewDisplay(holder);
mCamera.setPreviewCallback(new PreviewCallback() {
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
试试这段代码
答案 3 :(得分:4)
我遇到前置摄像头问题(颠倒问题)。然后我使用了Android Docs -
中记录的以下方法public void setCameraDisplayOrientation(Activity activity , int icameraId , Camera camera1s)
{
CameraInfo cameraInfo = new CameraInfo();
Camera.getCameraInfo(icameraId, cameraInfo);
int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
int degrees = 0; // k
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 (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT)
{
// cameraType=CAMERATYPE.FRONT;
result = (cameraInfo.orientation + degrees) % 360;
result = (360 - result) % 360; // compensate the mirror
}
else
{ // back-facing
result = (cameraInfo.orientation - degrees + 360) % 360;
}
// displayRotate=result;
camera.setDisplayOrientation(result);
}
答案 4 :(得分:3)
我接受了mCamera.setDisplayOrientation(90)的建议;但也旋转了位图,因为出于某种原因,其他方法在版本2.3.3中对我不起作用。
为了旋转位图,我做了这个:
Matrix matrix = new Matrix();
matrix.postRotate(90);
imageView1 = new ImageView(this);
Bitmap bitmap = BitmapFactory.decodeFile(files[i].getAbsolutePath());
Bitmap rotatedBitmap = Bitmap.createBitmap(bitmap , 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
Bitmap scaledBitmap = Bitmap.createScaledBitmap(rotatedBitmap, 80, 80, true);
imageView1.setImageBitmap(scaledBitmap);
答案 5 :(得分:0)
我已经将我的代码与教程1进行了比较,最终修复它的是将以下代码放入我的AndroidManifext.xml中:
在<activity>
标记中:
android:screenOrientation="landscape"
android:configChanges="keyboardHidden|orientation">
答案 6 :(得分:0)
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// If your preview can change or rotate, take care of those events here.
// Make sure to stop the preview before resizing or reformatting it.
if (mHolder.getSurface() == null) {
// preview surface does not exist
return;
}
try {
mCamera.stopPreview();
} catch (Exception e) {
e.printStackTrace();
}
Camera.Parameters parameters = mCamera.getParameters();
Display display = ((WindowManager) getContext().getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
if (display.getRotation() == Surface.ROTATION_0) {
parameters.setPreviewSize(h, w);
mCamera.setDisplayOrientation(90);
}
if (display.getRotation() == Surface.ROTATION_90) {
parameters.setPreviewSize(w, h);
mCamera.setDisplayOrientation(0);
}
if (display.getRotation() == Surface.ROTATION_180) {
parameters.setPreviewSize(h, w);
mCamera.setDisplayOrientation(270);
}
if (display.getRotation() == Surface.ROTATION_270) {
parameters.setPreviewSize(w, h);
mCamera.setDisplayOrientation(180);
}
previewCamera();
}
public void previewCamera() {
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (Exception e) {
//Log.d(APP_CLASS, "Cannot start preview", e);
e.printStackTrace();
}
}
答案 7 :(得分:0)
我认为SENSOR_ORIENTATION值将解释用于旋转的值,而不是硬编码到90度
CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
if (manager == null) {
Log.i(TAG, "camera manager is null");
return;
}
for (String id: manager.getCameraIdList()) {
CameraCharacteristics characteristics = manager.getCameraCharacteristics(id);
Integer orientation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
Log.i(TAG, "camera sensor orientation is " + orientation);
}