Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import java.awt.Color
- import java.awt.Image
- import java.awt.RenderingHints
- import java.awt.image.BufferedImage
- import java.io.File
- import java.util.stream.IntStream
- import javax.imageio.ImageIO
- import kotlin.math.sqrt
- import kotlin.random.Random
- class Converter(private val inputImage: String, private val outputFormat: String, private val randomCount: Int) {
- private val colors = hashMapOf<Color, String>()
- private val singleCache = hashMapOf<Color, String>()
- private val multiCache = hashMapOf<Color, ArrayList<String>>()
- fun convert(): String {
- loadColors()
- val original = ImageIO.read(File(inputImage))
- val base = getBase(original)
- val mosaic = BufferedImage(base.width * 100, base.height * 100, BufferedImage.TYPE_INT_RGB)
- val mosaicg2d = mosaic.createGraphics()
- mosaicg2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR)
- IntStream.range(1, base.width - 1).parallel().forEach { x ->
- IntStream.range(1, base.height - 1).parallel().forEach { y ->
- val baseColor = Color(base.getRGB(x, y))
- val imagePath = if (randomCount == 1) getSingleColor(baseColor) else getMultiColor(baseColor, randomCount)
- val image = ImageIO.read(File(imagePath))
- mosaicg2d.drawImage(image, x * 100, y * 100, x * 100 + 100, y * 100 + 100,
- 0, 0, 100, 100, null)
- }
- }
- mosaicg2d.dispose()
- val outputFile = generateOutputFile(File(inputImage).parentFile.path)
- ImageIO.write(mosaic, outputFormat, outputFile)
- return outputFile.path
- }
- private fun loadColors() {
- for (s in File("D:\\clopscaled.txt").readLines()) {
- val split = s.split(":")
- val red = split[2].toInt()
- val green = split[3].toInt()
- val blue = split[4].toInt()
- val color = Color(red, green, blue)
- colors[color] = "${split[0]}:${split[1]}"
- }
- println("${colors.size} colors loaded")
- }
- private fun getBase(image: BufferedImage): BufferedImage {
- return if (image.width * 100L * image.height * 100L <= 900000000L) {
- println("No need to resize")
- image
- } else {
- val scale = 300 * sqrt(1F / (image.width * image.height))
- println("Scale factor $scale")
- resizeImage(image, scale)
- }
- }
- private fun resizeImage(image: BufferedImage, factor: Float): BufferedImage {
- val newWidth = (image.width * factor).toInt()
- val newHeight = (image.height * factor).toInt()
- val tmp = image.getScaledInstance(newWidth, newHeight, Image.SCALE_SMOOTH)
- val resized = BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB)
- val g2d = resized.createGraphics()
- g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR)
- g2d.drawImage(tmp, 0, 0, null)
- g2d.dispose()
- return resized
- }
- private fun getSingleColor(baseColor: Color): String {
- if (singleCache.containsKey(baseColor))
- return singleCache[baseColor]!!
- val red = baseColor.red
- val green = baseColor.green
- val blue = baseColor.blue
- var diff = 0
- while (true) {
- for (color in colors.keys) {
- if (color.red <= red + diff && color.red >= red - diff
- && color.green <= green + diff && color.green >= green - diff
- && color.blue <= blue + diff && color.blue >= blue - diff) {
- val image = colors[color]!!
- singleCache[baseColor] = image
- return image
- }
- }
- diff++
- }
- }
- private fun getMultiColor(baseColor: Color, amount: Int): String {
- if (multiCache.containsKey(baseColor)) {
- return multiCache[baseColor]!!.random()
- }
- val red = baseColor.red
- val green = baseColor.green
- val blue = baseColor.blue
- val selection = arrayListOf<String>()
- var diff = 0
- while (true) {
- for (color in colors.keys) {
- if (red + diff >= color.red && red - diff <= color.red
- && green + diff >= color.green && green - diff <= color.green
- && blue + diff >= color.blue && blue - diff <= color.blue) {
- val image = colors[color]!!
- if (!selection.contains(image))
- selection.add(image)
- if (selection.size == amount) {
- multiCache[baseColor] = selection
- return selection.random()
- }
- }
- }
- diff++
- }
- }
- fun generateOutputFile(dir: String): File {
- val chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
- var filename = ""
- for (i in 0..10) {
- filename += chars[Random.nextInt(0, chars.length)]
- }
- return File("$dir\\$filename.$outputFormat")
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement