Picture taken from camera displayed in ImageView i

2019-03-02 13:43发布

问题:

I am using the following code to take a picture and then display it on screen to the user using an ImageView. I want the picture to be displayed fullscreen (like on snapchat). However, the picture is always displayed like this horizontally with a white screen everywhere else:

This is my layout:

<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

<FrameLayout
    android:id="@+id/camera_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

</FrameLayout>
<ImageView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:visibility="gone"
    android:id="@+id/picturedisplay"/>

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/imgClose"
    android:layout_gravity="right|bottom"
    android:text="Flip Cam"
    android:padding="20dp"/>
<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/snap"
    android:text="Capture"
    android:layout_gravity="center|bottom"
    android:padding="20dp"/>
<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Flash"
    android:id="@+id/imgOpen"
    android:layout_gravity="left|bottom"
    android:padding="20dp"/>

and the code:

public class CameraScreen extends Activity {
private Camera mCamera = null;
private SessionManager session;
private String rand_img;
private ImageView preview_pic;
private Bitmap bitmap;
private CameraPreview mCameraView = null;
private byte[] photo;
static final int CAM_REQUEST = 1;
private RandomString randomString = new RandomString(10);
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_camera_screen);
    session = new SessionManager(getApplicationContext());
    try {
        mCamera = Camera.open();//you can use open(int) to use different cameras
    } catch (Exception e) {
        Log.d("ERROR", "Failed to get camera: " + e.getMessage());
    }


    if (mCamera != null) {
        mCameraView = new CameraPreview(this, mCamera);//create a SurfaceView to show camera data
        FrameLayout camera_view = (FrameLayout) findViewById(R.id.camera_view);
        camera_view.addView(mCameraView);//add the SurfaceView to the layout
    }

    //btn to close the application
    Button imgClose = (Button) findViewById(R.id.imgClose);
    imgClose.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            System.exit(0);
        }
    });
    //btn to close the application
    Button logout = (Button) findViewById(R.id.imgOpen);
    logout.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            session.logOut();
            Intent a = new Intent(CameraScreen.this, MainActivity.class);
            startActivity(a);
            finish();
        }
    });
    Button snap = (Button) findViewById(R.id.snap);
    snap.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            mCamera.takePicture(shutterCallback, rawCallback, jpegCallback);
        }
    });
}

@Override
protected void onPause() {
    super.onPause();
    if (mCamera != null) {
        mCamera.setPreviewCallback(null);
        mCameraView.getHolder().removeCallback(mCameraView);
        mCamera.release();
    }
}
@Override
public void onResume() {
    super.onResume();

    // Get the Camera instance as the activity achieves full user focus
    if (mCamera == null) {
        initializeCamera(); // Local method to handle camera initialization
    }
}



protected void initializeCamera(){
    // Get an instance of Camera Object
    try{
        mCamera = Camera.open();//you can use open(int) to use different cameras
    } catch (Exception e){
        Log.d("ERROR", "Failed to get camera: " + e.getMessage());
    }


    if(mCamera != null) {
        mCameraView = new CameraPreview(this, mCamera);//create a SurfaceView to show camera data
        FrameLayout camera_view = (FrameLayout)findViewById(R.id.camera_view);
        camera_view.addView(mCameraView);//add the SurfaceView to the layout
    }
}
   private File getFile() {
    File sdCard = Environment.getExternalStorageDirectory();
    File folder = new File(sdCard.getAbsolutePath() +"/city_life_pic");
    if (!folder.exists()) {
        folder.mkdir();
    }
    rand_img = randomString.nextString() + ".jpg";
    File image = new File(folder,rand_img);
    return image;
}

Camera.ShutterCallback shutterCallback = new Camera.ShutterCallback() {
    public void onShutter() {
                     Log.d("ON SHUTTER", "onShutter'd");
    }
};

