Skip to content

xuefm/img-combiner

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

69 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

一、介绍

本项目为个人学习使用参考dromara / image-combiner

生产环境建议使用dromara / image-combiner

版本要求:JDK17

二、安装

<dependency>
    <groupId>io.github.xuefm</groupId>
    <artifactId>img-combiner</artifactId>
    <version>1.1.1</version>
</dependency>

三、示例

以下是测试方法

package io.github.xuefm;

import io.github.xuefm.combiner.DefaultImageCombiner;
import io.github.xuefm.combiner.ImageCombiner;
import io.github.xuefm.element.*;
import io.github.xuefm.enums.AlignType;
import io.github.xuefm.enums.LineWrapType;
import io.github.xuefm.enums.OutputFormat;
import org.junit.BeforeClass;
import org.junit.Test;

import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.time.LocalTime;

public class ImgTest {

    private static String filePath = "file:///" + System.getProperty("user.dir") + "/test_file/";
    private static String generateFilePath = System.getProperty("user.dir") + "/test_file/generate/";
    private static OutputFormat outputFormat = OutputFormat.PNG;


    @BeforeClass
    public static void init() {
        File file = new File(generateFilePath);
        if (!file.exists()) {
            file.mkdirs();
        } else {
            File[] files = file.listFiles();
            assert files != null;
            for (File file1 : files) {
                file1.delete();
            }
        }
    }

    @Test
    public void canvasRoundCorner() throws IOException {
        ImageCombiner imageCombiner = DefaultImageCombiner.of(400, 700, outputFormat, 100, 0f);

        imageCombiner.generate();
        imageCombiner.save(generateFilePath + "画布圆角01." + outputFormat.getName());

    }

    /**
     * 图片测试(主要测试横向对齐)
     *
     * @throws IOException
     */
    @Test
    public void t01ImgTest() throws IOException {
        ImageCombiner imageCombiner = DefaultImageCombiner.of(400, 600, outputFormat, 0, 0f);
        imageCombiner.addElement(
                ImageElement.of(filePath + "cat.jpg", null, null, AlignType.TransverseAlign.LEFT, null, 100, 100)
                        .setRoundCorner(50)
                        .setRotate(45)
                        .setAlpha(0.25f),
                ImageElement.of(filePath + "cat.jpg", null, null, AlignType.TransverseAlign.CENTER, null, 100, 100)
                        .setRoundCorner(50)
                        .setRotate(90)
                        .setAlpha(0.5f),
                ImageElement.of(filePath + "cat.jpg", null, null, AlignType.TransverseAlign.RIGHT, null, 100, 100)
                        .setRoundCorner(50)
                        .setRotate(180)
                        .setAlpha(0.75f)
        );
        imageCombiner.generate();
        imageCombiner.save(generateFilePath + "图片01." + outputFormat.getName());
    }

    /**
     * 图片测试(主要测试纵向对齐)
     *
     * @throws IOException
     */
    @Test
    public void t02ImgTest() throws IOException {
        ImageCombiner imageCombiner = DefaultImageCombiner.of(400, 600, outputFormat, 0, 0f);
        imageCombiner.addElement(
                ImageElement.of(filePath + "cat.jpg", null, null, null, AlignType.VerticalAlign.TOP, 100, 100)
                        .setRoundCorner(50)
                        .setRotate(45)
                        .setAlpha(0.25f),
                ImageElement.of(filePath + "cat.jpg", null, null, null, AlignType.VerticalAlign.CENTER, 100, 100)
                        .setRoundCorner(50)
                        .setRotate(90)
                        .setAlpha(0.5f),
                ImageElement.of(filePath + "cat.jpg", null, null, null, AlignType.VerticalAlign.BOTTOM, 100, 100)
                        .setRoundCorner(50)
                        .setRotate(180)
                        .setAlpha(0.75f)
        );
        imageCombiner.generate();
        imageCombiner.save(generateFilePath + "图片02." + outputFormat.getName());
    }

