0

I've been fighting with this problem for a while. My camera activity is locked to portrait mode and due to other features on it - it must be portrait mode. After I take photo with my Camera and displays it it appears rotated. I found solution to handle this problem but it takes too much memory of weaker devices so after clicking "take photo" button I have to wait around 8 sec till it goes to next activity (PREVIEW ACTIVITY) while on my own Nexus 4 it works without lags and starts instantly. My current code looks like that:

private Camera.PictureCallback mPicture = new Camera.PictureCallback() {

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

        File pictureFile = getOutputMediaFile();

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

        Bitmap bitmap = BitmapFactory.decodeFile(pictureFile.getAbsolutePath());
        Matrix matrix = new Matrix();
        if (currentCamera == BACK_CAMERA) {
            matrix.postRotate(90);
        } else {
            matrix.postRotate(270);
            matrix.preScale(1.0f, -1.0f);
        }
        Bitmap result = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
        try {
            FileOutputStream outStream = new FileOutputStream(pictureFile);
            result.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
            outStream.flush();
            outStream.close();
        } catch (FileNotFoundException e) {
            Log.d("ABC", "File not found: " + e.getMessage());
        } catch (IOException e) {
            Log.d("ABC", "Error accessing file: " + e.getMessage());
        }

        takenPhotoURL= pictureFile.getAbsolutePath();
        Intent intent = new Intent(CameraActivity.this, PreviewActivity.class);
        intent.putExtra("PhotoURI",takenPhotoURL);
        intent.putExtra("voteID",voteId);
        CameraActivity.this.startActivity(intent);
    }

getOutputMediaFile is a method that generates directory in my device where photo should be saved. (I'm not adding photo to gallery yet). When you analyse the code I've posted above you can see that im using FileOutputStream twice. First time I just save photo in phone memory, second time I open it again, write it on rotated matrix and flush it. I think using FileOutputStream, saving -> opening -> saving -> closing -> opening -> saving - closing is slowing weaker devices. I would like to modify this metod somehow to make it more efficient. Please help me with that.

What I have tried till now is trying to delete first FileOutputStream and make everything at once like that:

private Camera.PictureCallback mPicture = new Camera.PictureCallback() {

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

        File pictureFile = getOutputMediaFile();

        if (pictureFile == null){
            return;         
        }
        try {
            FileOutputStream outStream = new FileOutputStream(pictureFile);
            outStream.write(data);

            Bitmap bitmap = BitmapFactory.decodeFile(pictureFile.getAbsolutePath());

            Matrix matrix = new Matrix();
            if (currentCamera == BACK_CAMERA) {
                matrix.postRotate(90);
            } else {
                matrix.postRotate(270);
                matrix.preScale(1.0f, -1.0f);
            }
            Bitmap result = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);

            result.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
            outStream.flush();
            outStream.close();
        } catch (FileNotFoundException e) {
            Log.d("ABC", "File not found: " + e.getMessage());
        } catch (IOException e) {
            Log.d("ABC", "Error accessing file: " + e.getMessage());
        }

        takenPhotoURL= pictureFile.getAbsolutePath();
        Intent intent = new Intent(CameraActivity.this, PreviewActivity.class);
        intent.putExtra("PhotoURI",takenPhotoURL);
        intent.putExtra("voteID",voteId);
        CameraActivity.this.startActivity(intent);
    }

but it doesnt work. Photo is displayed without any changes (nothing happens). And I've tried also Exif but it didn't have effect. Please help me make it more efficient and faster.

F1sher
  • 7,140
  • 11
  • 48
  • 85
  • possible duplicate of [How to rotate and flip bitmap in onPictureTaken](http://stackoverflow.com/questions/16228654/how-to-rotate-and-flip-bitmap-in-onpicturetaken) – Alex Cohn Apr 07 '14 at 12:05
  • There is no reason to write `data` to file and then `decodeFromFile()`. **BitmapFactory** can decode image from `byte[]` as well. Anyways, using `Bitmap` to rotate large images is both slow and memory thirsty, as detailed in the linked solution. Using a third party lib like [MediaUtil](http://mediachest.sourceforge.net/mediautil/) (there is an Android port [on GitHub](http://github.com/bkhall/AndroidMediaUtil)), you can perform a lossless rotation of Jpeg buffer faster. – Alex Cohn Apr 07 '14 at 12:25

0 Answers0