Camera.PictureCallback rawCallback = new Camera.PictureCallback() {
    public void onPictureTaken(byte[] data, Camera camera) {
                     Log.d("ON PICTURE RAW", "onPictureTaken - raw");
    }
};

Camera.PictureCallback jpegCallback = new Camera.PictureCallback() {
    public void onPictureTaken(byte[] data, Camera camera) {
        photo = data;
        new SaveImageTask().execute(data);
        Log.d("ON PICTURE JPEG", "onPictureTaken - jpeg");
    }
};

private class SaveImageTask extends AsyncTask<byte[], Void, Void> {

    @Override
    protected Void doInBackground(byte[]... data) {
        FileOutputStream outStream = null;

        // Write to SD Card
        try {
            bitmap  = decodeByteArray(photo, 0, photo.length);
            File outFile = getFile();
            outStream = new FileOutputStream(outFile);
            outStream.write(data[0]);

            ExifInterface exif=new ExifInterface(outFile.toString());

            Log.d("EXIF value", exif.getAttribute(ExifInterface.TAG_ORIENTATION));
            if(exif.getAttribute(ExifInterface.TAG_ORIENTATION).equalsIgnoreCase("6")){
                bitmap= rotate(bitmap, 90);
            } else if(exif.getAttribute(ExifInterface.TAG_ORIENTATION).equalsIgnoreCase("8")){
                bitmap= rotate(bitmap, 270);
            } else if(exif.getAttribute(ExifInterface.TAG_ORIENTATION).equalsIgnoreCase("3")){
                bitmap= rotate(bitmap, 180);
            } else if(exif.getAttribute(ExifInterface.TAG_ORIENTATION).equalsIgnoreCase("0")){
                bitmap= rotate(bitmap, 90);
            }

            boolean bo = bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
            outStream.flush();
            outStream.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
        }
        return null;
    }

    @Override
    protected void onPostExecute(Void aVoid) {
        FrameLayout camera_view = (FrameLayout)findViewById(R.id.camera_view);
        preview_pic = (ImageView) findViewById(R.id.picturedisplay);
        camera_view.setVisibility(View.GONE);
        preview_pic.setVisibility(View.VISIBLE);
        preview_pic.setImageBitmap(bitmap);
    }
}
public static Bitmap rotate(Bitmap bitmap, int degree) {
    int w = bitmap.getWidth();
    int h = bitmap.getHeight();

    Matrix mtx = new Matrix();
    //       mtx.postRotate(degree);
    mtx.setRotate(degree);

    return Bitmap.createBitmap(bitmap, 0, 0, w, h, mtx, true);
}

}

EDIT ROTATION CODE:

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;
            }
            if (currentCamInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
                //switch camera to back camera
                mCamera = Camera.open(camBackId);
                result = (currentCamInfo.orientation + degrees) % 360;
                result = (360 - result) % 360; // compensate the mirror
            } else {
                //switch camera to front camera
                mCamera = Camera.open(camFrontId);
                result = (currentCamInfo.orientation - degrees + 360) % 360;

            }
            if (mCamera != null) {
                mCamera.setDisplayOrientation(result);
                //rotate camera
                mCameraView = new CameraPreview(this, mCamera);//create a SurfaceView to show camera data
                camera_view.addView(mCameraView);//add the SurfaceView to the layout
                Camera.Parameters p = mCamera.getParameters();
                p.setRotation(90);
                mCamera.setParameters(p);
            }

回答1:

Try adding mCamera.setDisplayOrientation(90) to your initializeCamera() method. You can also calculate the right orientation settings based on this code.

public static int getCameraDisplayOrientation(int cameraId, android.hardware.Camera camera) {
    android.hardware.Camera.CameraInfo info =
            new android.hardware.Camera.CameraInfo();
    android.hardware.Camera.getCameraInfo(cameraId, info);
    int rotation = Session.currentActivity.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;  // compensate the mirror
    } else {  // back-facing
        result = (info.orientation - degrees + 360) % 360;
    }
    return result;
}