Closed SAGARSURI closed 5 years ago
Hi, thanks for reporting this. Which phone/(s) is affected? Is the sample app affected too?
Samsung galaxy s8, Google pixel. Both running on 7.0
Is the sample app affected too?
In the sample app its flipping the image. But in my case its rotating as well as flipping. I am using the same code from your sample app.
EDIT: Here is a video: https://photos.app.goo.gl/nziWI3GMOqmMRul93
I am also seeing this on my devices. I don't think it is specific to the front facing camera though, rather it is something I see occurring after resuming the app while in landscape mode.
Step # 3 can be replaced with any thing that switches or reinitializes the activity while in landscape mode. For instance, if you rotate to landscape, hit your recents button then return to the fotoapparat sample app and take a photo with the back facing camera the result will be rotated.
I would guess this might be due to an issue with #90 assuming the default orientation is portrait at some point and not updating the orientation to landscape because no orientation update triggers it.
Regarding #90 just in general, I do believe there are valid use cases for using system orientation instead of device orientation (which #90 reverses). For my use case I don't allow my camera activity into all 4 orientations (I think most camera apps prevent the upsidedown/reverse portrait orientation). For any application that doesn't allow all orientations, #90 complicates things.
I think the issue in the video is different than the one in the reproduction steps. There reason for the first might be as @andrewcking decribed the updated orientation state is lost. For the second just a wrong calculation.
@Diolor Also having this issue on Galaxy Tab S2. Taking a front-facing photo with the device in landscape orientation is fine, but portrait orientation photos are rotated by 90 degrees clockwise.
@Diolor Having the same issue with a BV6000s. How can this be addressed?
@emilany The calculations inside OrientationResolver#computeImageOrientation
need to be fixed
I noticed that when I specify camera resolution parameter, like I want width:1080xheight:1440, but I have to set width=1440, height=1080, or I cannot get camera preview interface. Is this one of reason why it change orientation?
For anyone curious, I was able to resolve the issue for my purposes by setting Device.startOrientationMonitoring
in StartOrientationRoutine.kt
to just be an empty method. This perhaps isn't a great practice but it prevents fotoapparat from trying to correct orientation based on the way you are holding the device. I then am handling the rotation myself (as was the case pre version 2) and saving the file myself.
I use the following for rotating the image:
Matrix matrix = new Matrix();
if (camera.equals("Front")) {
matrix.postRotate(amountRotated-result.rotationDegrees);
} else {
matrix.postRotate(-amountRotated-result.rotationDegrees);
}
Bitmap rotated = Bitmap.createBitmap(result.bitmap, 0, 0, result.bitmap.getWidth(), result.bitmap.getHeight(), matrix, true);
Where amountRotated
is the device orientation offset, calculated however you want (using your own orientation listener or basing it on activity orientation). Doing it this way allows me to prevent photos from being taken in certain orientations.
This seems to be working on front and back cameras and in all orientations on my devices including those with non-standard camera mountings like the Nexus 5x.
I rotate bitmap and flip it while processing frames.
override fun process(frame: Frame) {
Log.d(TAG, "frame: ${frame.image.size}, ${frame.size}")
YuvImage(
frame.image,
ImageFormat.NV21,
frame.size.width,
frame.size.height,
null
).let { yuvImage ->
ByteArrayOutputStream().use { output ->
yuvImage.compressToJpeg(
Rect(0, 0, frame.size.width, frame.size.height),
100,
output
)
output.toByteArray().apply {
BitmapFactory.decodeByteArray(this, 0, size)?.let { bitmap ->
process(
bitmap.rotate(90f).flip(
false, activeCamera == Camera.Front
)
)
bitmap.recycle()
}
}
}
}
}
private fun Bitmap.flip(horizontal: Boolean, vertical: Boolean): Bitmap {
val matrix = Matrix()
matrix.preScale((if (horizontal) -1 else 1).toFloat(), (if (vertical) -1 else 1).toFloat())
return Bitmap.createBitmap(this, 0, 0, width, height, matrix, true)
}
private fun Bitmap.rotate(degrees: Float): Bitmap {
val matrix = Matrix()
matrix.postRotate(degrees)
val scaledBitmap = Bitmap.createScaledBitmap(this, width, height, true)
return Bitmap.createBitmap(
scaledBitmap,
0,
0,
scaledBitmap.width,
scaledBitmap.height,
matrix,
true
)
}
I am using the latest version of your library. I am using only front facing camera. I took the code from your sample app. But when I take the picture from front facing camera, the result is rotated and zoomed. I have to rotate the result bitmap to 270 degree and then flip it to get the proper result. May I know the actual issue and How can it be fixed ? Here is my code: