125 lines
4.5 KiB
Kotlin
125 lines
4.5 KiB
Kotlin
package io.gitlab.jfronny.compareimage
|
|
|
|
import javafx.application.Application
|
|
import javafx.collections.FXCollections
|
|
import javafx.fxml.FXMLLoader
|
|
import javafx.scene.Scene
|
|
import javafx.scene.SnapshotParameters
|
|
import javafx.scene.chart.CategoryAxis
|
|
import javafx.scene.chart.NumberAxis
|
|
import javafx.scene.chart.StackedBarChart
|
|
import javafx.scene.chart.XYChart
|
|
import javafx.scene.chart.XYChart.Series
|
|
import javafx.scene.image.WritableImage
|
|
import javafx.stage.Stage
|
|
import java.awt.image.BufferedImage
|
|
import java.nio.file.Files
|
|
import java.nio.file.Path
|
|
import java.util.*
|
|
import javax.imageio.ImageIO
|
|
import kotlin.io.path.Path
|
|
import kotlin.io.path.isDirectory
|
|
import kotlin.io.path.listDirectoryEntries
|
|
import kotlin.io.path.outputStream
|
|
|
|
class HelloApplication : Application() {
|
|
override fun start(stage: Stage) {
|
|
// Establish a task queue
|
|
val queue: Queue<() -> Unit> = LinkedList()
|
|
val immediate: Queue<() -> Unit> = LinkedList()
|
|
|
|
fun update() {
|
|
while (immediate.isNotEmpty()) immediate.remove()()
|
|
if (queue.isNotEmpty()) queue.remove()()
|
|
}
|
|
|
|
// Get data from parameters
|
|
val options = parameters.raw.map { Path(it) }.map { PickerOption(it) }
|
|
val permutations = options.run { flatMapIndexed { i, left -> subList(1 + i, size).map { right -> left to right } } }
|
|
|
|
// Show screen for single decision
|
|
permutations.forEachIndexed { i, it ->
|
|
queue.add {
|
|
if (it.first.score < -3 || it.second.score < -3) {
|
|
update()
|
|
return@add
|
|
}
|
|
|
|
val fxmlLoader = FXMLLoader(HelloApplication::class.java.getResource("picker-view.fxml"))
|
|
val scene = Scene(fxmlLoader.load(), 320.0, 240.0)
|
|
val controller = fxmlLoader.getController<PickerController>()
|
|
val permutationStage = Stage()
|
|
controller.hydrate(it.first, it.second, close = {
|
|
permutationStage.close()
|
|
update()
|
|
})
|
|
permutationStage.setOnCloseRequest { update() }
|
|
permutationStage.title = "${i + 1} / ${permutations.size}"
|
|
permutationStage.scene = scene
|
|
permutationStage.show()
|
|
immediate.add {
|
|
val s = when (controller.state) {
|
|
PickedState.LEFT -> it.first to it.second
|
|
PickedState.RIGHT -> it.second to it.first
|
|
else -> null
|
|
}
|
|
if (s != null) {
|
|
s.first.score++
|
|
s.second.score--
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Show tally screen
|
|
queue.add {
|
|
val data = options.toList()
|
|
.filter { it.score >= 0 }
|
|
.sortedByDescending { it.score }
|
|
.map { it.file.fileName.toString() to it.score }
|
|
|
|
val xAxis = CategoryAxis()
|
|
val yAxis = NumberAxis()
|
|
val sbc = StackedBarChart(xAxis, yAxis)
|
|
val series = Series<String, Number>()
|
|
|
|
stage.title = "Tally"
|
|
sbc.title = "Tally"
|
|
xAxis.label = "File"
|
|
xAxis.categories = FXCollections.observableArrayList(data.map { it.first })
|
|
yAxis.label = "Value"
|
|
series.name = "Files"
|
|
series.data.addAll(data.map { XYChart.Data(it.first, it.second) })
|
|
val scene = Scene(sbc, 800.0, 600.0)
|
|
sbc.data.addAll(series)
|
|
|
|
val path = Files.createTempFile("compare-image-", ".png")
|
|
writeImage(sbc.snapshot(SnapshotParameters(), null), path)
|
|
println("Wrote image to: $path")
|
|
|
|
stage.scene = scene
|
|
stage.show()
|
|
}
|
|
|
|
update()
|
|
}
|
|
}
|
|
|
|
fun writeImage(image: WritableImage, path: Path) {
|
|
val buf = BufferedImage(image.width.toInt(), image.height.toInt(), BufferedImage.TYPE_INT_ARGB)
|
|
val reader = image.pixelReader
|
|
for (x in 0 until buf.width) {
|
|
for (y in 0 until buf.height) {
|
|
buf.setRGB(x, y, reader.getArgb(x, y))
|
|
}
|
|
}
|
|
path.outputStream().use { ImageIO.write(buf, "png", it) }
|
|
}
|
|
|
|
fun main(args: Array<String>) {
|
|
Application.launch(HelloApplication::class.java, *(
|
|
if (args.size > 1) args
|
|
else if (args.size == 1 && Path(args[0]).isDirectory()) Path(args[0]).listDirectoryEntries().map { it.toString() }.toTypedArray()
|
|
else throw IllegalArgumentException("Please specify the images to compare")
|
|
))
|
|
} |