Skip to content

Image Orientation Issue #24

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Daxito opened this issue Jan 16, 2017 · 25 comments
Closed

Image Orientation Issue #24

Daxito opened this issue Jan 16, 2017 · 25 comments
Labels

Comments

@Daxito
Copy link

Daxito commented Jan 16, 2017

I just migrated my code to use this plugin instead of the "default" one and I noticed that if I take a picture in portrait orientation, then the resulting image is saved in landscape orientation, the image does not keep the portrait orientation and is is hard to look at the picture without rotating the phone, this issue is not present in the "default camera module".
if the image is taken in landscape then it keeps it that way, no issue.
Any ideas?

Thanks

@Daxito
Copy link
Author

Daxito commented Jan 16, 2017

These other issues are related:

NativeScript/NativeScript#1559

NativeScript/NativeScript#3499

@tsonevn
Copy link
Contributor

tsonevn commented Jan 17, 2017

Hi @Daxito,

Could you provide some more info about the device or simulator, which you are using for testing?

In the meantime you could also verify, whether you will have the same behavior with this sample app.

Regards,
@tsonevn

@Daxito
Copy link
Author

Daxito commented Jan 17, 2017

My device is a Samsung Galaxy S5, Android 6.0.1.
Your SampleApp works great, I am not able to duplicate the issue, what is the trick?

@Daxito
Copy link
Author

Daxito commented Jan 17, 2017

I am going to check why my App is changing the orientation and not the sample App even when both apps are using the same version of the plugin 0.0.8

@tsonevn
Copy link
Contributor

tsonevn commented Jan 18, 2017

Hi @Daxito,

Could you give us some code snippets or sample project, which could be debugged locally?

@zweimal
Copy link

zweimal commented Jan 18, 2017

Hey Guys,
This issue is 100% reproducible on my oldie Samsung Galaxy S3 (GT-I9300) with CyanogenMod 13 (Android 6.0.1) last SNAPSHOT (13.0.20161220) and on my new Samsung Galaxy S7 (SM-G930F) with OEM Android 6.0.1 (build# MMB29K.G930FXXU1BPLB).
Just take a photo on any phone position and outcome image will be rotated 90 degrees to the left.
Patch NativeScript/NativeScript#1635 seems to fix the problem, but using 'nativescript-imagepicker' plugin with photos took with android camera I got the same result. Probably the issue is into Image class

Some modifications starting from NS camera's SampleApp:

Added android:screenOrientation="portrait" into AndroidManifest.xml

		...
		<activity
			android:name="com.tns.NativeScriptActivity"
			...
			android:configChanges="keyboardHidden|orientation|screenSize"
			android:screenOrientation="portrait"
			android:theme="@style/LaunchScreenTheme">
		...

main-page.xml

<Page xmlns="http://schemas.nativescript.org/tns.xsd" loaded="onLoaded">
  <GridLayout class="container" rows="auto,*,auto">
    <Label row="0" text="Take a picture" class="title"/>
    <Image row="1" id="myImage" src="res://logo" stretch="aspectFill" />
    <Button row="2" text="Take" tap="onTap" />
  </GridLayout>
</Page>

main-page.ts

import { EventData } from 'data/observable';
import { Page } from 'ui/page';
import { takePicture } from 'camera';

var myImage;

export function onLoaded(args: EventData) {
  var page = <Page> args.object;
  myImage = page.getViewById('myImage');
  page.bindingContext = {};
}

export function onTap() {
  console.log('onTap');
  takePicture({width: 700, height: 700, keepAspectRatio: true})
    .then(picture => myImage.imageSource = picture);
}

app.css

.title {
    font-size: 30;
    horizontal-align: center;
    margin: 20;
}

button {
    font-size: 42;
    horizontal-align: center;
}

.container {
    padding: 20;
    background-repeat: no-repeat;
    background-position: center top;
}

Image {
    top: 0;
    border-radius: 290;
    height: 290;
    width: 290;
    border-width: 6;
    border-color: #00e988;
}

package.json

{
  "description": "NativeScript Application",
  "license": "SEE LICENSE IN <your-license-filename>",
  "readme": "NativeScript Application",
  "repository": "<fill-your-repository-here>",
  "nativescript": {
    "id": "org.nativescript.poc",
    "tns-android": {
      "version": "2.4.1"
    }
  },
  "dependencies": {
    "tns-core-modules": "^2.4.4"
  },
  "devDependencies": {
    "babel-traverse": "6.19.0",
    "babel-types": "6.19.0",
    "babylon": "6.14.0",
    "lazy": "1.0.11",
    "nativescript-dev-typescript": "^0.3.2",
    "typescript": "^2.1.1"
  }
}

@tsonevn
Copy link
Contributor

tsonevn commented Jan 18, 2017

Hi @zweimal
Thank you for the sample code.

I notice that you are using the old camera Module. With NativeScript 2.4 cameraModule has been migrated to external plugin called nativescript-camera. In the plugin has been fixed the Out of memory exception on Android and the problem with the rotation. You could review this article, where has been described how to use the plugin. Could you verify, whether you will have the same behavior with the plugin.

Regards,
@tsonevn

@Daxito
Copy link
Author

Daxito commented Jan 18, 2017

@tsonevn
I am preparing a demo app and I will attach it here asap.

@Daxito
Copy link
Author

Daxito commented Jan 18, 2017

Attached is a sample app showing the issue.
CameraTestRotation.zip

Also, after taking the picture, we send it over to our server using the nativescript-background-http and the file we received is also in the wrong orientation.

@cvgomes
Copy link

cvgomes commented Jan 20, 2017

I'm having the same exact issue with both Sony Xperia T3 (d5103) and in Samsung Galaxy S4 (GT-I9505).
T3 is using Android 4.4.4, and the S4 is using Android 5.0.1
Found this post in StackOverflow describing the same:
http://stackoverflow.com/questions/40609909/how-to-set-orientation-of-image-with-nativescript-imagepicker

@cvgomes
Copy link

cvgomes commented Jan 20, 2017

The same code works well on a Oneplus One using Android 6.0.1

@tsonevn
Copy link
Contributor

tsonevn commented Jan 20, 2017

Hi @Daxito,

Thank you for the sample project.

I was able to reproduce this behavior on my side, while using Samsung S4 device.
This problem has been reproduced only on some Android devices. We will research this problem further and will verify, what is causing this issue.

For further info, you could keep track on this issue.

In the meantime, you could verify, the screen orientation by using orientationChangedEvent and to rotate the image for some of the devices. To handle the device model, you could use platformModule.

You could review the below given example, where has been shown the given workaround.

main-page.xml

<Page xmlns="http://schemas.nativescript.org/tns.xsd" navigatingTo="navigatingTo" xmlns:nativescript-fresco="nativescript-fresco">
    <GridLayout rows="auto, *, auto">
        <StackLayout orientation="horizontal" row="0" padding="10">
            <Label text="saveToGallery"/>
            <Switch checked="{{ saveToGallery }}"/>
        </StackLayout>

        <ScrollView row="1">
            <StackLayout orientation="vertical">
                <Label text="from takePicture imagesource"/>
                <Image rotate="{{ imagerotate }}" src="{{ cameraImage }}" width="100%" height="128" cssClass="image" stretch="aspectFit"/>
                <Label text="from file imagesource"/>
                <Image rotate="{{ imagerotate }}" loaded="secondimageloaded" src="{{ cameraImageLocal }}" width="100%" height="128" cssClass="imageLocal" stretch="aspectFit"/>
                <Label text="from file Fresco"/>
                <nativescript-fresco:FrescoDrawee actualImageScaleType="fitCenter" cssClass="frescoImage" width="100%" height="128" imageUri="{{ cameraFilePath }}"/>
            </StackLayout>
        </ScrollView>

        <StackLayout orientation="horizontal" row="2" padding="10">
            <Button text="Take Picture" tap="onTakePictureTap"/>
            <Button text="Request Permissions" tap="onRequestPermissionsTap"/>
        </StackLayout>
    </GridLayout>
</Page>

main-page.js

var observable_1 = require("data/observable");
var nativescript_camera_1 = require("nativescript-camera");
var imageSourceModule = require("image-source");
var trace = require("trace");
var fs = require('file-system');


var application = require("application");
var platform=require("platform");


var orientation="PORTRAIT";
var model;

trace.addCategories(trace.categories.Debug);
trace.enable();
function navigatingTo(args) {
    var page = args.object;
    var picturePath = null;
    page.bindingContext = observable_1.fromObject({
        cameraImage: picturePath,
        cameraImageLocal: null,
        saveToGallery: true,
        cameraFilePath: null
    });

    model = platform.device.model;
    
// check orientation
    application.on("orientationChanged", function (e) {
                var currentPageWidth =platform.screen.mainScreen.widthDIPs;
                var currentPageHeight = platform.screen.mainScreen.heightDIPs;

                console.log("device model");
                console.log(model);
               

                if(currentPageWidth>currentPageHeight){
                    orientation="LANDSCAPE";
                }
                else{
                    orientation="PORTRAIT";
                }
            });

    page.bindingContext.set("imagerotate", 0);
}
exports.navigatingTo = navigatingTo;
function onRequestPermissionsTap(args) {
    nativescript_camera_1.requestPermissions();
}
exports.onRequestPermissionsTap = onRequestPermissionsTap;
function onTakePictureTap(args) {
    var page = args.object.page;
    var saveToGallery = page.bindingContext.get("saveToGallery");
    nativescript_camera_1.takePicture({ width: 180, height: 180, keepAspectRatio: true, saveToGallery: saveToGallery }).
        then(function (imageAsset) {
        var source = new imageSourceModule.ImageSource();
        source.fromAsset(imageAsset).then(function (source) {
            console.log("Size: " + source.width + "x" + source.height);
            page.bindingContext.set("cameraImage", source);
        

            if(orientation=="PORTRAIT"){
                page.bindingContext.set("imagerotate", 90);
            }
            else{
                page.bindingContext.set("imagerotate", 0);
            }

            var folder = fs.knownFolders.documents();
            var date = new Date();
            var path = fs.path.join(folder.path, "camera_picture" + date.getTime() + ".png");

            var saved = source.saveToFile(path, "png");

            console.log('Saved camera picture: ', saved);

            var savedImageSource = imageSourceModule.fromFile(path);

            page.bindingContext.set("cameraImageLocal", savedImageSource);

            console.log(path);
            page.bindingContext.set("cameraFilePath", path);
        });

    }, function (err) {
        console.log("Error -> " + err.message);
    });
}
exports.onTakePictureTap = onTakePictureTap;

exports.secondimageloaded=function(args){
    console.log("image loaded");
    console.log(args.object.rotate);

}

Hope this helps

@tsonevn tsonevn added the bug label Jan 20, 2017
@Daxito
Copy link
Author

Daxito commented Jan 20, 2017

@tsonevn
Thank you for the update and workaround! I will keep an eye on this issue.

@mounirka
Copy link

Hi guys, i'm using the plugin and i noticed this bug on my device, i came up with a solutions that works on my device but it slower a bit the process.
In the file inside the plugin nativescript-camera.android.js i added the following code at the end of the file:

var rotateBitmap = function (imgPath, angle) {
    try {
        var matrix = new android.graphics.Matrix();
        matrix.postRotate(angle);
        var bmOptions = new android.graphics.BitmapFactory.Options();
        var oldBitmap = android.graphics.BitmapFactory.decodeFile(imgPath, bmOptions);
        var finalBitmap = android.graphics.Bitmap.createBitmap(oldBitmap, 0, 0, oldBitmap.getWidth(), oldBitmap.getHeight(), matrix, true);
        var out = new java.io.FileOutputStream(imgPath);
        finalBitmap.compress(android.graphics.Bitmap.CompressFormat.JPEG, 100, out);
        out.flush();
        out.close();
    } catch (e) {
        console.log("Exception: " + e);
    }
}

And then just before the line var asset = new imageAssetModule.ImageAsset(picturePath_1); add this:

var ei = new android.media.ExifInterface(picturePath_1);
var orientation = ei.getAttributeInt(android.media.ExifInterface.TAG_ORIENTATION, android.media.ExifInterface.ORIENTATION_NORMAL);
                        switch(orientation) {
                            case android.media.ExifInterface.ORIENTATION_ROTATE_90:
                                rotateBitmap(picturePath_1, 90);
                                break;
                            case android.media.ExifInterface.ORIENTATION_ROTATE_180:
                                rotateBitmap(picturePath_1, 180);
                                break;
                            case android.media.ExifInterface.ORIENTATION_ROTATE_270:
                                rotateBitmap(picturePath_1, 270);
                                break;
                        }

I'm not very skilled on android, if someone can propose a better solution it may help a lot of people, thank you

@gregersen79
Copy link

Also experiencing this rotation issue on a Sony Xperia Z3, LG G4 and LG Spirit. Using version 0.0.8 of the camera plugin.

@mounirka
Copy link

mounirka commented Feb 3, 2017

Hi @gregersen79 have you tried my solution? does it work on your devices? thank you

@gregersen79
Copy link

Hi @mounirka yes I implemented your solution and it worked well, thank you! So until this issue gets resolved I'll go with this.

@gregersen79
Copy link

Okay, so after a little research I found, that if I'm loading an imageSource from the returned imageAsset, the imageSource will have a correct rotationAngle.
I'm using the imageCropper plugin after the camera plugin, so for me the problem is that the imageCropper plugin doesn't handle the rotationAngle property for the imageSource.
So I guess the handling of the image orientation for the camera plugin is a expected.

@tsonevn
Copy link
Contributor

tsonevn commented Feb 6, 2017

Could you try to upgrade to latest NativeScript 2.5 and to verify, whether you will have the same problem with image orientation while using default Image component.
You could use tns update command, which will upgrade all needed dependencies in the project.

@gregersen79
Copy link

@tsonevn I have an upcoming release of our app with Nativescript 2.4, but I will upgrade as soon as I get a change, should be the start of next week.

@sagesan
Copy link

sagesan commented Feb 7, 2017

i have the same problem on samsung galaxy 4, and after 2.5 other plugin broke so i can't test the camera :/

@sagesan
Copy link

sagesan commented Feb 7, 2017

ok i disabled the plugin and the pictures are still being rotated

@cvgomes
Copy link

cvgomes commented Feb 15, 2017

@tsonevn issue still present on {N} 2.5

@rossbg
Copy link

rossbg commented Feb 23, 2017

After days of bad feelings I just tried @mounirka solution and it works.

@EddyVerbruggen
Copy link
Contributor

Hey @mounirka, I encountered this issue today myself and have taken the liberty to transform your code into a PR (#52). Thanks for sharing!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

9 participants