nativescript-camera-plus
nativescript-camera-plus copied to clipboard
Preview rotated when app isn't in natural orientation - Android API 21+ / CameraX
Whenever the view is rotated, preview image must rotate accordingly. Since that's not happening, we get a rotated preview window:

Experments in Fancycamera component with preview.setRotation(rotation: Int) were noneffective. This is actually a naive code problem, as mentioned in this stackoverflow topic. As explained in Husayn Hakeem's blog post, the recommended solution is to use PreviewView class from CameraX (see the implementation). Question is how to do that in a nativescript plugin?
NativeScript does not have a surface view, so the solution may to through programmatic binding of a child view. Possibly through NativeScript's PlaceHolder element, which allows the adding any native widget to the application.
We can use the preview view by extending that instead of the textureview but they didn’t have a way to interact with the preview view using OpenGL which I would like to do soon to add support in the canvas plugin
Hmm now I see. Unfortunately PreviewView is final, so it can't be extended. And this guide indicates we can't mix our own surface or TextureView with a PreviewView.
So this would be a huge change:
- from
FancyCamera : FrameLayoutholdingCameraBase : TextureView - to
PreviewView : FrameLayout
The PreviewView class applies a transformation matrix to the surface, and we can't copy that code because the methods are all internal and the code is too complex anyway. It would be easier if google made Preview.Builder.setTargetRotation or Preview.setTargetRotation to work readily with our TextureView. But that doesn't seem to be on their plans. So there is no middle ground.
For immediate results, I tried handling it all within camera-plus, based on View.setRotation. That seems doable, although it is a cheap workaround that would require a few adjustments to show up right. In the image below, I rotated FancyCamera and the buttons, but would still need to recalculate their locations (note they are in wrong position):

Thoughts about this approach? My wonder is code maintenance.
Update: nvm, rotation seems to be working with Fancy Camera 3.0.0-alpha15.
@Murilo-Perrone can you give me a few more details about how you did your rotation? I need something that I can do right now, and what you have seems good enough. I don't need any details related to the buttons as I am already using my own. I just need to know how/where you set the rotation in camera-plus. Thanks!
@sublime392 hi sorry for the delay. That tentative is based on rough view rotation, such as the CSS 'rotate' property:
public camLoaded(e: any): void {
this.cam = e.object as CameraPlus;
if (isAndroid) {
this.cam.rotate = 90;
You can get same result through this.cam.nativeView.setRotation(90). This can respond to orientation changes detected by nativescript component:
constructor(private zone: NgZone) {
on("orientationChanged", (evt) => {
setTimeout(() => this.onOrientationChanged(evt.eventName, evt.newValue), 1000)
});
}
onOrientationChanged(eventName: string, newValue: string) {
if (newValue == "landscape") {
...
}
if (newValue == "portrait") {
...
}
}
In case you want to seek for a workaround within the plugin code, the above detection may be done with native code, as described in issue 143 . Then other adjustments can be tried in camera-plus.android.ts. Here is an example:
private _onLayoutChangeFn(...args: any[]) {
console.log("_onLayoutChangeFn: ", args);
const size = this.getActualSize();
CLog('xml width/height:', size.width + 'x' + size.height);
this.adjustRotation(); // <== NEW CODE
this._initDefaultButtons();
}
private adjustRotation() {
const viewAngle = this.nativeView.getDisplay().getRotation() * 90;
CLog("viewAngle: " + viewAngle);
// this.rotate = 360 - viewAngle;
this._nativeView.setRotation(360 - viewAngle);
const oldHeight = this._nativeView.height;
this._nativeView.height = this._nativeView.width;
this._nativeView.width = oldHeight;
if (this._flashBtn) this._flashBtn.setRotation(viewAngle);
if (this._takePicBtn) this._takePicBtn.setRotation(viewAngle);
if (this._toggleCamBtn) this._toggleCamBtn.setRotation(viewAngle);
if (this._galleryBtn) this._galleryBtn.setRotation(viewAngle);
this._nativeView.requestLayout();
}