Skip to content

Commit

Permalink
Add the command palette to extract the color palette from an image.
Browse files Browse the repository at this point in the history
  • Loading branch information
dwursteisen committed Jan 17, 2024
1 parent c453418 commit 512ed54
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class MainCommand : CliktCommand(invokeWithoutSubcommand = true) {
ExportCommand(),
ServeCommand(),
LibCommand(),
PaletteCommand(),
)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package com.github.minigdx.tiny.cli.command

import com.github.ajalt.clikt.core.CliktCommand
import com.github.ajalt.clikt.parameters.arguments.argument
import com.github.ajalt.clikt.parameters.options.default
import com.github.ajalt.clikt.parameters.options.flag
import com.github.ajalt.clikt.parameters.options.option
import com.github.ajalt.clikt.parameters.types.file
import com.github.minigdx.tiny.cli.config.GameParameters
import com.github.minigdx.tiny.cli.exception.MissingTinyConfigurationException
import com.github.minigdx.tiny.file.CommonVirtualFileSystem
import com.github.minigdx.tiny.log.StdOutLogger
import com.github.minigdx.tiny.platform.glfw.GlfwPlatform
import kotlinx.coroutines.runBlocking
import java.io.File

class PaletteCommand : CliktCommand(name = "palette", help = "Extract the color palette from an image.") {

val game by option(
help = "The directory containing all game information",
)
.file(mustExist = true, canBeDir = true, canBeFile = false)
.default(File("."))

val image by argument(
help = "The image used to extract the palette.",
).file(mustExist = true, canBeFile = true, canBeDir = false)

val append by option(help = "Append, instead of replacing, the palette information in the game file.")
.flag()

val print by option(help = "Print in the console the palette information, without updating the game.")
.flag()

override fun run() {
val tiny = game.resolve("_tiny.json")
if (!tiny.exists()) {
throw MissingTinyConfigurationException(tiny)
}
// Open the _tiny.json
val gameParameters = GameParameters.read(tiny)
val gameOptions = gameParameters.toGameOptions()
val platform = GlfwPlatform(gameOptions, StdOutLogger("whatever"), CommonVirtualFileSystem(), game)
val imageData = runBlocking {
platform.createImageStream(image.relativeTo(game).path).read()
}

val colors = mutableSetOf<String>()
if (append) {
// Append only new colors
colors.addAll(gameOptions.palette)
}
var extractedColors = emptyList<String>()

for (index in 0..(imageData.height * imageData.width) step 4) {
val r = imageData.data[index].toInt().coerceIn(0, 255)
val g = imageData.data[index + 1].toInt().coerceIn(0, 255)
val b = imageData.data[index + 2].toInt().coerceIn(0, 255)

// Convert to hex string
val hexString = String.format("#%02x%02x%02x", r, g, b).uppercase()
if (colors.add(hexString)) {
extractedColors = extractedColors + hexString
}
}

if (print) {
echo("\uD83C\uDFA8 Colors extracted from the file ${image.name}:")
extractedColors.forEach {
echo("- $it")
}
return
}

val replacedColors = if (append) {
gameOptions.palette + extractedColors
} else {
extractedColors
}

gameParameters.setPalette(replacedColors).write(tiny)
echo("\uD83C\uDFA8 Game has been updated with the new color palette (with ${replacedColors.size} colors)")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ sealed class GameParameters() {

abstract fun addSound(sound: String): GameParameters

abstract fun setPalette(colors: List<String>): GameParameters

/**
* Return the list of the user Lua script to load.
*/
Expand Down Expand Up @@ -143,4 +145,8 @@ data class GameParametersV1(
override fun addLibrary(lib: String): GameParameters {
return copy(libraries = libraries + lib)
}

override fun setPalette(colors: List<String>): GameParameters {
return copy(colors = colors)
}
}
37 changes: 36 additions & 1 deletion tiny-doc/src/docs/asciidoc/tiny-cli.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,38 @@ Alternatively, you can also manually add resources to your game by editing the `

With the `tiny-cli add` command, you can easily add new resources to your game and customize its functionality and appearance. Whether you are adding new spritesheets, sounds, or fonts, this command makes it easy to create the game of your dreams with the tiny game engine.

=== the `tiny-cli palette` command

The tiny-cli lib command is used extract a color palette from an image to use it in your `🧸 Tiny` game. This command provides an easy way to use colors from an image as your game's palette color.

==== Usage

To use the `tiny-cli palette` command, follow the syntax:

[source,shell]
tiny-cli palette <image_name>

For example:

[source,shell]
tiny-cli palette my_palette.png

This command will replace your game palette with the palette extract from the file.

You might want to check before which palette will be extract from the image using the flag `--print`:

[source,shell]
tiny-cli palette --print my_palette.png

If, instead to replace your game's color palette,
the flag `--append` can help you to append colors in your game's palette
instead of replacing it:

[source,shell]
tiny-cli palette --append my_palette.png

NOTE: Only colors that are not already in your game's palette will be appended, to not mess with colors index.

=== The `tiny-cli export` command

The `tiny-cli export` command is a tool for exporting your tiny game to a zip file, which includes all the assets needed to run the game in a browser. This command makes it easy to distribute your game and share it with others.
Expand Down Expand Up @@ -176,7 +208,7 @@ Where:

`--port [port number]`: Allows you to specify a custom port number to run the server on. The default port number is 8080.

==== Example Usage
==== Usage

To run the tiny serve command, you can use the following examples:

Expand Down Expand Up @@ -206,12 +238,14 @@ To use the `tiny-cli lib` command, follow the syntax:

[source,shell]
tiny-cli lib <library_name>

Replace <library_name> with the name of the library you want to download and add to your game.

For example, to download and add the particles library to your game, you would run the following command:

[source,shell]
tiny-cli lib particles

This command will download the particles library and add it to your game.

==== Library Repository
Expand All @@ -229,4 +263,5 @@ Here are a few examples to illustrate how to use the `tiny-cli lib` command:
Download and add the particles library to your game:
[source,shell]
tiny-cli lib particles

This command will download the particles library from the repository and add it to your game.

0 comments on commit 512ed54

Please sign in to comment.