Skip to content

Commit

Permalink
Improved color calculation and added lock for single running instance
Browse files Browse the repository at this point in the history
  • Loading branch information
milux committed Nov 11, 2018
1 parent a4bd702 commit 28f8acb
Showing 1 changed file with 44 additions and 33 deletions.
77 changes: 44 additions & 33 deletions src/main/kotlin/de/milux/ppcolor/Main.kt
Original file line number Diff line number Diff line change
@@ -1,21 +1,31 @@
package de.milux.ppcolor

import java.awt.*
import java.io.RandomAccessFile
import java.lang.Thread.sleep
import java.util.*
import kotlin.math.abs
import kotlin.math.max
import kotlin.system.exitProcess

const val MIN_ROUND_TIME = 100L
val SCALE_FACTOR = Toolkit.getDefaultToolkit().screenResolution / 96.0
const val STEPS_X = 20
const val STEPS_Y = 20
const val RGB_MIN_DIFF = 25

fun main(args : Array<String>) {
val lockFile = RandomAccessFile("ppcolor.lock", "rw")
val lock = lockFile.channel.tryLock()
if (lock == null) {
println("Already running!")
exitProcess(1)
}

val screenDevices = GraphicsEnvironment.getLocalGraphicsEnvironment().screenDevices
if (screenDevices.size < 2) {
println("No Second Screen detected!")
exitProcess(1)
exitProcess(2)
}
val screenBounds = screenDevices[1].defaultConfiguration.bounds
val robot = Robot()
Expand All @@ -27,10 +37,9 @@ fun main(args : Array<String>) {
(screenBounds.height / SCALE_FACTOR).toInt()
)

val stepX = (screenBounds.width / SCALE_FACTOR - 20) / STEPS_X
val stepY = (screenBounds.height / SCALE_FACTOR - 20) / STEPS_Y
val baseX = 10
val baseY = 10
val stepX = ((screenBounds.width - 1) / SCALE_FACTOR) / STEPS_X
val stepY = ((screenBounds.height - 1) / SCALE_FACTOR) / STEPS_Y
val numValues = STEPS_X * STEPS_Y / 4

while(true) {
val time = System.currentTimeMillis()
Expand All @@ -41,44 +50,46 @@ fun main(args : Array<String>) {
// ImageIO.write(image, "png", File("ss" + System.currentTimeMillis() + ".png"))
val colorModel = image.colorModel

for (sx in 0..STEPS_X) {
for (sy in 0..STEPS_Y) {
val rgb = image.getRGB((baseX + sx * stepX).toInt(), (baseY + sy * stepY).toInt())
for (sx in 0 .. STEPS_X) {
for (sy in 0 .. STEPS_Y) {
val rgb = image.getRGB((sx * stepX).toInt(), (sy * stepY).toInt())
val color = Color(colorModel.getRed(rgb), colorModel.getGreen(rgb), colorModel.getBlue(rgb))
rawList += color
}
}

// Take the upper quarter with the brightest values
val sortedColors = rawList.sortedBy { it.red + it.green + it.blue }
val colorList = sortedColors.slice(STEPS_X * STEPS_Y / 4 * 3 .. STEPS_X * STEPS_Y)

val clSize = colorList.size
val mainColor = Color(
colorList.sumBy { it.red } / clSize,
colorList.sumBy { it.green } / clSize,
colorList.sumBy { it.blue } / clSize
)
print(mainColor)
val sortedColors = rawList
.filter { abs(it.red - it.green) > RGB_MIN_DIFF
|| abs(it.green - it.blue) > RGB_MIN_DIFF
|| abs(it.red - it.blue) > RGB_MIN_DIFF }
.sortedBy {
val hsb = Color.RGBtoHSB(it.red, it.green, it.blue, null)
hsb[1] * hsb[2]
}
// Only execute if we have color values
if (sortedColors.isNotEmpty()) {
val colorList = sortedColors
.slice(max(0, sortedColors.size - numValues) until sortedColors.size)

val hsb = Color.RGBtoHSB(mainColor.red, mainColor.green, mainColor.blue, null)
// Maximize saturation
hsb[1] = 1.0f
val satColor = Color.getHSBColor(hsb[0], hsb[1], hsb[2])
val clSize = colorList.size
val mainColor = Color(
colorList.sumBy { it.red } / clSize,
colorList.sumBy { it.green } / clSize,
colorList.sumBy { it.blue } / clSize
)
print(mainColor)

val ccMax = max(max(satColor.red, satColor.green), satColor.blue)
val scaleFactor = 255.0 / ccMax
val normColor = Color(
(satColor.red * scaleFactor).toInt(),
(satColor.green * scaleFactor).toInt(),
(satColor.blue * scaleFactor).toInt()
)
val hsb = Color.RGBtoHSB(mainColor.red, mainColor.green, mainColor.blue, null)
// Maximize saturation and brightness
val satColor = Color.getHSBColor(hsb[0], 1.0f, 1.0f)

print(" -> ")
print(normColor)
println()
print(" -> ")
print(satColor)
println()

calcThread.setTargetColor(normColor)
calcThread.setTargetColor(satColor)
}

// Sleep after each cycle until MIN_ROUND_TIME ms are over
val sleepTime = MIN_ROUND_TIME - (System.currentTimeMillis() - time)
Expand Down

0 comments on commit 28f8acb

Please sign in to comment.