Прежде всего, благодарим всех за признание и поддержку ImageCombiner. Открытую версию мы выпустили более четырёх лет назад, и с тех пор она претерпела несколько десятков итераций.
ImageCombiner всегда придерживался концепции «простота в использовании», стремясь снизить порог входа. Поэтому в течение этого времени некоторые друзья предлагали более сложные функции, но они не были включены.
Эти требования всё ещё существуют. После тщательного рассмотрения мы планируем выпустить коммерческую версию в первой половине 2024 года. Основное внимание будет уделено расширению функций и повышению производительности, чтобы удовлетворить потребности более сложных бизнес-сценариев.
Кроме того, коммерческая версия также предоставит подробные документы по разработке и демонстрационные примеры, а также пятичасовую техническую поддержку. Если вам это нужно, вы можете рассмотреть возможность обновления!
В последнее время компания столкнулась с большим количеством запросов на распространение, неизбежно связанных с созданием различных маркетинговых изображений. Комбинирование изображений само по себе не является сложной технологией, но использование низкоуровневых API может быть довольно утомительным. Поэтому я решил потратить некоторое время на создание небольшого инструмента, надеясь освободить производственные мощности. В итоге я открыл свой первый проект с открытым исходным кодом после десяти лет работы (преодолевая нулевой рекорд, ха-ха). Я надеюсь, что он сможет помочь нуждающимся друзьям!
ImageCombiner — это инструмент, специально разработанный для серверной обработки изображений на Java. Он не имеет сложных функций, прост в использовании и предоставляет простые интерфейсы, основанные на реальных бизнес-сценариях. С помощью нескольких строк кода можно легко комбинировать изображения (конечно, его также можно использовать для создания водяных знаков). Поддерживаются три типа материалов: изображения, текст и прямоугольники. Поддерживается позиционирование, масштабирование, поворот, закругление углов, прозрачность, цвет, шрифт, размер шрифта, удаление линий, центрирование рисования, автоматический перенос текста и другие функции. Этого достаточно для удовлетворения повседневных потребностей в комбинировании изображений.
Специально создан репозиторий для сбора и демонстрации работ. Вы можете поделиться своими достижениями и идеями.
Использовать ImageCombiner очень просто. Основной класс — это ImageCombiner, который создаёт новый объект, указывает фоновое изображение и выходной формат, затем добавляет различные элементы материала, устанавливает положение, размер и эффекты элементов (например, закруглённые углы, цвета, прозрачность и т. д.), а затем вызывает метод combine() для объединения. Метод combine() возвращает объект BufferedImage напрямую или вызывает getCombinedImageStream() для получения потока, удобного для загрузки на OSS и другие операции, или сохраняет его локально с помощью метода save(). Это удобно при отладке.
Проект не зависит ни от каких фреймворков и полностью написан на основе JDK. В нём нет сложных вещей, и производительность неплохая. ``` //副标题(v2.6.3版本开始支持加载项目内字体文件,可以不用在服务器安装,性能略低) combiner.addTextElement("年度狂欢", "/font/yahei.ttf", 0, 150, 1450);
//内容(设置文本自动换行,需要指定最大宽度(超出则换行)、最大行数(超出则丢弃)、行高) combiner.addTextElement(content, "微软雅黑", Font.BOLD, 40, 150, 1480) .setSpace(.5f) //字间距 .setStrikeThrough(true) //删除线 .setAutoBreakLine(837, 2, 60); //自动换行(还有一个LineAlign参数可以指定对齐方式);
//商品图(设置坐标、宽高和缩放模式,若按宽度缩放,则高度按比例自动计算) combiner.addImageElement(productImageUrl, 0, 160, 837, 0, ZoomMode.Width) .setCenter(true) //居中绘制(会忽略x坐标,改为自动计算) .setRoundCorner(46) //设置圆角;
//头像(圆角设置一定的大小,可以把头像变成圆的) combiner.addImageElement(avatar, 200, 1200) .setRoundCorner(200); //圆角;
//水印(设置透明度,0.01.0)
combiner.addImageElement(waterMark, 630, 1200)
.setAlpha(.8f) //透明度(0.01.0)
.setRotate(45) //旋转(0360)
.setBlur(20) //高斯模糊(1100)
.setRepeat(true, 100, 50); //平铺绘制(可设置水平、垂直间距);
//加入圆角矩形元素(版本>=1.2.0),作为二维码的底衬 combiner.addRectangleElement(138, 1707, 300, 300) .setColor(Color.WHITE) .setRoundCorner(50) //该值大于等于宽高时,就是圆形,如设为300 .setAlpha(.8f) .setGradient(Color.yellow,Color.blue,GradientDirection.LeftRight); //颜色渐变 .setBorderSize(5); //设置border大小就是空心,不设置就是实心;
//二维码(强制按指定宽度、高度缩放) combiner.addImageElement(qrCodeUrl, 138, 1707, 186, 186, ZoomMode.WidthHeight);
//价格(元素对象也可以直接new,然后手动加入待绘制列表) TextElement textPrice = new TextElement("¥1290", 60, 230, 1300); textPrice.setColor(Color.red); //红色 textPrice.setStrikeThrough(true); //删除线 combiner.addElement(textPrice); //加入待绘制集合;
//执行图片合并 combiner.combine();
//可以获取流(并上传oss等) InputStream is = combiner.getCombinedImageStream();
//也可以保存到本地
//combiner.save("d://image.jpg");
``` Динамический расчёт высоты осуществляется по тому же принципу. Например, если нужно отобразить цену под описанием товара, но неизвестно, сколько строк будет в описании, то координата Y элемента цены будет неопределённой. Можно получить высоту предыдущего элемента с помощью метода textElement.getHeight()
, а затем суммировать её с координатами Y последующих элементов.
В graphics2D нет прямого способа вертикального выравнивания текста. В этом проекте также не было сделано соответствующей упаковки, но можно использовать функцию автоматического переноса строк для достижения этой цели. Для этого необходимо установить для textElement значение «автоматический перенос» и ширину строки равной 0 (для версии v2.3.8 и ниже ширина должна быть больше одного символа и меньше двух символов), а межстрочный интервал можно регулировать с помощью параметра высоты строки.
public void verticalTextTest() throws Exception {
ImageCombiner combiner = new ImageCombiner("https://img.thebeastshop.com/combine_image/funny_topic/resource/bg_3x4.png", OutputFormat.JPG);
// Добавляем текст и устанавливаем автоматический перенос строк, а ширину строки устанавливаем равной 0
combiner.addTextElement("Через функцию автоматического переноса строк можно реализовать вертикальное выравнивание текста", 50, 200, 100)
.setAutoBreakLine(0, 50, 60);
combiner.addTextElement("Чтобы текст был выровнен по вертикали, установите для него автоматический перенос строк и ширину строки равную 0", 50, 300, 100)
.setAutoBreakLine(0, 50, 60, LineAlign.Center);
// Создаём изображение
combiner.combine();
combiner.save("d://verticalTextTest.jpg");
}
Фактический результат:
Недавно один из друзей сообщил, что при строгом следовании координатам, предоставленным дизайнером, полученный результат не полностью соответствует дизайну. Это известная проблема, связанная с некоторыми базовыми концепциями рендеринга текста, такими как базовая линия. Например, Sketch и другие программы для дизайна используют ascent для отображения полей, в то время как graphics2D использует base для рисования, поэтому могут возникать различия в положении на оси Y. Кроме базовой линии, высота строки также влияет на окончательное положение текста.
ImageCombiner оптимизировал эту проблему в версии 2.0.0, чтобы обеспечить соответствие рендеринга базовой линии с программами для дизайна, такими как Sketch, и учёл фактор высоты строки, так что разработчикам нужно только следовать параметрам, указанным в дизайне, чтобы получить желаемый результат.
Начиная с версии 2.5.1, поддерживается установка опорной базовой линии (верхней или нижней), которая используется в некоторых сценариях, где требуется выравнивание по нижнему краю, например, как в примере из раздела 2.4.1.
Внимание: Если вы используете старую версию (<2.0.0) в своём проекте, из-за различий в расчётах координат после обновления может возникнуть смещение в расположении текста. Необходимо вручную настроить параметры, чтобы адаптироваться к новому способу расчёта координат. Будьте осторожны при обновлении!
На изображении ниже показан результат рендеринга ImageComber в сравнении с дизайном, созданным в Sketch. Код для этого примера: combiner.addTextElement("Нажмите на холст выше", 60, 0, 0).setLineHeight(100)
.
С версии 2.6.0 появилась поддержка установки базовой линии для текстовых элементов, по умолчанию она равна Top, что означает, что верхняя часть текста используется как опорная базовая линия.
На изображениях ниже показаны результаты рендеринга с использованием различных базовых линий (Top, Middle, Bottom, Base), где Top и Bottom учитывают высоту строки (если она установлена).
Тип элемента | Характеристика | Соответствующий метод |
---|---|---|
ImageElement | Изображение | setImage() и setImgUrl() |
ImageElement | Позиция | setX() и setY() |
ImageElement | Масштабирование | setWidth(), setHeight() и ZoomMode |
ImageElement | Вращение | setRotate() |
ImageElement | Закруглённые углы | setRoundCorner() |
ImageElement | Центрирование | setCenter() |
ImageElement | Прозрачность | setAlpha() |
ImageElement | Гауссово размытие | setBlur() |
ImageElement | Направление рисования | setDirection() |
ImageElement | Повторяющееся рисование | setRepeat() |
TextElement | Текст | setText() |
TextElement | Позиция | setX() и setY() |
TextElement | Центрирование | setCenter() |
TextElement | Вращение | setRotate() |
TextElement | Прозрачность | setAlpha() |
TextElement | Цвет | setColor() |
TextElement | Шрифт | setFont() |
TextElement | Размер шрифта | setFont() |
TextElement | Высота строки | setLineHeight() |
TextElement | Зачёркивание | setStrikeThrough() |
TextElement | Автоматический перенос строк | setAutoBreakLine() |
TextElement | Направление рисования | setDirection() |
TextElement | Межстрочный интервал | setSpace() |
TextElement | Повторяющееся рисование | setRepeat() |
TextElement | Адаптация ширины | setAutoFitWidth() |
TextElement | Опорная базовая линия | setBaseLine() |
RectangleElement | Позиция | setX() и setY() |
RectangleElement | Центрирование | setCenter() |
RectangleElement | Закруглённые углы | setRoundCorner() |
RectangleElement | Прозрачность | setAlpha() |
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарии ( 0 )