Skip to content

Instantly share code, notes, and snippets.

@nea89o
Created February 14, 2024 15:57
Show Gist options
  • Save nea89o/bc8b65685c0a061d797bb615e524eeab to your computer and use it in GitHub Desktop.
Save nea89o/bc8b65685c0a061d797bb615e524eeab to your computer and use it in GitHub Desktop.
Replaces black backgrounds with transparent ones. Essentially scales the transparency with the respective brightness of the each pixel.
import java.awt.Color
import java.awt.image.BufferedImage
import java.io.File
import javax.imageio.ImageIO
import kotlin.system.exitProcess
fun main(args: Array<String>) {
var inf: File? = null
var outf: File? = null
var doinvpremul = false
var i = 0
while (i in args.indices) {
val arg = args[i]
val hasNext = i + 1 in args.indices
if (arg == "--inverse-premultiplication") {
doinvpremul = true
} else if (arg == "--in" && hasNext) {
inf = File(args[++i])
} else if (arg == "--out" && hasNext) {
outf = File(args[++i])
}
i += 1
}
if (inf == null || outf == null) {
println("Usage: --in <infile> --out <outfile> [--inverse-premultiplication]")
exitProcess(1)
}
val img = ImageIO.read((inf))
val target = BufferedImage(img.width, img.height, BufferedImage.TYPE_INT_ARGB)
for (x in 0 until img.width) {
for (y in 0 until img.height) {
val rgb = Color(img.getRGB(x, y))
val hsl = Color.RGBtoHSB(rgb.red, rgb.green, rgb.blue, null)
val lum = hsl[2]
fun invpremul(x: Int) = if (doinvpremul) (x / lum).toInt().coerceAtMost(255) else x
target.setRGB(
x, y,
(invpremul(rgb.red) shl 16)
or (invpremul(rgb.blue) shl 0)
or (invpremul(rgb.green) shl 8)
or ((lum * 255).toInt() shl 24)
)
}
}
ImageIO.write(target, "PNG", (outf))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment