1

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: enter image description here

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);
            }
Alk
  • 5,215
  • 8
  • 47
  • 116

1 Answers1

2

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;
}
Endre Börcsök
  • 477
  • 1
  • 8
  • 19
  • I got this to work for the back facing camera, specifically the `setRotation(90);` with the camera parameters worked. However, I am having a problem when using the front facing camera, the pictures come up upside down when the same exact code is applied as before. – Alk Feb 18 '16 at 20:57
  • You can try setting it to either 0,90,180 or 270 depending on the native orientation of the camera. – Endre Börcsök Feb 18 '16 at 21:02
  • Setting it to 270 makes the image the right orientation however it appears like a mirror image, setting to 90 makes it upside down, and 180 is just flipped in the same position. – Alk Feb 18 '16 at 21:04
  • Images taken by the fron facing camera are often mirrored to my knowledge. Please take a picture with your device's native camera application and confirm if it takes a mirrored image. – Endre Börcsök Feb 18 '16 at 21:08
  • is there a way to undo this effect, since my app goes straight from the cam preview to the mirrored image and this looks pretty sloppy since you can easily see that it has been mirrored – Alk Feb 18 '16 at 21:14
  • Yes, you can apply this method to your ImageView: imgView.setScaleX(-1.0f). If you want to reuse the image (eg. you save it/upload it) make sure you flip it when needed. You can use Bitmap for that purpose : http://stackoverflow.com/questions/7925278/drawing-mirrored-bitmaps-in-android – Endre Börcsök Feb 18 '16 at 21:20