Android自定义相机图像以错误的方向保存

时间:2014-01-09 23:24:30

标签: android camera orientation

我正在尝试为Android应用程序创建自定义相机。我已成功使用自己的客户界面获取相机拍照并保存。 SurfaceView预览也以纵向模式显示(也是需要的)。我的问题是,保存图片后,它们不会以拍摄照片时相机所在的方向显示。我知道在这里有一些与我非常相似的问题,但他们无法帮助我。我用来测试它的电话(当然在模拟器之外)是HTC Evo 4G。下面是我的代码细分。非常感谢您提供的任何帮助!请注意,我在一个类中执行所有这些操作,并将图像保存为文件而不是位图。

清单

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

<activity android:name=".CameraClass"
            android:screenOrientation="portrait" />

按钮单击

btn_takepicture.setOnClickListener(new View.OnClickListener() {

                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    mCamera.takePicture(null, null, pic_call);

                    Toast.makeText(getApplicationContext(), "Picture Added!", Toast.LENGTH_SHORT).show();
            }
        });

图片回调方法

private PictureCallback pic_call= new PictureCallback() {
        public void onPictureTaken(byte[] datas, Camera mCamera) {
            // TODO Auto-generated method stub  
            String root = Environment.getExternalStorageDirectory().toString(); 
            File myDir = new File(root + "/Images/");  
            myDir.mkdirs();
            if (myDir.exists()){

        }

        Random generator = new Random(); 
        int n = 10000;
        n = generator.nextInt(n);
        String fname = "Image"+ n +".jpg";
        File file = new File (myDir, fname); 
        Uri uriSavedImage = Uri.fromFile(file);  


        sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, 
                Uri.parse("file://"+ Environment.getExternalStorageDirectory())));
        Intent is = new Intent(CameraClass.this, Display.class);
        is.putExtras(basket);

        try {
            file.createNewFile();
            FileOutputStream fos = new FileOutputStream(file);
            fos.write(datas);
            fos.close();
        } catch (FileNotFoundException e) {  

        } catch (IOException e) {                
        }
        startActivity(is);
    }

};

相机暂停/发布方式

@Override
    protected void onPause() { 
        super.onPause();
        releaseCamera();   
    }

    private void releaseCamera() {
        // TODO Auto-generated method stub
        if (mCamera != null){
            mCamera.release();
            mCamera = null;   
        }
    }

表面改变方法

@Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,
            int height) {
        // TODO Auto-generated method stub
        if (surfaceHolder.getSurface() == null) {

        }
        try {
            mCamera.stopPreview();
        }
        catch (Exception e) {

        }
        try {
            mCamera.setPreviewDisplay(surfaceHolder);
            mCamera.startPreview();
        }
        catch (Exception e) {
            Log.d("TAG", "Error starting mCamera preview: " + e.getMessage());
        }
        Camera.Parameters parameters = mCamera.getParameters();
        parameters.set("orientation", "portrait");

        if(mCamera != null) {
            try {
                mCamera.setPreviewDisplay(surfaceHolder);
                mCamera.startPreview();
                previewing = true;
            }
            catch (IOException e) {
                e.printStackTrace();
            }
        }
    } 

表面创建

public void surfaceCreated(SurfaceHolder holder) {
        try {
            mCamera = Camera.open();
            camParam = mCamera.getParameters();
            Camera.Parameters params = mCamera.getParameters();
            String currentversion = android.os.Build.VERSION.SDK;
            Log.d("System out", "currentVersion " + currentversion);
            int currentInt = android.os.Build.VERSION.SDK_INT;
            Log.d("System out", "currentVersion " + currentInt);

            if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
                if (currentInt != 7) {
                    mCamera.setDisplayOrientation(90);
                } else {
                    Log.d("System out", "Portrait " + currentInt);

                    params.setRotation(90);

                    mCamera.setParameters(params);
                }
            }
            if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
                if (currentInt != 7) {
                    mCamera.setDisplayOrientation(0);
                } else {
                    Log.d("System out", "Landscape " + currentInt);
                    params.set("orientation", "landscape");
                    params.set("rotation", 90);
                    mCamera.setParameters(params);
                }
            }
            mCamera.setPreviewDisplay(holder);
            mCamera.startPreview();
        } catch (IOException e) {
            Log.d("CAMERA", e.getMessage());
        }
    } 

表面破坏方法

@Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        // TODO Auto-generated method stub

    }

设置相机方向方法

public static void setCameraDisplayOrientation(Activity activity, int cameraID, android.hardware.Camera mCamera) {
        Camera.CameraInfo info = new Camera.CameraInfo();
        Camera.getCameraInfo(cameraID, info);
        int rotation = activity.getWindowManager().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;
        }
        else {
            result = (info.orientation - degrees + 360) % 360;
        }
        mCamera.setDisplayOrientation(result);
    }

1 个答案:

答案 0 :(得分:4)

某些设备在保存时不会旋转图像,而是设置一个EXIF标题,说“嘿,图像查看器!您可以在显示时旋转此图像吗?kthxbye”。

这就是为什么在my CWAC-Camera library中,我会通过旋转来旋转这些图像,因为并非所有图像查看者都会尊重这些EXIF标题。