Working with Images in Kotlin: Library Overview and Practical Examples
Kotlin is a modern programming language that runs on top of the JVM. Thanks to full compatibility with Java, all standard Java libraries such as javax.imageio, java.awt, and javax.swing can be used for image processing. In this article, we will look at the main approaches to working with images in Kotlin: reading, writing, resizing, applying filters, and format conversion.
Required Libraries
To work with images in Kotlin (JVM), no additional dependencies are required — the standard JDK library is sufficient. However, for more complex tasks (e.g., processing large images or working with metadata), third-party libraries may be needed:
- java.awt.image.BufferedImage — the main class for representing an image in memory.
- javax.imageio.ImageIO — reading and writing images in various formats (PNG, JPEG, BMP, GIF).
- java.awt.Graphics2D — drawing and transformations.
- Thumbnailator (optional) — simplifies resizing and creating thumbnails.
- BoofCV (optional) — a computer vision library with Kotlin support.
Reading and Writing Images
The simplest way to load an image is to use ImageIO.read().
import java.awt.image.BufferedImageimport java.io.Fileimport javax.imageio.ImageIO
fun main() { // Reading an image val inputFile = File("input.jpg") val image: BufferedImage = ImageIO.read(inputFile) ?: throw Exception("Failed to load image")
// Writing in a different format val outputFile = File("output.png") ImageIO.write(image, "png", outputFile)
println("Image saved: ${outputFile.absolutePath}")}Resizing an Image
To resize, we use Graphics2D with smoothing parameters.
import java.awt.Graphics2Dimport java.awt.RenderingHintsimport java.awt.image.BufferedImageimport javax.imageio.ImageIOimport java.io.File
fun resizeImage(inputPath: String, outputPath: String, targetWidth: Int, targetHeight: Int) { val original: BufferedImage = ImageIO.read(File(inputPath)) val resized = BufferedImage(targetWidth, targetHeight, BufferedImage.TYPE_INT_RGB) val g2d: Graphics2D = resized.createGraphics()
// Enable smoothing for high-quality scaling g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR) g2d.drawImage(original, 0, 0, targetWidth, targetHeight, null) g2d.dispose()
ImageIO.write(resized, "jpg", File(outputPath)) println("Image resized: $outputPath")}
fun main() { resizeImage("input.jpg", "resized.jpg", 800, 600)}Applying Filters (Blur, Contrast)
For simple effects, you can use BufferedImageOp (e.g., ConvolveOp for blur).
import java.awt.image.BufferedImageimport java.awt.image.ConvolveOpimport java.awt.image.Kernelimport javax.imageio.ImageIOimport java.io.File
fun applyBlur(inputPath: String, outputPath: String) { val image: BufferedImage = ImageIO.read(File(inputPath))
// 5x5 blur kernel val size = 5 val weight = 1.0f / (size * size) val kernelData = FloatArray(size * size) { weight } val kernel = Kernel(size, size, kernelData) val blurOp = ConvolveOp(kernel)
val blurred = blurOp.filter(image, null) ImageIO.write(blurred, "jpg", File(outputPath))}
fun main() { applyBlur("input.jpg", "blurred.jpg")}Format Conversion
Simply p