简体   繁体   中英

Android Custom Camera Image Saved in Wrong Orientation

I am attempting to create a custom camera for an Android application. I have successfully gotten the camera with my own customer interface to take pictures, and save them. The SurfaceView preview is displaying in Portrait mode (which is desired) as well. My problem is that after the pictures are saved, they aren't displayed in the orientation that the camera was in when the picture was taken. I know there are a few questions very similar to mine on here, but they haven't been able to assist me. The phone that I am using for testing this (outside of the emulator of course) is an HTC Evo 4G. Below is my code broken down. Thank you so much for any help that you can provide! Please note, I am doing all of this in a single class, and am saving the Image as a File and NOT as a Bitmap.

    <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);
    }

Some devices do not rotate the image when saving it, but rather set an EXIF header saying "hey, image viewer! could you, like, rotate this image when you display it? kthxbye".

That's why in my CWAC-Camera library , I go through the gyrations to rotate those images, as not all image viewers will honor those EXIF headers.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM