diff --git a/lib/src/main/kotlin/dev/patbeagan/consolevision/BufferedImageExt.kt b/lib/src/main/kotlin/dev/patbeagan/consolevision/BufferedImageExt.kt new file mode 100644 index 0000000..2a9a187 --- /dev/null +++ b/lib/src/main/kotlin/dev/patbeagan/consolevision/BufferedImageExt.kt @@ -0,0 +1,18 @@ +package dev.patbeagan.consolevision + +import dev.patbeagan.consolevision.imagefilter.ImageFilter +import java.awt.image.BufferedImage + +inline fun BufferedImage.withLine( + onLineEnd: () -> Unit = {}, + action: (Int, Int) -> Unit, +) { + (minY until height).forEach { y -> + (minX until width).forEach { x -> action(y, x) } + onLineEnd() + } +} + +fun BufferedImage.applyFilter(imageFilter: ImageFilter) { + imageFilter(this) +} diff --git a/lib/src/main/kotlin/dev/patbeagan/consolevision/ConsoleVisionRuntime.kt b/lib/src/main/kotlin/dev/patbeagan/consolevision/ConsoleVisionRuntime.kt index ec36cd4..102b669 100644 --- a/lib/src/main/kotlin/dev/patbeagan/consolevision/ConsoleVisionRuntime.kt +++ b/lib/src/main/kotlin/dev/patbeagan/consolevision/ConsoleVisionRuntime.kt @@ -9,30 +9,28 @@ class ConsoleVisionRuntime( config: Config ) { - data class Config( - val reductionRate: Int, - val paletteReductionRate: Int, - val isCompatPalette: Boolean, - val shouldNormalize: Boolean, - val shouldMutateColors: Boolean = false - ) - - private val paletteColors: ColorPalette? = - paletteImage?.createColorPalette(config.paletteReductionRate) + private val paletteColors: ColorPalette? = paletteImage + ?.createColorPalette(config.paletteReductionRate) private val imagePrinter = ImagePrinter( config.reductionRate, ColorMapToAnsi(config.isCompatPalette), config.shouldNormalize, - config.shouldMutateColors + config.shouldMutateColors, + paletteColors, ) fun printFrame(file: BufferedImage): String { // // todo make this an option // print(CURSOR_TO_START) - return imagePrinter.getFrame( - file, - paletteColors - ) + return imagePrinter.getFrame(file) } + + data class Config( + val reductionRate: Int, + val paletteReductionRate: Int, + val isCompatPalette: Boolean, + val shouldNormalize: Boolean, + val shouldMutateColors: Boolean = false + ) } diff --git a/lib/src/main/kotlin/dev/patbeagan/consolevision/ImagePrinter.kt b/lib/src/main/kotlin/dev/patbeagan/consolevision/ImagePrinter.kt index 7870b22..84ae998 100644 --- a/lib/src/main/kotlin/dev/patbeagan/consolevision/ImagePrinter.kt +++ b/lib/src/main/kotlin/dev/patbeagan/consolevision/ImagePrinter.kt @@ -4,7 +4,6 @@ import dev.patbeagan.consolevision.ansi.AnsiColor import dev.patbeagan.consolevision.ansi.StyleExtensions.style import dev.patbeagan.consolevision.imagefilter.ColorMutation import dev.patbeagan.consolevision.imagefilter.ColorNormalization -import dev.patbeagan.consolevision.imagefilter.applyFilter import dev.patbeagan.consolevision.types.ColorInt import dev.patbeagan.consolevision.types.ColorPalette import dev.patbeagan.consolevision.types.CompressionStyle @@ -20,17 +19,15 @@ class ImagePrinter( private val colorMapToAnsi: ColorMapToAnsi, private val shouldNormalizeColors: Boolean, private val shouldMutateColors: Boolean = false, + private val paletteColors: ColorPalette? = null, + private val compressionStyle: CompressionStyle = LOWER_HALF, ) { private val applyPalette: (ColorInt, ColorPalette?) -> ColorInt = { colorInt: ColorInt, palette: ColorPalette? -> palette?.matchColor(colorInt) ?: colorInt }.memoize() - fun getFrame( - read: BufferedImage, - paletteColors: ColorPalette? = null, - compressionStyle: CompressionStyle = LOWER_HALF, - ): String { + fun getFrame(read: BufferedImage): String { applyFilters(read) val out = buildOutput(read, compressionStyle, paletteColors) return out.toString() diff --git a/lib/src/main/kotlin/dev/patbeagan/consolevision/imagefilter/ColorMutation.kt b/lib/src/main/kotlin/dev/patbeagan/consolevision/imagefilter/ColorMutation.kt index 913bcdb..2f62f9e 100644 --- a/lib/src/main/kotlin/dev/patbeagan/consolevision/imagefilter/ColorMutation.kt +++ b/lib/src/main/kotlin/dev/patbeagan/consolevision/imagefilter/ColorMutation.kt @@ -1,6 +1,7 @@ package dev.patbeagan.consolevision.imagefilter import dev.patbeagan.consolevision.types.ColorInt +import dev.patbeagan.consolevision.withLine import java.awt.image.BufferedImage import kotlin.random.Random diff --git a/lib/src/main/kotlin/dev/patbeagan/consolevision/imagefilter/ColorNormalization.kt b/lib/src/main/kotlin/dev/patbeagan/consolevision/imagefilter/ColorNormalization.kt index efe192a..6f4a193 100644 --- a/lib/src/main/kotlin/dev/patbeagan/consolevision/imagefilter/ColorNormalization.kt +++ b/lib/src/main/kotlin/dev/patbeagan/consolevision/imagefilter/ColorNormalization.kt @@ -1,6 +1,7 @@ package dev.patbeagan.consolevision.imagefilter import dev.patbeagan.consolevision.types.ColorInt +import dev.patbeagan.consolevision.withLine import java.awt.image.BufferedImage /** diff --git a/lib/src/main/kotlin/dev/patbeagan/consolevision/imagefilter/ImageFilter.kt b/lib/src/main/kotlin/dev/patbeagan/consolevision/imagefilter/ImageFilter.kt index fd2c3de..ea822a1 100644 --- a/lib/src/main/kotlin/dev/patbeagan/consolevision/imagefilter/ImageFilter.kt +++ b/lib/src/main/kotlin/dev/patbeagan/consolevision/imagefilter/ImageFilter.kt @@ -5,17 +5,3 @@ import java.awt.image.BufferedImage interface ImageFilter { operator fun invoke(bufferedImage: BufferedImage) } - -inline fun BufferedImage.withLine( - onLineEnd: () -> Unit = {}, - action: (Int, Int) -> Unit, -) { - (minY until height).forEach { y -> - (minX until width).forEach { x -> action(y, x) } - onLineEnd() - } -} - -fun BufferedImage.applyFilter(imageFilter: ImageFilter) { - imageFilter(this) -} diff --git a/lib/src/main/kotlin/dev/patbeagan/consolevision/types/ColorPalette.kt b/lib/src/main/kotlin/dev/patbeagan/consolevision/types/ColorPalette.kt index 866112b..f4fb2e7 100644 --- a/lib/src/main/kotlin/dev/patbeagan/consolevision/types/ColorPalette.kt +++ b/lib/src/main/kotlin/dev/patbeagan/consolevision/types/ColorPalette.kt @@ -2,8 +2,7 @@ package dev.patbeagan.consolevision.types @JvmInline value class ColorPalette(private val palette: Set) { - fun matchColor(colorInt: ColorInt): ColorInt? = - palette.minByOrNull { - colorInt.removeAlpha().colorDistanceFrom(it) - } + fun matchColor(colorInt: ColorInt): ColorInt? = palette.minByOrNull { + colorInt.removeAlpha().colorDistanceFrom(it) + } } diff --git a/lib/src/main/kotlin/dev/patbeagan/consolevision/types/CompressedPoint.kt b/lib/src/main/kotlin/dev/patbeagan/consolevision/types/CompressedPoint.kt index 9054f60..70601a1 100644 --- a/lib/src/main/kotlin/dev/patbeagan/consolevision/types/CompressedPoint.kt +++ b/lib/src/main/kotlin/dev/patbeagan/consolevision/types/CompressedPoint.kt @@ -11,12 +11,12 @@ value class CompressedPoint(private val base: Long) { /** * The first coordinate in the CompressedPoint */ - val x get() = (base shr 32).toInt() + val x: Int get() = (base shr 32).toInt() /** * The second coordinate in the CompressedPoint */ - val y get() = base.toInt() // (base and (2.0.pow(32) - 1).toLong()).toInt() + val y: Int get() = base.toInt() // (base and (2.0.pow(32) - 1).toLong()).toInt() override fun toString(): String = "CompressedPoint of ${this.x} to ${this.y}\n" + diff --git a/lib/src/main/kotlin/dev/patbeagan/consolevision/util/BufferedImageExtensions.kt b/lib/src/main/kotlin/dev/patbeagan/consolevision/util/BufferedImageExtensions.kt index afe1dba..f6e5347 100644 --- a/lib/src/main/kotlin/dev/patbeagan/consolevision/util/BufferedImageExtensions.kt +++ b/lib/src/main/kotlin/dev/patbeagan/consolevision/util/BufferedImageExtensions.kt @@ -5,11 +5,6 @@ import dev.patbeagan.consolevision.types.ColorPalette import java.awt.image.BufferedImage import java.awt.image.DataBufferByte -fun BufferedImage.getByteData(): ByteArray { - val buffer = raster.dataBuffer as DataBufferByte - return buffer.data -} - fun BufferedImage.createColorPalette( paletteReductionRate: Int, ): ColorPalette { diff --git a/lib/src/test/kotlin/dev/patbeagan/consolevision/util/ImagePrinterTest.kt b/lib/src/test/kotlin/dev/patbeagan/consolevision/util/ImagePrinterTest.kt index f31ce12..61ef9e9 100644 --- a/lib/src/test/kotlin/dev/patbeagan/consolevision/util/ImagePrinterTest.kt +++ b/lib/src/test/kotlin/dev/patbeagan/consolevision/util/ImagePrinterTest.kt @@ -20,13 +20,21 @@ internal class ImagePrinterTest { @Before fun setup() { - imagePrinter = ImagePrinter(0, ColorMapToAnsi(false), shouldNormalizeColors = false) + imagePrinter = ImagePrinter( + 0, + ColorMapToAnsi(false), + shouldNormalizeColors = false, + ) } @Test fun compatPalette() { println( - ImagePrinter(0, ColorMapToAnsi(true), shouldNormalizeColors = false).getFrame( + ImagePrinter( + 0, + ColorMapToAnsi(true), + shouldNormalizeColors = false, + ).getFrame( getScaledImage(readAsset(LENNA)) ) ) @@ -43,7 +51,11 @@ internal class ImagePrinterTest { @Test fun `sample image fullsize normalized`() { println("sample image fullsize normalized") - ImagePrinter(0, ColorMapToAnsi(false), shouldNormalizeColors = true) + ImagePrinter( + 0, + ColorMapToAnsi(false), + shouldNormalizeColors = true, + ) .getFrame(readAsset(IMAGE_SMALL)).also { println(it) } } @@ -55,10 +67,18 @@ internal class ImagePrinterTest { val read2 = getScaledImage(read) println("Normalized: TRUE") - ImagePrinter(0, ColorMapToAnsi(false), shouldNormalizeColors = true).getFrame(read1) + ImagePrinter( + 0, + ColorMapToAnsi(false), + shouldNormalizeColors = true, + ).getFrame(read1) .also { println(it) } println("Normalized: FALSE") - ImagePrinter(0, ColorMapToAnsi(false), shouldNormalizeColors = false).getFrame(read2) + ImagePrinter( + 0, + ColorMapToAnsi(false), + shouldNormalizeColors = false, + ).getFrame(read2) .also { println(it) } } @@ -70,10 +90,18 @@ internal class ImagePrinterTest { val read2 = getScaledImage(read) println("Reduced: TRUE") - ImagePrinter(8, ColorMapToAnsi(false), shouldNormalizeColors = false).getFrame(read1) + ImagePrinter( + 8, + ColorMapToAnsi(false), + shouldNormalizeColors = false, + ).getFrame(read1) .also { println(it) } println("Reduced: FALSE") - ImagePrinter(0, ColorMapToAnsi(false), shouldNormalizeColors = false).getFrame(read2) + ImagePrinter( + 0, + ColorMapToAnsi(false), + shouldNormalizeColors = false, + ).getFrame(read2) .also { println(it) } } @@ -85,10 +113,18 @@ internal class ImagePrinterTest { val read2 = getScaledImage(read) println("Reduced: TRUE") - ImagePrinter(40, ColorMapToAnsi(false), shouldNormalizeColors = false).getFrame(read1) + ImagePrinter( + 40, + ColorMapToAnsi(false), + shouldNormalizeColors = false, + ).getFrame(read1) .also { println(it) } println("Reduced: FALSE") - ImagePrinter(0, ColorMapToAnsi(false), shouldNormalizeColors = false).getFrame(read2) + ImagePrinter( + 0, + ColorMapToAnsi(false), + shouldNormalizeColors = false, + ).getFrame(read2) .also { println(it) } } @@ -100,9 +136,13 @@ internal class ImagePrinterTest { @Test fun `sample image compressed dots`() { println("sample image compressed dots") - imagePrinter.getFrame( - readAsset(IMAGE_SMALL), + ImagePrinter( + 0, + ColorMapToAnsi(false), + shouldNormalizeColors = false, compressionStyle = CompressionStyle.DOTS_HIGH + ).getFrame( + readAsset(IMAGE_SMALL), ).also { println(it) } } @@ -126,7 +166,7 @@ internal class ImagePrinterTest { 0, ColorMapToAnsi(true), shouldNormalizeColors = true, - shouldMutateColors = true + shouldMutateColors = true, ).getFrame(image) .also { println(it) } } @@ -168,9 +208,14 @@ internal class ImagePrinterTest { }.forEach { (first, second) -> val (scale, transformOp) = read.getScaleToBoundBy(70, 70) println(first) - imagePrinter.getFrame( - read.scale(scale, transformOp), - second?.createColorPalette(0) + ImagePrinter( + 0, + ColorMapToAnsi(false), + shouldNormalizeColors = false, + compressionStyle = CompressionStyle.LOWER_HALF, + paletteColors = second?.createColorPalette(0), + ).getFrame( + read.scale(scale, transformOp) ).also { println(it) } } } diff --git a/server/src/main/kotlin/dev/patbeagan/consolevision/server/routes/PostUpdateRoute.kt b/server/src/main/kotlin/dev/patbeagan/consolevision/server/routes/PostUpdateRoute.kt index e1639a2..6eb2129 100644 --- a/server/src/main/kotlin/dev/patbeagan/consolevision/server/routes/PostUpdateRoute.kt +++ b/server/src/main/kotlin/dev/patbeagan/consolevision/server/routes/PostUpdateRoute.kt @@ -4,7 +4,6 @@ import dev.patbeagan.consolevision.ConsoleVisionRuntime import dev.patbeagan.consolevision.ImageScaler import dev.patbeagan.consolevision.server.RouteHandler import dev.patbeagan.consolevision.util.Const -import dev.patbeagan.consolevision.util.getByteData import io.ktor.application.* import io.ktor.http.content.* import io.ktor.request.* @@ -14,6 +13,7 @@ import org.apache.commons.codec.digest.DigestUtils import org.koin.core.component.inject import org.slf4j.Logger import java.awt.image.BufferedImage +import java.awt.image.DataBufferByte import java.io.ByteArrayInputStream import java.io.File import java.io.FileWriter @@ -104,9 +104,15 @@ class PostUpdateRoute : RouteHandler { } } } + is PartData.FormItem -> TODO() is PartData.BinaryItem -> TODO() } } } +} + +fun BufferedImage.getByteData(): ByteArray { + val buffer = raster.dataBuffer as DataBufferByte + return buffer.data } \ No newline at end of file