    /**
     * 矩形测试(主要横向试纵向对齐)
     *
     * @throws IOException
     */
    @Test
    public void t01RectangleTest() throws IOException {
        ImageCombiner imageCombiner = DefaultImageCombiner.of(400, 600, outputFormat, 0, 0f);
        imageCombiner.addElement(
                RectangleElement.of(null, null, AlignType.TransverseAlign.LEFT, null, 0, 100)
                        .setRoundCorner(50)
                        .setRotate(30)
                        .setAlpha(0.25f)
                        .setColor(Color.RED)
                ,
                RectangleElement.of(null, null, AlignType.TransverseAlign.CENTER, null, 100, 100)
                        .setRoundCorner(50)
                        .setRotate(60)
                        .setAlpha(0.5f)
                        .setColor(Color.GREEN),
                RectangleElement.of(null, null, AlignType.TransverseAlign.RIGHT, null, 0, 100)
                        .setRoundCorner(50)
                        .setRotate(90)
                        .setAlpha(0.75f)
                        .setColor(Color.BLUE)
        );
        imageCombiner.generate();
        imageCombiner.save(generateFilePath + "矩形01." + outputFormat.getName());
    }

    /**
     * 矩形测试(主要横向试纵向对齐)
     *
     * @throws IOException
     */
    @Test
    public void t02RectangleTest() throws IOException {
        ImageCombiner imageCombiner = DefaultImageCombiner.of(400, 600, outputFormat, 0, 0f);
        imageCombiner.addElement(
                RectangleElement.of(0, null, null, AlignType.VerticalAlign.TOP, 100, 100)
                        .setRoundCorner(50)
                        .setRotate(30)
                        .setAlpha(0.25f)
                        .setColor(Color.RED),
                RectangleElement.of(0, null, null, AlignType.VerticalAlign.CENTER, 100, 100)
                        .setRoundCorner(50)
                        .setRotate(60)
                        .setAlpha(0.5f)
                        .setColor(Color.GREEN),
                RectangleElement.of(0, null, null, AlignType.VerticalAlign.BOTTOM, 100, 100)
                        .setRoundCorner(50)
                        .setRotate(90)
                        .setAlpha(0.75f)
                        .setColor(Color.BLUE)
        );
        imageCombiner.generate();
        imageCombiner.save(generateFilePath + "矩形02." + outputFormat.getName());
    }

    @Test
    public void t01TextTest() throws IOException {
        ImageCombiner imageCombiner = DefaultImageCombiner.of(400, 600, outputFormat, 0, 0f);
        imageCombiner.addElement(
                TextElement.of("汉字文本:你好世界", 0, 0, null, null).setFont(new Font("微软雅黑", Font.PLAIN, 36))
                        .setColor(Color.CYAN)
                        .setLineFeed(LineWrapType.BY_TEXT_COUNT, 3),
                TextElement.of("English text:Hello world", 0, 200, null, null).setFont(new Font("微软雅黑", Font.PLAIN, 36))
                        .setColor(Color.GREEN)
                        .setLineFeed(LineWrapType.BY_PIXEL, 100)
        );
        imageCombiner.generate();
        imageCombiner.save(generateFilePath + "文本01." + outputFormat.getName());
    }

    @Test
    public void t02TextTest() throws IOException {
        ImageCombiner imageCombiner = DefaultImageCombiner.of(400, 600, outputFormat, 0, 0f);
        imageCombiner.addElement(
                TextElement.of("汉字文本:你好世界", null, 0, AlignType.TransverseAlign.CENTER, null).setFont(new Font("微软雅黑", Font.PLAIN, 36))
                        .setColor(Color.CYAN)
                        .setLineFeed(LineWrapType.BY_TEXT_COUNT, 3),
                TextElement.of("English text:Hello world", null, 200, AlignType.TransverseAlign.CENTER, null).setFont(new Font("微软雅黑", Font.PLAIN, 36))
                        .setColor(Color.GREEN)
                        .setLineFeed(LineWrapType.BY_PIXEL, 100)
        );
        imageCombiner.generate();
        imageCombiner.save(generateFilePath + "文本02." + outputFormat.getName());
    }

