All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.moon.core.awt.ImageJoiner Maven / Gradle / Ivy

package com.moon.core.awt;

import com.moon.core.lang.IntUtil;
import com.moon.core.lang.ref.IntAccessor;

import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;

import static com.moon.core.enums.Const.ZERO;

/**
 * @author moonsky
 */
public enum ImageJoiner implements ImageDescriptor {

    JPG,
    JPEG,
    GIF,
    PNG,
    BMP;

    /*
     * ----------------------------------------------------------------------------
     * join
     * ----------------------------------------------------------------------------
     */

    public final boolean verticalJoin(String outputPath, String... sourcePaths) {
        return join(Direction.VERTICAL, outputPath, sourcePaths);
    }

    public final boolean horizontalJoin(String outputPath, String... sourcePaths) {
        return join(Direction.HORIZONTAL, outputPath, sourcePaths);
    }

    public final boolean join(Direction direction, String outputPath, String... sourceImages) {
        return join(direction, extensionName(), outputPath, sourceImages);
    }

    public final boolean join(Direction direction, String outputType, String outputPath, String... sourceImages) {
        BufferedImage resultImage = join(direction, sourceImages);
        return OpUtil.write(resultImage, outputType, outputPath);
    }

    /*
     * ----------------------------------------------------------------------------
     * zoom join
     * ----------------------------------------------------------------------------
     */

    public boolean joinWithSameHeight(String outputPath, String... sourceImages) {
        return joinWithSameHeight(extensionName(), outputPath, sourceImages);
    }

    public boolean joinWithSameHeight(String outputType, String outputPath, String... sourceImages) {
        BufferedImage resultImage = joinWithSameHeight(sourceImages);
        return OpUtil.write(resultImage, outputType, outputPath);
    }

    public boolean joinWithSameWidth(String outputPath, String... sourceImages) {
        return joinWithSameWidth(extensionName(), outputPath, sourceImages);
    }

    public boolean joinWithSameWidth(String outputType, String outputPath, String... sourceImages) {
        BufferedImage resultImage = joinWithSameWidth(sourceImages);
        return OpUtil.write(resultImage, outputType, outputPath);
    }

    /*
     * ----------------------------------------------------------------------------
     * inner
     * ----------------------------------------------------------------------------
     */

    private static BufferedImage joinWithSameSize(Operator operator, String... sourceImages) {
        final int length = sourceImages.length;
        return length < 1 ? OpUtil.empty() : operator
            .accept(sourceImages, IntAccessor.of(Integer.MAX_VALUE), new int[length], new int[length],
                new ArrayList(length));
    }

    private interface Operator {

        /**
         * inner
         *
         * @param sources  源
         * @param accessor 索引
         * @param heights  高
         * @param widths   宽
         * @param images   图片文件列表
         *
         * @return 操作后的图片
         */
        BufferedImage accept(
            String[] sources,
            IntAccessor accessor,
            int[] heights,
            int[] widths,
            List images
        );
    }

    private static BufferedImage joinWithSameWidth(String... sourceImages) {
        return joinWithSameSize((sources, accessor, heights, widths, images) -> {
            final int length = sources.length;
            for (int i = 0; i < length; i++) {
                BufferedImage image = OpUtil.read(sources[i]);

                int width = image.getWidth();
                accessor.set(IntUtil.min(width, accessor.get()));

                widths[i] = width;
                heights[i] = image.getHeight();
                images.add(image);
            }

            int width = accessor.get();
            int wholeHeight = Direction.V.computeWhole(length, width, widths, heights);

            BufferedImage resultImage = OpUtil.createBuffered(width, wholeHeight);
            for (int i = 0, index = 0; i < images.size(); i++) {
                BufferedImage image = images.get(i);
                int height = heights[i];

                BufferedImage newImage = OpUtil.createBuffered(width, height);
                int[] imageRgbPoints = new int[width * height];

                newImage.getGraphics().drawImage(image, ZERO, ZERO, width, height, null);
                imageRgbPoints = newImage.getRGB(ZERO, ZERO, width, height, imageRgbPoints, ZERO, width);

                resultImage.setRGB(ZERO, index, width, height, imageRgbPoints, ZERO, width);
                index += height;
            }
            return resultImage;
        }, sourceImages);
    }

    private static BufferedImage joinWithSameHeight(String... sourceImages) {
        return joinWithSameSize((sources, accessor, heights, widths, images) -> {
            final int length = sources.length;
            for (int i = 0; i < length; i++) {
                BufferedImage image = OpUtil.read(sources[i]);

                int height = image.getHeight();
                accessor.set(IntUtil.min(height, accessor.get()));

                heights[i] = height;
                widths[i] = image.getWidth();
                images.add(image);
            }

            int height = accessor.get();
            int wholeWidth = Direction.H.computeWhole(length, height, widths, heights);

            BufferedImage resultImage = OpUtil.createBuffered(wholeWidth, height);
            for (int i = 0, index = 0; i < images.size(); i++) {
                BufferedImage image = images.get(i);
                int width = widths[i];

                BufferedImage newImage = OpUtil.createBuffered(width, height);

                newImage.getGraphics().drawImage(image, ZERO, ZERO, width, height, null);
                int[] points = newImage.getRGB(ZERO, ZERO, width, height, new int[width * height], ZERO, width);

                resultImage.setRGB(index, ZERO, width, height, points, ZERO, width);
                index += width;
            }
            return resultImage;
        }, sourceImages);
    }

    private static BufferedImage join(Direction direction, String... sourceImages) {
        int len = sourceImages.length;
        if (len < 1) {
            return OpUtil.empty();
        }

        BufferedImage[] images = new BufferedImage[len];
        int[][] rgbArrays = new int[len][];
        for (int i = 0; i < len; i++) {
            BufferedImage current = OpUtil.read(sourceImages[i]);

            int width = current.getWidth();
            int height = current.getHeight();
            // 从图片中读取RGB: 这句可以不用
            int[] rgbArray = new int[width * height];
            images[i] = current;
            rgbArrays[i] = current.getRGB(ZERO, ZERO, width, height, rgbArray, ZERO, width);
        }
        return Join.newSize(images, rgbArrays, direction);
    }

    private static final class Join {

        static BufferedImage newSize(
            BufferedImage[] images, int[][] rgbArrays, Direction direction
        ) {
            int width = 0;
            int height = 0;
            for (int i = 0; i < images.length; i++) {
                height = direction.computeHeight(Maths.MAX, height, images[i].getHeight());
                width = direction.computeWidth(Maths.MAX, width, images[i].getWidth());
            }

            return height < 1 || width < 1 ? OpUtil.empty() : Join.out(images, rgbArrays, width, height, direction);
        }

        static BufferedImage out(
            BufferedImage[] images, int[][] rgbArrays, int outWidth, int outHeight, Direction direction
        ) {
            BufferedImage outImage = OpUtil.createBuffered(outWidth, outHeight);
            int index = 0;
            for (int i = 0; i < images.length; i++) {
                BufferedImage image = images[i];
                int width = image.getWidth();
                int height = image.getHeight();
                direction.setRGB(outImage, index, width, height, rgbArrays[i], ZERO, width);
                index = direction.nextIndex(index, width, height);
            }
            return outImage;
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy