Level indicator for the camera app

As the title suggests.

It would be nice to have some sort of graphic indication that you are holding the phone at a 0 angle when taking photos or videos.

10 Likes

Not a bad idea, I can normally guess roughly where level/upright is but to have an indicator would be useful.

Looking at an app by Poetaster called Spiritlevel (Openrepos), the cover shows something that could be miniaturised to fit the camera screen and act as a means of levelling. This could also be fudged in by patch or adding a file or two to the existing camera app. I don’t expect that this will be implemented by Jolla.

4 Likes

Was thinking the same thing, Spiritlevel is cool, and really quite neatly done.

Another idea would be to mimic the “Debugging Overlay” which shows framerate and rendering speed overlayed on the whole display.

A patch could do something similar, but only display it when the Camera is active. This way it would be available to any app that uses the camera, not just the ones to decide to implement that feature.

2 Likes

g5

Something like that as proposed design. (colours, size, position etc can vary depending on the implementation)

1 Like

Primary and secondary theme colors to not be so obtrusive?

2 Likes

The basic idea is that the middle part moves according to the angle of the phone. When its level it changes to a different colour than when its not level.

Theme colours are fine.

1 Like

I’ll kick it off with something you can paste into the following file;

devel-su nano /usr/lib64/qt5/qml/com/jolla/camera/capture/CaptureOverlay.qml

Paste it in underneath the last dollop of code at the bottom of said file.

The following code is taken/adapted from an app by Kimmoli called Inclinometer found in Jolla Store;

    ///// PASTE THE CODE UNDER THIS BIT
    ConfigurationValue {
        id: previousStoragePathStatus
        key: "/apps/jolla-camera/previousStoragePathStatus"
    }
    ///// PASTE THE CODE UNDER THIS BIT


    Accelerometer {
        id: accelerometer
        dataRate: 25
        active: Qt.application.state === Qt.ApplicationActive

        property double delta: 0.0
        property double rawAngle: 0.0
        property double angle: 0.0
        property double x: 0.0
        property double y: 0.0
        property double z: 0.0

        Behavior on x { NumberAnimation { duration: 175 } }
        Behavior on y { NumberAnimation { duration: 175 } }

        onReadingChanged: {
            x = reading.x
            y = reading.y
            var a
            if ( (Math.atan(y / Math.sqrt(y * y + x * x))) >= 0 )
                a = -(Math.acos(x / Math.sqrt(y * y + x * x)) - (Math.PI/2) )
            else
                a = Math.PI + (Math.acos(x / Math.sqrt(y * y + x * x)) - (Math.PI/2) )
            rawAngle = a * (180/Math.PI)
            angle = rawAngle + delta
        }
    }

    Item {
        id: angleItem
        anchors.centerIn: parent
        rotation: accelerometer.rawAngle

        Rectangle {
            id: line
            color: "white"
            anchors.centerIn: parent
            height: 10; width: parent.paintedWidth
        }
        Rectangle {
            id: lineRight
            anchors.left: line.right
            color: line.color; height: line.height
            anchors.verticalCenter: line.verticalCenter
            width: Math.max(page.height, page.width)/20
        }
        Rectangle {
            id: lineLeft
            anchors.right: line.left
            color: line.color; height: line.height
            anchors.verticalCenter: line.verticalCenter
            width: Math.max(page.height, page.width)/20
        }
        OpacityRampEffect {
            sourceItem: lineLeft
            direction: OpacityRamp.LeftToRight
        }
        OpacityRampEffect {
            sourceItem: lineRight
            direction: OpacityRamp.RightToLeft
        }
    }
    Item {
        z: -1
        id: calibItem
        anchors.centerIn: angleItem
        rotation: 90 - accelerometer.delta;

        Rectangle {
            id: calibLine
            anchors.centerIn: parent
            color: "white"; height: 10
            width: angleItem.paintedWidth
        }
        Rectangle {
            id: calibLineRight
            color: calibLine.color
            anchors.left: calibLine.right
            width: 120; height: calibLine.height
            anchors.verticalCenter: calibLine.verticalCenter
        }
        Rectangle {
            id: calibLineLeft
            color: calibLine.color
            anchors.right: calibLine.left
            width: 120; height: calibLine.height
            anchors.verticalCenter: calibLine.verticalCenter
        }
        OpacityRampEffect {
            offset: 0.25
            sourceItem: calibLineLeft
            direction: OpacityRamp.LeftToRight
        }
        OpacityRampEffect {
            offset: 0.25
            sourceItem: calibLineRight
            direction: OpacityRamp.RightToLeft
        }
    }
    Image {
        width: 144; height: width
        anchors.centerIn: parent
        rotation: accelerometer.angle
        source: "image://theme/icon-m-qr"
    }

}

Looks something like the following (not a screenshot from camera, because file is overlay, so leveller does not show);

6 Likes