RedApparat / Fotoapparat

Making Camera for Android more friendly. 📸
Apache License 2.0
3.82k stars 405 forks source link

orientation data in exif is always ORIENTATION_UNDEFINED #136

Closed AviranAbady closed 6 years ago

AviranAbady commented 6 years ago

What are you trying to achieve or the steps to reproduce?

Read orientation data from exif

How did you initialize FA?

// init camera
        fotoApparat = Fotoapparat
                .with(getContext())
                .cameraErrorCallback(this)
                .cameraProvider(CameraProviders.defaultProvider(getContext()))
                .into(cameraView)
                .previewScaleType(ScaleType.CENTER_CROP)
                .build();
    }

// start camera
 fotoApparat.start();

// take picture

 fotoApparat.takePicture().toPendingResult().whenAvailable(new PendingResult.Callback<Photo>() {
                @Override
                public void onResult(Photo photo) {
                    handlePhoto(photo.encodedImage);
                }
            });
        }

// read exif from the byte array (using exif support library)
        InputStream in = null;
        ExifInterface exifInterface = null;
        try {
            in = new ByteArrayInputStream(encodedImage);
            exifInterface= new ExifInterface(in);
        }
        catch (IOException e) {}

        }

        exifInterface.getAttribute(ExifInterface.TAG_ORIENTATION); // <- always zero
       // ORIENTATION_UNDEFINED = 0;

What was the result you received?

Orientation data in exif is always ORIENTATION_UNDEFINED = 0; checked on several devices

What did you expect?

correct orientation data

Context:

The activity is locked into portrait mode (using manifest) I do rotate the device into landscape mode to take photos Photo.rotationDegrees will have correct values around 90 or 270 when device is in landscape.

FA Version: 1.4.1 Nexus 6p, Nexus 5x

AviranAbady commented 6 years ago

I've created a demo project showcasing the issue https://github.com/AviranAbady/FotoApparatIssueDemo

the project below has the activity set to portrait only.

The "take photo" button will appear only when the phone is rotated to landscape position (There's an orientation listener)

Once an image is captured, exif is extracted - orientation will be undefined.

@Diolor @dmitry-zaitsev please assist, thanks.

Diolor commented 6 years ago

Honestly I don't know how EXIF data behave. Did you find your solution?

AviranAbady commented 6 years ago

@Diolor unfortunately, no.

Diolor commented 6 years ago

will photo#rotation work for you?

AviranAbady commented 6 years ago

@Diolor no, i cant tell from that if the photo is upside down.

on most phones, rotating to the left (90 deg counter clock wise) will result in a normal photo. but on some phones (like nexus 5x) if you rotate to the left (90 deg couter clock wise) you will get an upside down photo.

photo#rotation would be the same on both phones.

I've created a demo project, linked in the original post, if you wanna have a look.

Diolor commented 6 years ago

https://github.com/Fotoapparat/Fotoapparat/blob/master/sample/src/main/java/io/fotoapparat/sample/MainActivity.java#L225

AviranAbady commented 6 years ago

@Diolor it's not about how to rotate the bitmap, this is about knowing when it needs rotation.

In an app, when the activity is set to portrait only. If a photo is taken when the phone is rotated to landscape... the rotation of the image is unpredictible.

on most phones, if you rotate clock wise it will be upside down. on some phones, it's the other way around...

currently it's impossible to know when you need to rotate it back to normal.

dmitry-zaitsev commented 6 years ago

@AviranAbady sorry for the very late reply.

I checked your sample app. The thing is - we pass the JPEG image from the camera as is, and in our configuration the camera is not writing EXIF rotation into the image. So we are writing it manually into the file later on.

What does it mean for you:

indraAsLesmana commented 5 years ago

for everyone who reads this discussion, here's the answer: val orientation = ExifInterface(file.absolutePath).getAttribute(ExifInterface.TAG_ORIENTATION)

jrocha commented 5 years ago

I was having this issue as well. After checking checking the code I found that saveToFile write this attribute async, so I just wait it to be done.

photoResult.saveToFile(targetFile)
                    .whenDone(unit -> {
                        // do you your stuff here
                    });