Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/flatpak.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ jobs:
runs-on: ${{ matrix.variant.runner }}
steps:
- uses: actions/checkout@v4
with:
submodules: recursive # fetch submodules (recursively)
fetch-depth: 0 # ensure full history so submodule refs are resolvable
token: ${{ secrets.GITHUB_TOKEN }}
- uses: flatpak/flatpak-github-actions/flatpak-builder@v6
with:
bundle: photobooth.flatpak
Expand Down
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "shared-modules"]
path = shared-modules
url = https://github.com/flathub/shared-modules
31 changes: 31 additions & 0 deletions io.github.saeugetier.photobooth.json
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,37 @@
}
]
},
{
"name": "libgphoto2",
"builddir": true,
"cleanup": [
"/doc",
"*.la"
],
"sources": [
{
"type": "git",
"url": "https://github.com/gphoto/libgphoto2.git",
"tag": "v2.5.32",
"commit": "de1f0617b1ffa39c1980d1306343709c7dc0120e",
"x-checker-data": {
"type": "anitya",
"project-id": 12558,
"stable-only": true
}
},
{
"type": "script",
"dest-filename": "autogen.sh",
"commands": [
"AUTOMAKE=\"automake --foreign\" autoreconf -vfis"
]
}
],
"modules": [
"shared-modules/libusb/libusb.json"
]
},
{
"name": "qtbooth",
"buildsystem": "qmake",
Expand Down
1 change: 1 addition & 0 deletions qml.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
<file>qml/SnapshotSettings.qml</file>
<file>qml/SnapshotSettingsForm.ui.qml</file>
<file>qml/content/CameraRenderer.qml</file>
<file>qml/content/CameraSource.qml</file>
<file>qml/content/CollageImageDelegate.qml</file>
<file>qml/content/CollageRenderer.qml</file>
<file>qml/content/Countdown.qml</file>
Expand Down
10 changes: 1 addition & 9 deletions qml/Application.qml
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ ApplicationWindow {
console.log("Window mode changed to: " + applicationSettings.windowMode)
}

settingsMenu.comboBoxCamera.onCurrentIndexChanged:
settingsMenu.comboBoxCamera.onCurrentTextChanged:
{
applicationSettings.cameraName = settingsMenu.comboBoxCamera.currentText
}
Expand Down Expand Up @@ -225,13 +225,5 @@ ApplicationWindow {
{
flow.imagePreview.effectButton.visible = !disableEffectPopup
}

onCameraNameChanged:
{
print("Camera changed to " + cameraName)
var id = flow.settingsMenu.findDeviceId(cameraName)
print("Found ID: " + id)
flow.snapshotMenu.cameraRenderer.deviceId = id
}
}
}
2 changes: 2 additions & 0 deletions qml/ApplicationFlow.qml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ ApplicationFlowForm {
state = "collageSelection"
}

snapshotMenu.cameraRenderer.cameraName: applicationSettings.cameraName