    @Test
    public void t03TextTest() throws IOException {
        ImageCombiner imageCombiner = DefaultImageCombiner.of(400, 600, outputFormat, 0, 0f);
        imageCombiner.addElement(
                TextElement.of("汉字文本:你好世界", 0, null, null, AlignType.VerticalAlign.TOP).setFont(new Font("微软雅黑", Font.PLAIN, 36))
                        .setColor(Color.CYAN)
                        .setLineFeed(LineWrapType.BY_TEXT_COUNT, 3),
                TextElement.of("English text:Hello world", 0, null, null, AlignType.VerticalAlign.BOTTOM).setFont(new Font("微软雅黑", Font.PLAIN, 36))
                        .setColor(Color.GREEN)
                        .setLineFeed(LineWrapType.BY_PIXEL, 100)
        );
        imageCombiner.generate();
        imageCombiner.save(generateFilePath + "文本03." + outputFormat.getName());
    }

    @Test
    public void t04TextTest() throws IOException {
        ImageCombiner imageCombiner = DefaultImageCombiner.of(400, 600, outputFormat, 0, 0f);
        imageCombiner.addElement(
                TextElement.of("汉字文本:你好世界English text:Hello world", 0, 0, null, null).setFont(new Font("微软雅黑", Font.PLAIN, 36))
                        .setColor(Color.CYAN)
                        .setGradient(new Color[]{Color.RED, Color.GREEN, Color.BLUE},
                                new float[]{0.0f, 0.1f, 0.5f}),
                TextElement.of("汉字文本:你好世界English text:Hello world", 0, 200, null, null).setFont(new Font("微软雅黑", Font.PLAIN, 36))
                        .setColor(Color.CYAN)


        );
        imageCombiner.generate();
        imageCombiner.save(generateFilePath + "文本04." + outputFormat.getName());
    }

    @Test
    public void t05TextTest() throws IOException {
        ImageCombiner imageCombiner = DefaultImageCombiner.of(400, 600, outputFormat, 0, 0f);
        imageCombiner.addElement(
                TextElement.of("静夜思\n" +
                                "床前明月光,\n" +
                                "疑是地上霜。\n" +
                                "举头望明月,\n" +
                                "低头思故乡。", 0, null, null, AlignType.VerticalAlign.TOP).setFont(new Font("微软雅黑", Font.PLAIN, 36))
                        .setGradient(new Color[]{Color.RED, Color.GREEN, Color.BLUE},
                                new float[]{0.0f, 0.1f, 0.5f})
                        .setLineFeed(LineWrapType.BY_LINE_BREAKS, 0)

        );
        imageCombiner.generate();
        imageCombiner.save(generateFilePath + "文本05." + outputFormat.getName());
    }


    @Test
    public void t01lineTest() throws IOException {
        ImageCombiner imageCombiner = DefaultImageCombiner.of(400, 700, outputFormat, 0, 0f);

        imageCombiner.addElement(
                LineElement.of(200, 300, 200, 400)
                        .setColor(Color.RED)
        );
        imageCombiner.addElement(
                LineElement.of(200, 300, 200, 400)
                        .setColor(Color.RED)
                        .setRotate(90)
        );

        imageCombiner.generate();
        imageCombiner.save(generateFilePath + "线01." + outputFormat.getName());
    }

    @Test
    public void t02lineTest() throws IOException {
        ImageCombiner imageCombiner = DefaultImageCombiner.of(400, 700, outputFormat, 0, 0f);
        imageCombiner.addElement(
                LineElement.of(100, 100, 100, 100, 200, 200, null, null),
                LineElement.of(200, 200, 200, 300)

        );

        imageCombiner.generate();
        imageCombiner.save(generateFilePath + "线02." + outputFormat.getName());
    }


    @Test
    public void oval1() throws IOException {
        ImageCombiner imageCombiner = DefaultImageCombiner.of(400, 300, outputFormat, 0, 0f);
        imageCombiner.addElement(OvalElement.of(0, 0, AlignType.TransverseAlign.CENTER, AlignType.VerticalAlign.CENTER, 200, 100)
                .setColor(Color.RED));

        imageCombiner.generate();
        imageCombiner.save(generateFilePath + "椭圆01." + outputFormat.getName());

    }

