Mirror the front facing camera in Android

10,477

Solution 1

First when you open your camera instance with Camera.open() you should open front camera with Camera.open(getSpecialFacingCamera())

private int getSpecialFacingCamera() {
    int cameraId = -1;
    // Search for the front facing camera
    int numberOfCameras = Camera.getNumberOfCameras();
    for (int i = 0; i < numberOfCameras; i++) {
        Camera.CameraInfo info = new Camera.CameraInfo();
        Camera.getCameraInfo(i, info);
        if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
            cameraId = i;
            break;
        }
    }
    return cameraId;
}

Then in your callback method where camera data is converting in to image you can use this code to keep it normal

public void onPictureTaken(byte[] data, Camera camera){
            Bitmap newImage = null;
            Bitmap cameraBitmap;
            if (data != null) {
                cameraBitmap = BitmapFactory.decodeByteArray(data, 0, (data != null) ? data.length : 0);
                if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
                    // use matrix to reverse image data and keep it normal
                    Matrix mtx = new Matrix();
                    //this will prevent mirror effect
                    mtx.preScale(-1.0f, 1.0f);
                    // Setting post rotate to 90 because image will be possibly in landscape
                    mtx.postRotate(90.f);
                    // Rotating Bitmap , create real image that we want
                    newImage = Bitmap.createBitmap(cameraBitmap, 0, 0, cameraBitmap.getWidth(), cameraBitmap.getHeight(), mtx, true);
                }else{// LANDSCAPE MODE
                    //No need to reverse width and height
                    newImage = Bitmap.createScaledBitmap(cameraBitmap, screenWidth, screenHeight, true);
                    cameraBitmap = newImage;
                }
            }
        }

you can pass newImage in canvas and create jpeg image and save it on device. Do not forgot Camera is deprecated in Api level 21...

Solution 2

You can use Matrix to flip the image data, something like:

byte[] baImage = null;
Size size = camera.getParameters().getPreviewSize();
ByteArrayOutputStream os = new ByteArrayOutputStream();
YuvImage yuv = new YuvImage(data, ImageFormat.NV21, size.width, size.height, null);
yuv.compressToJpeg(new Rect(0, 0, size.width, size.height), 100, os);
baImage = os.toByteArray();
Bitmap bitmap = BitmapFactory.decodeByteArray(rawImage, 0, rawImage.length);
Matrix matrix = new Matrix(); 
matrix.preScale(-1.0f, 1.0f); 
Bitmap mirroredBitmap = Bitmap.createBitmap(bitmap, 0, 0, size.width, size.height, matrix, false);
Share:
10,477
Eduardo
Author by

Eduardo

Languages: Java, Scala, Kotlin, JavaScript, TypeScript Build Tools: Gradle, SBT Database: Oracle, MySQL, MongoDB Methodologies: Agile, TDD

Updated on July 20, 2022

Comments

  • Eduardo
    Eduardo over 1 year

    When you take a picture with the front facing camera in Android the preview is reflected along the Y axis to make the image seen appear as if the user was looking in the mirror. I want to undo this effect (apply a second reflection) or just stop the one thats done automatically.

    I though to use this:

    Camera mCamera;
    ....
    mCamera.setPreviewCallback(...);
    

    But I dont really know what to do with the overriding of

    onPreviewFrame(byte[] data, Camera camera){...}
    

    Whats the best way I can achieve what I've described?

    Note I am trying to apply this effect to the live preview, not images that are already taken.

  • vitriolix
    vitriolix over 10 years
    And... I missed your last note and answered the wrong question ;)
  • ND1010_
    ND1010_ over 3 years
    Perfect result by onPictureTaken() method, saved my day Thanks