Fix image opening and folder opening on Linux.
This commit is contained in:
parent
48076c69a5
commit
c1ca8b2234
5 changed files with 75 additions and 59 deletions
|
@ -1,70 +1,71 @@
|
|||
plugins {
|
||||
id 'java'
|
||||
id 'application'
|
||||
id 'org.jetbrains.kotlin.jvm' version '1.8.22'
|
||||
id 'org.javamodularity.moduleplugin' version '1.8.12'
|
||||
id 'org.openjfx.javafxplugin' version '0.0.13'
|
||||
id 'org.beryx.jlink' version '2.25.0'
|
||||
id 'java'
|
||||
id 'application'
|
||||
id 'org.jetbrains.kotlin.jvm' version '1.8.22'
|
||||
id 'org.javamodularity.moduleplugin' version '1.8.12'
|
||||
id 'org.openjfx.javafxplugin' version '0.0.13'
|
||||
id 'org.beryx.jlink' version '2.25.0'
|
||||
}
|
||||
|
||||
group 'com.nuculabs.dev'
|
||||
version '1.2'
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
ext {
|
||||
junitVersion = '5.10.0'
|
||||
junitVersion = '5.10.0'
|
||||
}
|
||||
|
||||
|
||||
tasks.withType(JavaCompile) {
|
||||
options.encoding = 'UTF-8'
|
||||
options.encoding = 'UTF-8'
|
||||
}
|
||||
|
||||
application {
|
||||
mainModule = 'dev.nuculabs.imagetagger.ui'
|
||||
mainClass = 'dev.nuculabs.imagetagger.ui.MainPage'
|
||||
mainModule = 'dev.nuculabs.imagetagger.ui'
|
||||
mainClass = 'dev.nuculabs.imagetagger.ui.MainPage'
|
||||
}
|
||||
kotlin {
|
||||
jvmToolchain( 17 )
|
||||
jvmToolchain(17)
|
||||
}
|
||||
|
||||
javafx {
|
||||
version = '21'
|
||||
modules = ['javafx.controls', 'javafx.fxml']
|
||||
version = '21'
|
||||
modules = ['javafx.controls', 'javafx.fxml']
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(":img-ai"))
|
||||
implementation(project(":img-core"))
|
||||
implementation('org.controlsfx:controlsfx:11.1.2')
|
||||
implementation('com.dlsc.formsfx:formsfx-core:11.6.0') {
|
||||
exclude(group: 'org.openjfx')
|
||||
}
|
||||
implementation('net.synedra:validatorfx:0.4.0') {
|
||||
exclude(group: 'org.openjfx')
|
||||
}
|
||||
implementation('org.kordamp.ikonli:ikonli-javafx:12.3.1')
|
||||
implementation('org.kordamp.ikonli:ikonli-fontawesome5-pack:12.3.1')
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1-Beta")
|
||||
testImplementation("org.junit.jupiter:junit-jupiter-api:${junitVersion}")
|
||||
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:${junitVersion}")
|
||||
implementation(project(":img-ai"))
|
||||
implementation(project(":img-core"))
|
||||
implementation('org.controlsfx:controlsfx:11.1.2')
|
||||
implementation('com.dlsc.formsfx:formsfx-core:11.6.0') {
|
||||
exclude(group: 'org.openjfx')
|
||||
}
|
||||
implementation('net.synedra:validatorfx:0.4.0') {
|
||||
exclude(group: 'org.openjfx')
|
||||
}
|
||||
implementation('org.kordamp.ikonli:ikonli-javafx:12.3.1')
|
||||
implementation('org.kordamp.ikonli:ikonli-fontawesome5-pack:12.3.1')
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1-Beta")
|
||||
implementation("org.apache.commons:commons-lang3:3.14.0")
|
||||
testImplementation("org.junit.jupiter:junit-jupiter-api:${junitVersion}")
|
||||
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:${junitVersion}")
|
||||
}
|
||||
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
useJUnitPlatform()
|
||||
}
|
||||
|
||||
jlink {
|
||||
imageZip = project.file("${buildDir}/distributions/ImageTagger-${javafx.platform.classifier}-${version}.zip")
|
||||
options = ['--strip-debug', '--compress', '2', '--no-header-files', '--no-man-pages']
|
||||
launcher {
|
||||
name = 'ImageTagger'
|
||||
}
|
||||
imageZip = project.file("${buildDir}/distributions/ImageTagger-${javafx.platform.classifier}-${version}.zip")
|
||||
options = ['--strip-debug', '--compress', '2', '--no-header-files', '--no-man-pages']
|
||||
launcher {
|
||||
name = 'ImageTagger'
|
||||
}
|
||||
}
|
||||
|
||||
jlinkZip {
|
||||
group = 'distribution'
|
||||
group = 'distribution'
|
||||
}
|
|
@ -15,6 +15,7 @@ module dev.nuculabs.imagetagger.ui {
|
|||
requires kotlinx.coroutines.core;
|
||||
requires dev.nuculabs.imagetagger.ai;
|
||||
requires dev.nuculabs.imagetagger.core;
|
||||
requires org.apache.commons.lang3;
|
||||
|
||||
opens dev.nuculabs.imagetagger.ui to javafx.fxml, javafx.graphics;
|
||||
opens dev.nuculabs.imagetagger.ui.controls to javafx.fxml, javafx.graphics;
|
||||
|
|
|
@ -2,6 +2,7 @@ package dev.nuculabs.imagetagger.ui.controls
|
|||
|
||||
import dev.nuculabs.imagetagger.core.AnalyzedImage
|
||||
import dev.nuculabs.imagetagger.ui.alerts.ErrorAlert
|
||||
import org.apache.commons.lang3.SystemUtils;
|
||||
import javafx.fxml.FXML
|
||||
import javafx.fxml.FXMLLoader
|
||||
import javafx.scene.control.Button
|
||||
|
@ -121,14 +122,21 @@ class ImageTagsEntryControl(private val image: AnalyzedImage) : HBox() {
|
|||
* If the operation fails it will display an error alert.
|
||||
*/
|
||||
fun onOpenImageClick() {
|
||||
if (Desktop.isDesktopSupported()) {
|
||||
val desktop = Desktop.getDesktop()
|
||||
if (desktop.isSupported(Desktop.Action.OPEN)) {
|
||||
desktop.open(File(image.absolutePath()))
|
||||
}
|
||||
if (image.hasError()) {
|
||||
return
|
||||
}
|
||||
if (SystemUtils.IS_OS_LINUX) {
|
||||
Runtime.getRuntime().exec("xdg-open ${image.absolutePath()}")
|
||||
} else {
|
||||
logger.severe("Cannot open image ${image.absolutePath()}. Desktop action not supported!")
|
||||
ErrorAlert("Can't open file: ${image.absolutePath()}\nOperation is not supported!")
|
||||
if (Desktop.isDesktopSupported()) {
|
||||
val desktop = Desktop.getDesktop()
|
||||
if (desktop.isSupported(Desktop.Action.OPEN)) {
|
||||
desktop.open(File(image.absolutePath()))
|
||||
}
|
||||
} else {
|
||||
logger.severe("Cannot open image ${image.absolutePath()}. Desktop action not supported!")
|
||||
ErrorAlert("Can't open file: ${image.absolutePath()}\nOperation is not supported!")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ import javafx.fxml.FXMLLoader
|
|||
import javafx.scene.control.Button
|
||||
import javafx.scene.control.Label
|
||||
import javafx.scene.layout.HBox
|
||||
import org.apache.commons.lang3.SystemUtils
|
||||
import java.awt.Desktop
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
|
@ -71,18 +72,22 @@ class ImageTagsSessionHeader : HBox() {
|
|||
* Opens the directory in the user's Desktop.
|
||||
*/
|
||||
fun openDirectory() {
|
||||
this.directoryPath?.let {
|
||||
if (Desktop.isDesktopSupported()) {
|
||||
val desktop = Desktop.getDesktop()
|
||||
if (desktop.isSupported(Desktop.Action.OPEN)) {
|
||||
desktop.open(File(it))
|
||||
directoryPath?.let {
|
||||
if (SystemUtils.IS_OS_LINUX) {
|
||||
Runtime.getRuntime().exec("xdg-open $directoryPath")
|
||||
} else {
|
||||
if (Desktop.isDesktopSupported()) {
|
||||
val desktop = Desktop.getDesktop()
|
||||
if (desktop.isSupported(Desktop.Action.OPEN)) {
|
||||
desktop.open(File(it))
|
||||
} else {
|
||||
logger.severe("Cannot open image directory $it. Desktop action not supported!")
|
||||
ErrorAlert("Can't open file: $it\nOperation is not supported!")
|
||||
}
|
||||
} else {
|
||||
logger.severe("Cannot open image directory $it. Desktop action not supported!")
|
||||
ErrorAlert("Can't open file: $it\nOperation is not supported!")
|
||||
}
|
||||
} else {
|
||||
logger.severe("Cannot open image directory $it. Desktop action not supported!")
|
||||
ErrorAlert("Can't open file: $it\nOperation is not supported!")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
19
readme.md
19
readme.md
|
@ -1,6 +1,7 @@
|
|||
# ![](./docs/image-analysis.png) Image Tagger
|
||||
# ![](./docs/image-analysis.png) Image Tagger
|
||||
|
||||
Image Tagger is a simple software application for predicting an image's keywords using a deep learning model based on resnet.
|
||||
Image Tagger is a simple software application for predicting an image's keywords using a deep learning model based on
|
||||
resnet.
|
||||
|
||||
It allows photographers to automate the image tagging process. 📸
|
||||
|
||||
|
@ -10,7 +11,7 @@ It allows photographers to automate the image tagging process. 📸
|
|||
|
||||
1. Download a release from the release page.
|
||||
2. Unzip the release.
|
||||
3. Run `ImageTagger\image\bin\ImageTagger`.
|
||||
3. Run `ImageTagger\image\bin\ImageTagger`.
|
||||
|
||||
![./docs/application.png](./docs/application.png)
|
||||
|
||||
|
@ -18,21 +19,20 @@ Photo credit: [https://unsplash.com/@ndcphoto](https://unsplash.com/@ndcphoto)
|
|||
|
||||
## Development
|
||||
|
||||
If you want to build the application yourself, you will need Java 17 JDK and the
|
||||
If you want to build the application yourself, you will need Java 17 JDK and the
|
||||
AI models available in the AIModels release.
|
||||
|
||||
The release archive is in the [releases page](https://github.com/dnutiu/ImageTagger/releases).
|
||||
|
||||
Note: Some desktop related features do not work under Linux. I have tested them on Fedora 39.
|
||||
Contributions are welcome :-)
|
||||
|
||||
Note: On Linux desktop related features (opening images, folders) are handled
|
||||
via [xdg-open](https://linux.die.net/man/1/xdg-open).
|
||||
|
||||
### Building and Running from source
|
||||
|
||||
To build from source you will need Java 17 JDK and Gradle.
|
||||
|
||||
Due to some GitHub limitations that do not allow me to upload large files, you'll need to download the AIModels
|
||||
zip file which contains the deep learning models and place them into the
|
||||
zip file which contains the deep learning models and place them into the
|
||||
`ImageTagger/img-ai/src/main/resources/dev/nuculabs/imagetagger/ai/` path.
|
||||
|
||||
To build the project run:
|
||||
|
@ -53,4 +53,5 @@ You can visit my tech blog at [https://blog.nuculabs.dev](https://blog.nuculabs.
|
|||
|
||||
# Credits
|
||||
|
||||
- Icons: <a href="https://www.flaticon.com/free-icons/image-analysis" title="image analysis icons">Image analysis icons created by Dewi Sari - Flaticon</a>
|
||||
- Icons: <a href="https://www.flaticon.com/free-icons/image-analysis" title="image analysis icons">Image analysis icons
|
||||
created by Dewi Sari - Flaticon</a>
|
Loading…
Reference in a new issue