Работа с изображениями в Kotlin: изменение размера и кадрирование (resize & crop)
В современной веб-разработке и создании мобильных приложений на Kotlin часто возникает необходимость программно обрабатывать изображения: уменьшать размер для оптимизации загрузки, обрезать лишние края или подготавливать превью. В этой статье мы рассмотрим мощный инструмент для работы с графикой — библиотеку ImageMagick (через Java-обёртку JMagick), которая идеально подходит для задач resize и crop на Kotlin.
Что такое ImageMagick и JMagick?
ImageMagick — это кроссплатформенное программное обеспечение с открытым исходным кодом для создания, редактирования и преобразования растровых изображений. Оно поддерживает более 200 форматов (JPEG, PNG, GIF, WebP, TIFF и другие). Для работы с ImageMagick из Java/Kotlin используется библиотека JMagick, предоставляющая Java Native Interface (JNI) к функциям ImageMagick.
Преимущества использования ImageMagick в Kotlin:
- Высокая производительность (нативный код C/C++)
- Богатый функционал: resize, crop, rotate, фильтры, конвертация форматов
- Поддержка потоковой обработки больших изображений
- Точный контроль качества при сжатии
Установка и подключение
Для работы с JMagick необходимо установить нативный ImageMagick на вашу систему. Затем добавьте зависимость в build.gradle.kts (для Gradle):
dependencies {
implementation("org.im4java:im4java:1.4.0") // Альтернативная обёртка
// Или используйте JMagick:
implementation("org.jmagick:jmagick:6.6.9")
}
Примечание: JMagick требует установки ImageMagick версии 6.x (не 7). Для простоты в примерах мы будем использовать im4java — более современную обёртку, не требующую JNI.
Изменение размера изображения (Resize)
Операция resize изменяет размеры изображения с сохранением пропорций (или без). В im4java это делается через класс ConvertCmd.
Пример: уменьшить изображение до ширины 300 пикселей, сохранив пропорции:
import org.im4java.core.ConvertCmd
import org.im4java.core.IMOperation
fun resizeImage(inputPath: String, outputPath: String, targetWidth: Int) {
val cmd = ConvertCmd()
val op = IMOperation()
op.addImage(inputPath)
op.resize(targetWidth, null) // null = авто-высота по пропорции
op.addImage(outputPath)
cmd.run(op)
}
fun main() {
resizeImage("input.jpg", "output_resized.jpg", 300)
println("Изображение уменьшено до ширины 300px")
}
Параметры resize:
resize(width, height)— если один параметр null, пропорции сохраняютсяresize(width, height, "^")— минимальное заполнение областиresize(width, height, "!")— принудительное изменение без сохранения пропорций
Кадрирование изображения (Crop)
Crop вырезает прямоугольную область из изображения. Указываются координаты верхнего левого угла и размеры области.
Пример: вырезать центральный квадрат размером 200x200 пикселей:
import org.im4java.core.ConvertCmd
import org.im4java.core.IMOperation
fun cropImage(inputPath: String, outputPath: String,
x: Int, y: Int, width: Int, height: Int) {
val cmd = ConvertCmd()
val op = IMOperation()
op.addImage(inputPath)
op.crop(width, height, x, y)
op.addImage(outputPath)
cmd.run(op)
}
fun main() {
// Вырезаем область: левый верхний угол (100,50), размер 400x300
cropImage("input.jpg", "output_cropped.jpg", 100, 50, 400, 300)
println("Изображение обрезано")
}
Для автоматического центрирования можно вычислить координаты:
fun cropCenter(inputPath: String, outputPath: String, cropSize: Int) {
// Получаем размеры оригинального изображения (упрощённо)
val identify = IdentifyCmd()
val opId = IMOperation()
opId.addImage(inputPath)
val output = identify.run(opId) // возвращает строку с размерами
// Парсим ширину и высоту (упрощённо)
val dimensions = output.split(" ")[2].split("x")
val origW = dimensions[0].toInt()
val origH = dimensions[1].toInt()
val x = (origW - cropSize) / 2
val y = (origH - cropSize) / 2
cropImage(inputPath, outputPath, x, y