    @Test
    public void t01MixingTest() throws IOException {
        ImageCombiner imageCombiner = DefaultImageCombiner.of(400, 600, outputFormat, 0, 0f);
        imageCombiner.addElement(

                ImageElement.of(filePath + "cat.jpg", null, null, AlignType.TransverseAlign.CENTER, AlignType.VerticalAlign.TOP, 100, 100)
                        .setRoundCorner(50)
                        .setRotate(45),
                RectangleElement.of(null, null, AlignType.TransverseAlign.CENTER, AlignType.VerticalAlign.CENTER, 100, 100)
                        .setRoundCorner(50)
                        .setColor(Color.RED),
                TextElement.of("汉字文本:你好世界", null, null, AlignType.TransverseAlign.CENTER, AlignType.VerticalAlign.BOTTOM).setFont(new Font("微软雅黑", Font.PLAIN, 32))
                        .setAlpha(1f)
                        .setColor(Color.CYAN)
                        .setLineFeed(LineWrapType.BY_TEXT_COUNT, 3)
                        .setStrikethrough(true)
                ,
                TextElement.of("汉字文本:你好世界", 0, 0, null, null).setFont(new Font("宋体", Font.PLAIN, 32))
                        .setAlpha(1f)
                        .setColor(Color.CYAN)
                        .setLineFeed(LineWrapType.BY_TEXT_COUNT, 3)
                        .setUnderline(true)
        );
        imageCombiner.generate();
        imageCombiner.save(generateFilePath + "混合01." + outputFormat.getName());
    }

    @Test
    public void clockTest() throws IOException {
        ImageCombiner imageCombiner = DefaultImageCombiner.of(400, 700, outputFormat, 0, 0f);
        imageCombiner.addElement(
                TextElement.of("你好啊", null, 100, AlignType.TransverseAlign.CENTER, null)
                        .setColor(new Color(0, 255, 255))
                        .setFont(new Font("宋体", Font.PLAIN, 72))
                        .setAlpha(0.35f)
        );
        //表盘
        imageCombiner.addElement(
                RectangleElement.of(null, null, AlignType.TransverseAlign.CENTER, AlignType.VerticalAlign.CENTER, 200, 200)
                        .setColor(new Color(30, 31, 34))
                        .setRoundCorner(200)
        );
        //时间刻度
        for (int i = 0; i < 12; i++) {
            imageCombiner.addElement(
                    LineElement.of(200, 251, 200, (i % 3 == 0 ? 270 : 260))
                            .setColor(Color.WHITE)
                            .setRotate(30 * i, 200, 350)
            );
        }
        //时针、分针、秒针
        LocalTime localTime = LocalTime.now();
        int hour = localTime.getHour();
        int minute = localTime.getMinute();
        int second = localTime.getSecond();
        double hourAngle = (hour % 12 + minute / 60.0 + second / 3600.0) * 30;
        double minuteAngle = (minute + second / 60.0) * 6;
        double secondAngle = second * 6;
        imageCombiner.addElement(
                LineElement.of(200, 330, 200, 350)
                        .setColor(Color.WHITE)
                        .setRotate((int) hourAngle, 200, 350)
        );
        imageCombiner.addElement(
                LineElement.of(200, 310, 200, 350)
                        .setColor(Color.WHITE)
                        .setRotate((int) minuteAngle, 200, 350)
        );
        imageCombiner.addElement(
                LineElement.of(200, 300, 200, 350)
                        .setColor(Color.RED)
                        .setRotate((int) secondAngle, 200, 350)
        );
        imageCombiner.addElement(
                TextElement.of("你好啊", null, 600, AlignType.TransverseAlign.CENTER, null)
                        .setColor(new Color(255, 0, 255))
                        .setFont(new Font("宋体", Font.PLAIN, 72))
                        .setAlpha(0.35f)
        );

        imageCombiner.addElement(
                LineElement.of(200, 500, 200, 600)
                        .setColor(Color.RED)
        );
        imageCombiner.addElement(
                LineElement.of(200, 500, 200, 600)
                        .setColor(Color.RED)
                        .setRotate(90)
        );

        imageCombiner.generate();
        imageCombiner.save(generateFilePath + "时钟02." + outputFormat.getName());

    }


}

四、详细

1.元素介绍

元素类 元素介绍
ImageElement 图片元素
TextElement 文本元素
RectangleElement 矩形元素
LineElement 线形元素

五、扩展方法

如果提供的元素不能满足或有更好的实现可按一下方式进行扩展

1.创建XxxElement并继承Element

2.创建XxxPainter并继承IPainter(或实现AbstractPainter)

3.在配置中添加对应配置ImageCombinerConfig.setPainter(XxxElement.class,new XxxPainter());