【问题标题】:Android how to fix camera orientationAndroid如何修复相机方向
【发布时间】:2013-12-02 14:34:12
【问题描述】:

注意相机的视图(不是捕获的图像)是如何向左翻转的(上图),Activity 的方向是正确的,但是相机视图是混乱的,请帮助我 :) 谢谢你。

这是 XML 布局文件:

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

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center|top"
            android:orientation="vertical" >

            <SurfaceView
                android:id="@+id/camerapreview"
                android:layout_margin="10dp"
                android:layout_width="300dp"
                android:layout_height="300dp" />
        </LinearLayout>
    </LinearLayout>

</LinearLayout>

这里是活动的代码:

public class CustomCameraActivity extends Activity implements SurfaceHolder.Callback {

    Camera camera;
    SurfaceView surfaceView;
    SurfaceHolder surfaceHolder;
    boolean previewing = false;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.camera);

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

    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        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;
    }
}

【问题讨论】:

标签: android android-activity camera orientation


【解决方案1】:

我找到了解决方案here。 @Ed Jellard 的回答。

我只需在surfaceCreated(SurfaceHolder holder) 方法上添加camera.setDisplayOrientation(90);,现在显示在正确的角度。

看看快乐的 T-REX :)

【讨论】:

  • 我不认为这只 T-REX 很高兴 :P 无论如何,它帮助了我。谢谢。
  • @AmitGupta 在我看来很开心。 :D
  • 这仅在设备的相机以横向方式定向时才有效。虽然这适用于大多数人,但不适用于 Nexus 5X 等摄像头为反向横向的设备(您需要将方向设置为 180)
  • 这仅适用于此设备,并且您已在其他设备上旋转图像。这可能是正确的解决方案:captechconsulting.com/blogs/…
【解决方案2】:

这个问题很久以前就解决了,但是我遇到了一些困难,所以这是我的最终解决方案,希望这对其他人有帮助:

public void startPreview() {
        try {
            Log.i(TAG, "starting preview: " + started);

            // ....
            Camera.CameraInfo camInfo = new Camera.CameraInfo();
            Camera.getCameraInfo(cameraIndex, camInfo);
            int cameraRotationOffset = camInfo.orientation;
            // ...

            Camera.Parameters parameters = camera.getParameters();
            List<Camera.Size> previewSizes = parameters.getSupportedPreviewSizes();
            Camera.Size previewSize = null;
            float closestRatio = Float.MAX_VALUE;

            int targetPreviewWidth = isLandscape() ? getWidth() : getHeight();
            int targetPreviewHeight = isLandscape() ? getHeight() : getWidth();
            float targetRatio = targetPreviewWidth / (float) targetPreviewHeight;

            Log.v(TAG, "target size: " + targetPreviewWidth + " / " + targetPreviewHeight + " ratio:" + targetRatio);
            for (Camera.Size candidateSize : previewSizes) {
                float whRatio = candidateSize.width / (float) candidateSize.height;
                if (previewSize == null || Math.abs(targetRatio - whRatio) < Math.abs(targetRatio - closestRatio)) {
                    closestRatio = whRatio;
                    previewSize = candidateSize;
                }
            }

            int rotation = getWindowManager().getDefaultDisplay().getRotation();
            int degrees = 0;
            switch (rotation) {
            case Surface.ROTATION_0:
                degrees = 0;
                break; // Natural orientation
            case Surface.ROTATION_90:
                degrees = 90;
                break; // Landscape left
            case Surface.ROTATION_180:
                degrees = 180;
                break;// Upside down
            case Surface.ROTATION_270:
                degrees = 270;
                break;// Landscape right
            }
            int displayRotation;
            if (isFrontFacingCam) {
                displayRotation = (cameraRotationOffset + degrees) % 360;
                displayRotation = (360 - displayRotation) % 360; // compensate
                                                                    // the
                                                                    // mirror
            } else { // back-facing
                displayRotation = (cameraRotationOffset - degrees + 360) % 360;
            }

            Log.v(TAG, "rotation cam / phone = displayRotation: " + cameraRotationOffset + " / " + degrees + " = "
                    + displayRotation);

            this.camera.setDisplayOrientation(displayRotation);

            int rotate;
            if (isFrontFacingCam) {
                rotate = (360 + cameraRotationOffset + degrees) % 360;
            } else {
                rotate = (360 + cameraRotationOffset - degrees) % 360;
            }

            Log.v(TAG, "screenshot rotation: " + cameraRotationOffset + " / " + degrees + " = " + rotate);

            Log.v(TAG, "preview size: " + previewSize.width + " / " + previewSize.height);
            parameters.setPreviewSize(previewSize.width, previewSize.height);
            parameters.setRotation(rotate);
            camera.setParameters(parameters);
            camera.setPreviewDisplay(mHolder);
            camera.startPreview();

            Log.d(TAG, "preview started");

            started = true;
        } catch (IOException e) {
            Log.d(TAG, "Error setting camera preview: " + e.getMessage());
        }
    }

【讨论】:

  • 我不知道如何处理变量。如果您添加有关其余部分的更多信息,那就太好了。代码中有很多红色变量。
【解决方案3】:

Camera.CameraInfo 类中有一个属性,名为orientation。它返回整数。您可以获取当前方向,然后进行相应的更改。

请参阅此 answer 处理方向和 CameraInfo 类。

我相信这会对你有所帮助。

【讨论】:

    【解决方案4】:

    当您旋转手机时,相机会自动旋转,但是如果您希望相机或图库中的图像处于正确的方向,请使用:-

    public void rotate(String filePath){
                  Bitmap cameraBitmap = null;
                BitmapFactory.Options bmOptions = new BitmapFactory.Options();
                bmOptions.inJustDecodeBounds = false;
                bmOptions.inPurgeable = true;
                bmOptions.inBitmap = cameraBitmap; 
                bmOptions.inMutable = true; 
    
            cameraBitmap = BitmapFactory.decodeFile(filePath,bmOptions); 
            // Your image file path
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                cameraBitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);
    
    
            ExifInterface exif = new ExifInterface(filePath);
            float rotation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);  
            System.out.println(rotation);
    
            float rotationInDegrees = exifToDegrees(rotation);
            System.out.println(rotationInDegrees);
    
            Matrix matrix = new Matrix();
            matrix.postRotate(rotationInDegrees);
    
            Bitmap rotatedBitmap = Bitmap.createBitmap(cameraBitmap , 0, 0, cameraBitmap.getWidth(), cameraBitmap.getHeight(), matrix, true);
            FileOutputStream fos=new FileOutputStream(filePath);
            rotatedBitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
            fos.write(bos.toByteArray());
            cameraBitmap.recycle();
            System.gc();
            fos.flush();
            fos.close();
    }
    
    private static float exifToDegrees(float exifOrientation) {        
        if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_90) { return 90; } 
        else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_180) {  return 180; } 
        else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_270) {  return 270; }            
        return 0;    
    } 
    

    【讨论】:

    • 这不是一个实际的答案,阅读OP comment
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多