2

I'm creating android camera app. This is an custom camera using camera API.
Whenever I take picture from camera it always save in landscap mode.
I'm using this method to set the camera orientation.

 public static void setCameraDisplayOrientation(Activity activity,
                                               int cameraId, android.hardware.Camera camera) {
    android.hardware.Camera.CameraInfo info =
            new android.hardware.Camera.CameraInfo();
    android.hardware.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;  // compensate the mirror
    } else {  // back-facing
        result = (info.orientation - degrees + 360) % 360;
    }
    camera.setDisplayOrientation(result);
}

Here is code which is responsible to store image.

 PictureCallback jpegCallback = new PictureCallback() {
    public void onPictureTaken(byte[] data, Camera camera) {
        File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
        if (pictureFile == null){
            Log.d(TAG, "Error creating media file, check storage permissions: ");
            return;
        }

        try {
            FileOutputStream fos = new FileOutputStream(pictureFile);
            fos.write(data);
            fos.close();
        } catch (FileNotFoundException e) {
            Log.d(TAG, "File not found: " + e.getMessage());
        } catch (IOException e) {
            Log.d(TAG, "Error accessing file: " + e.getMessage());
        }
     } 
    };

This code save the image successfully but always in landscape mode. What I'm missing I'm new in android. I want to save image as like it is shown in preview.

Update 2 (According To Answer)

       PictureCallback jpegCallback = new PictureCallback() {
    public void onPictureTaken(byte[] data, Camera camera) {

        Camera.CameraInfo info = new Camera.CameraInfo();

        int rotationAngle = getCorrectCameraOrientation (MainActivity.this, info);
   Toast.makeText(MainActivity.this, "Angle "+ rotationAngle, Toast.LENGTH_SHORT).show();
        File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);

        try {
            writeFile (data, pictureFile);
        } catch (IOException e) {
            e.printStackTrace();
        }

        processImage (pictureFile, rotationAngle, 1);
    }
   };

I'm using code in this way but this is not working still same problem image is always in landscape mode.

Fiverr Projects
  • 311
  • 2
  • 4
  • 13
  • Please see my answer below http://stackoverflow.com/questions/43447987/android-camera-provide-upside-down-data-on-back-camera-in-some-devices/43449660#43449660 – PEHLAJ Apr 18 '17 at 11:46
  • Why would update2 code change someting? You are still saving data array. And do nothing wjth camera info or orientation. – greenapps Apr 18 '17 at 12:22

1 Answers1

1

Try

1. First of all, add methods (writeFile, processImage and getCorrectCameraOrientation) defined below (After step 3)

2. Calculate camera orientation after capturing photo and update onPictureTaken**

@Override
public void onPictureTaken (final byte[] data, final Camera camera) {

    int rotationAngle = getCorrectCameraOrientation (this, info);

3. Create file and update photo angle using rotationAngle

File file = new File (folder, fileName);

try {
    file.createNewFile ();
}
catch (IOException e) {
    e.printStackTrace ();
}

writeFile (data, file);
processImage (file, rotationAngle, compressRatio);

writeFile

public static void writeFile (byte[] data, File file) throws IOException {

    BufferedOutputStream bos = null;

    try {
        FileOutputStream fos = new FileOutputStream (file);
        bos = new BufferedOutputStream (fos);
        bos.write (data);
    }
    finally {
        if (bos != null) {
            try {
                bos.flush ();
                bos.close ();
            }
            catch (Exception e) {
            }
        }
    }
}

processImage

public static void processImage (File file, int rotationAngle, int compressionRatio) {

    BufferedOutputStream bos = null;

    try {

        Bitmap bmp = BitmapFactory.decodeFile (file.getPath ());

        Matrix matrix = new Matrix ();
        matrix.postRotate (rotationAngle);

        bmp = Bitmap.createBitmap (bmp, 0, 0, bmp.getWidth (), bmp.getHeight (), matrix, true);

        FileOutputStream fos = new FileOutputStream (file);
        bmp.compress (Bitmap.CompressFormat.PNG, compressionRatio, fos);
    }
    catch (IOException e) {
        e.printStackTrace ();
    }
    catch (OutOfMemoryError t) {
        t.printStackTrace ();
    }
    catch (Throwable t) {
        t.printStackTrace ();
    }
    finally {
        if (bos != null) {
            try {
                bos.flush ();
                bos.close ();
            }
            catch (Exception e) {
            }
        }
    }
}

getCorrectCameraOrientation

    public static int getCorrectCameraOrientation (Activity activity, Camera.CameraInfo info) {

    int rotation = activity.getWindowManager ().getDefaultDisplay ().getRotation ();
    int degrees = 0;

    if (hasValidRotation (rotation)) {
        degrees = rotation * 90;
    }

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

    return result;
}
PEHLAJ
  • 9,980
  • 9
  • 41
  • 53
  • I update my question according to your answer but this is not working still same problem. I'm not recognize how `processImage` is working. You are saving the file first then processing the image ? – Fiverr Projects Apr 18 '17 at 12:08
  • Yes, I am saving the byte data to local file and then applying rotation angle on the saved file. Use locally saved image file. – PEHLAJ Apr 18 '17 at 12:09
  • This code is fully tested on multiple devices and our apps are live on play store. You will face different orientation issue on different devices but this will resolve your issue – PEHLAJ Apr 18 '17 at 12:13
  • Yes you are write this is working. The problem is getting `roatationAngle`. I checked it is returning `0` so I manually set it `90` and its working – Fiverr Projects Apr 18 '17 at 12:21
  • And what is the compressRatio ? By setting the `1` increase it size. – Fiverr Projects Apr 18 '17 at 12:26
  • This is terrible code as the original jpg file contains an exif header with all kind of information. By making a bitmap out of it you throw away the complete exif. Finally you make a png out of it. – greenapps Apr 18 '17 at 12:26
  • Sorry @greenapps I didn't understand what do you mean. You mean this code is not good to rotate image ? Can you please explain a little bit more ? – Fiverr Projects Apr 18 '17 at 12:37
  • Of course it can rotate. Just read better what i said. Its not that difficult. – greenapps Apr 18 '17 at 12:46