RedApparat / Fotoapparat

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

Resulting photo is rotated 90° counter-clockwise #263

Closed mcontin closed 6 years ago

mcontin commented 6 years ago

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

I'm trying to take a picture in portrait mode and have the result in the same orientation.

How did you initialize FA?

mFotoApparat = Fotoapparat
                .with(getApplicationContext())
                .into(mCameraView)                      // view which will draw the camera preview
                .previewScaleType(ScaleType.CenterCrop)
                .photoResolution(highestResolution())   // we want to have the biggest photo possible
                .lensPosition(back())                   // we want back camera
                .focusMode(firstAvailable(              // (optional) use the first focus mode which is supported by device
                        continuousFocusPicture(),
                        autoFocus(),                    // in case if continuous focus is not available on device, auto focus will be used
                        fixed()                         // if even auto focus is not available - fixed focus mode will be used
                ))
                .build();

What was the result you received?

The photo is taken but rotated 90° counter-clockwise.

What did you expect?

I expected the photo to be taken in the same orientation as the device.

Context:

dmitry-zaitsev commented 6 years ago

The image itself will always have the same orientation. What defines the correct rotation is Exif information in JPEG file. That means that if you will save the byte array into a file and then open it in some image viewer the image will have the correct orientation.

If you would like to decode the Bitmap then you should take a look at Photo.rotationDegrees field in the result. It tells you how you should rotate the image so that it will have the correct orientation.

Why do we not just rotate the Bitmap for you? Because it is ridiculously inefficient memory and performance wise. Usually, such things are done by rotating the ImageView itself.

mcontin commented 6 years ago

Rotating the ImageView sounds like a work-around, especially since there's .copy(Bitmap, int) which should return the rotated BitmapPhoto but it's not working either. Should I open another issue for that?

dmitry-zaitsev commented 6 years ago

copy(Bitmap, int) is just a method generated by Kotlin. It creates a copy of BitmapPhoto object but does not actually rotate the Bitmap.

Rotating the ImageView sounds like a work-around

It might sound like it, but when you are dealing with 30MB+ images it becomes a big deal. Rotating bitmap in memory means:

That is certainly not impossible, but it will result in a noticeable lag. Especially on lower-end devices.

If you still wish to proceed with this approach, then take a look at: https://stackoverflow.com/a/29982596/926907

We might introduce some nice API to simplify this process for you.

tand22 commented 6 years ago

This however means when you do a base64 encode and upload to a server the image has an incorrect orientation.