imagePreview.onAccept: (filename, effect) =>
{
if(applicationSettings.printEnable)
Expand Down
25 changes: 11 additions & 14 deletions qml/SettingsMenu.qml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import QtQuick.Controls
import QtQuick.Dialogs
import Qt.labs.platform
import QtQml
import GPhotoCamera
import "content"

SettingsMenuForm {
Expand All @@ -25,26 +26,22 @@ SettingsMenuForm {
{
listModel.push(availableCameras[i].description)
}
var gphotoCameras = gphotoCamera.availableCameras();
console.log("GPhoto Camera Count: " + Number(gphotoCameras.length).toString())
for(i = 0; i < gphotoCameras.length; i++)
{
listModel.push(gphotoCameras[i])
}
return listModel;
}

MediaDevices
{
id: mediaDevices
GPhotoCamera {
id: gphotoCamera
}

function findDeviceId(cameraName)
MediaDevices
{
var i;
var availableCameras = mediaDevices.videoInputs;
for(i = 0; i < availableCameras.length; i++)
{
if(availableCameras[i].description === cameraName)
{
return availableCameras[i].id;
}
}
return mediaDevices.defaultVideoInput.id
id: mediaDevices
}

Component.onCompleted:
Expand Down
2 changes: 2 additions & 0 deletions qml/SettingsMenuForm.ui.qml
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ Item {
}
ComboBox {
id: comboBoxCamera
Layout.preferredWidth: 300
}
}

Expand Down Expand Up @@ -206,6 +207,7 @@ Item {
}
ComboBox {
id: comboBoxCameraOrientation
Layout.preferredWidth: 300
textRole: "text"
valueRole: "value"
model: [{
Expand Down
160 changes: 36 additions & 124 deletions qml/content/CameraRenderer.qml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Qt5Compat.GraphicalEffects
import QtQuick.Layouts
import BackgroundFilter
import CaptureProcessor
import GPhotoCamera

Item {
id: renderer
Expand All @@ -13,35 +14,16 @@ Item {

property bool photoProcessing: (state === "snapshot")
property bool mirrored: true
property string deviceId: camera.deviceId
property string cameraName: ""
property alias backgroundFilter: backgroundFilter
property bool backgroundFilterEnabled: false
property url backgroundImage: ""

function printDevicesToConsole(devices) {
console.log("Found " + devices.length + " camera devices!")
for (var i = 0; i < devices.length; i++) {
console.log(
"Found device: " + devices[i].deviceId + " with number " + i)
}
}

MediaDevices {
id: mediaDevices
onCameraNameChanged:
{
print("Camera changed to " + cameraName)
}

onDeviceIdChanged: id => {
// get the camera device with id from mediaDevices
console.log("Selected camera: " + id)
var availableCameras = mediaDevices.videoInputs
for (var i = 0; i < availableCameras.length; i++) {
if (availableCameras[i].deviceId === id) {
camera.cameraDevice = availableCameras[i]
break
}
}
}

CaptureProcessor
{
id: captureProcessor
Expand All @@ -65,83 +47,42 @@ Item {
}
}

CaptureSession {
CameraSource
{
id: cameraSource

camera: Camera {
id: camera
cameraDevice: mediaDevices.defaultVideoInput
exposureMode: Camera.ExposurePortrait
exposureCompensation: -1.0
whiteBalanceMode: Camera.WhiteBalanceAuto
flashMode: Camera.FlashAuto
torchMode: Camera.TorchAuto
}
cameraName: renderer.cameraName

id: cameraSession

videoOutput: output

imageCapture: ImageCapture {
id: imageCapture

onImageCaptured:
{
whiteOverlay.state = "released"
renderer.state = "store"
console.log("Captured")

console.log(applicationSettings.foldername.toString())
var path = applicationSettings.foldername.toString()
if(backgroundFilterEnabled)
{
path = path + "/raw"
}
path = path.replace(/^(file:\/{2})/, "")
var cleanPath = decodeURIComponent(path)
console.log(cleanPath)

captureProcessor.saveCapture(preview, cleanPath + "/Pict_" + new Date().toLocaleString(
locale, "dd_MM_yyyy_hh_mm_ss") + ".jpg")
}
onErrorOccurred: {
renderer.state = "preview"
failed()
}
onErrorStringChanged: {
console.log("Camera error: " + errorString)
onImageCaptured: function(image) {
whiteOverlay.state = "released"
renderer.state = "store"
console.log("Captured: " + image)

console.log(applicationSettings.foldername.toString())
var path = applicationSettings.foldername.toString()
if(backgroundFilterEnabled)
{
path = path + "/raw"
}
}
path = path.replace(/^(file:\/{2})/, "")
var cleanPath = decodeURIComponent(path)
console.log(cleanPath)

captureProcessor.saveCapture(image, cleanPath + "/Pict_" + new Date().toLocaleString(
locale, "dd_MM_yyyy_hh_mm_ss") + ".jpg")
}

/*onCameraStateChanged:
{
if(camera.cameraState == Camera.UnloadedState)
{
console.log("Camera State Changed: Unloaded")
printDevicesToConsole(QtMultimedia.availableCameras)
camera.stop()
cameraDiscoveryTimer.start()
}
else if(camera.cameraState == Camera.LoadedState)
{
console.log("Camera State Changed: Loaded")
printDevicesToConsole(QtMultimedia.availableCameras)
}
else if(camera.cameraState == Camera.ActiveState)
{
console.log("Camera State Changed: Active");
cameraDiscoveryTimer.stop()
}
else
{
console.log("Camera State Changed: Unknown");
}
}*/
onErrorOccurred: function(errorString) {
renderer.state = "preview"
console.log("Camera error: " + errorString)
failed()
}
}


ReplaceBackgroundVideoFilter {
id: backgroundFilter
videoSink: output.videoSink
videoSink: cameraSource.output.videoSink
background: backgroundImage

onCaptureProcessingFinished: fileName =>
Expand All @@ -155,14 +96,6 @@ Item {
}
}

Connections {
id: cameraErrorListener
target: camera
function errorOccured(_, errorString) {
console.log("Camera Error: " + errorString)
}
}

VideoOutput {
id: output

Expand Down Expand Up @@ -222,31 +155,10 @@ Item {
height: output.height
}

/* Timer
{
id: cameraDiscoveryTimer

interval: 1000
repeat: true

onTriggered:
{
//camera discovery is delayed
var availableCameras = QtMultimedia.availableCameras
printDevicesToConsole(availableCameras)

if(availableCameras.length > 0)
{
camera.deviceId = availableCameras[0].deviceId
camera.start()
}

}
}*/
function takePhoto() {
if (cameraSession.imageCapture.readyForCapture) {
if (cameraSource.readyForCapture) {
state = "snapshot"
cameraSession.imageCapture.capture()
cameraSource.captureImage()
} else {
renderer.state = "preview"
failed()
Expand Down Expand Up @@ -279,7 +191,7 @@ Item {
}
StateChangeScript {
script: {
camera.start()
cameraSource.start()
}
}
},
Expand Down Expand Up @@ -310,7 +222,7 @@ Item {
}
ScriptAction {
script: {
camera.stop()
cameraSource.stop()
}
}
}
Expand Down
Loading