Java实现图片的垂直方向拼接

利用Java实现了任意两张图片的垂直方向拼接,不限制大小类型,可直接用于生产。

实现任意两张图片的垂直方向拼接,对于过小图片实现了放大,保证了图片拼接后的清晰度。

对于高度大于宽度的图片,进行了-90度旋转。

java 复制代码
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;

//垂直方向合并图片
public class ImageMerge {

    /**
     * 1比较2张图片的大小,以2张图片的最大边长为宽,以第二边长为高,构造2张空图片
     * 2选择第一张图片,若宽小于于高,旋转-90度,粘贴到第一张空图片上
     * 3选择第二张图片,若宽小于于高,旋转-90度,粘贴到第二张空图片上
     *
     * @param img1 待合并的第一张图
     * @param img2 带合并的第二张图
     * @return 返回合并后的BufferedImage对象
     * @throws IOException
     */
    public static BufferedImage mergeImage(BufferedImage img1, BufferedImage img2) throws IOException {
        //判断是否需要放大图片
        if (Math.max(img1.getWidth(), img1.getHeight()) > Math.max(img2.getWidth(), img2.getHeight())) {
            img2 = judgeIfNeedChangeImageSize(img1, img2);
        } else {
            img1 = judgeIfNeedChangeImageSize(img1, img2);
        }
        //获取背景图片宽高
        int w1 = img1.getWidth();
        int h1 = img1.getHeight();
        int w2 = img2.getWidth();
        int h2 = img2.getHeight();
        List<Integer> list = Arrays.asList(w1, w2, h1, h2);
        list.sort((v1, v2) -> v2 - v1);
        int maxWidth = list.get(0);
        int maxHeight = list.get(1);
        int[] backgroundImage = new int[maxWidth * maxHeight];
        //设置背景图片数据
        for (int i = 0; i < backgroundImage.length; i++) {
            backgroundImage[i] = -1;
        }
        //绘制背景图片
        BufferedImage createImage = new BufferedImage(maxWidth, maxHeight << 1, BufferedImage.TYPE_INT_RGB);
        createImage.setRGB(0, 0, maxWidth, maxHeight, backgroundImage, 0, maxWidth);
        createImage.setRGB(0, maxHeight, maxWidth, maxHeight, backgroundImage, 0, maxWidth);
        //准备图片一绘制数据
        int[] imageArrayOne = new int[w1 * h1];
        imageArrayOne = img1.getRGB(0, 0, w1, h1, imageArrayOne, 0, w1);
        if (w1 < h1) {
            rotateImage(w1, h1, imageArrayOne);
            int temp = w1;
            w1 = h1;
            h1 = temp;
        }
        //计算绘图位置,尽量居中
        int startX;
        int startY;
        startX = (maxWidth - w1) >> 1;
        startY = (maxHeight - h1) >> 1;
        //在背景图片上绘制图片
        createImage.setRGB(startX, startY, w1, h1, imageArrayOne, 0, w1);
        //准备图片一绘制数据
        int[] imageArrayTwo = new int[w2 * h2];
        imageArrayTwo = img2.getRGB(0, 0, w2, h2, imageArrayTwo, 0, w2);
        if (w2 < h2) {
            rotateImage(w2, h2, imageArrayTwo);
            int temp = w2;
            w2 = h2;
            h2 = temp;
        }
        //计算绘图位置,尽量居中
        startX = (maxWidth - w2) >> 1;
        startY = (maxHeight - h2) >> 1;
        //准备图片二绘制数据
        createImage.setRGB(startX, maxHeight + startY, w2, h2, imageArrayTwo, 0, w2);
        return createImage;
    }


    private static BufferedImage judgeIfNeedChangeImageSize(BufferedImage img1, BufferedImage img2) {
        int w1 = img1.getWidth();
        int h1 = img1.getHeight();
        int w2 = img2.getWidth();
        int h2 = img2.getHeight();
        int max1 = Math.max(w1, h1);
        int max2 = Math.max(w2, h2);
        if (max1 < max2) {
            return enlargementImage(img1, w1, h1, max1, max2);
        } else {
            return enlargementImage(img2, w2, h2, max2, max1);
        }
    }

    private static BufferedImage enlargementImage(BufferedImage srcImg, int w1, int h1, int max1, int max2) {
        while (max2 / max1 >= 2) {
            max1 *= 2;
            w1 *= 2;
            h1 *= 2;
        }
        // 放大边长
        BufferedImage resultImg = new BufferedImage(w1, h1, BufferedImage.TYPE_INT_RGB);
        //绘制放大后的图片
        resultImg.getGraphics().drawImage(srcImg, 0, 0, w1, h1, null);
        return resultImg;
    }


    /**
     * 旋转图片-90度
     *
     * @param width  目标图像宽度
     * @param height 目标图像高度
     * @return
     */
    public static void rotateImage(int width, int height, int[] imageArray) {
        int[][] arr = new int[height][width];
        int x = 0;
        int y = 0;
        for (int i = 0; i < imageArray.length; i++) {
            arr[y][x++] = imageArray[i];
            if (x % width == 0) {
                x = 0;
                y++;
            }
        }
        //旋转-90度
        int index = 0;
        for (int j = width - 1; j >= 0; j--) {
            for (int i = 0; i < arr.length; i++) {
                imageArray[index++] = arr[i][j];
            }
        }
    }


    private static final String SOURCE_FILE_PATH = "C:\\Users\\Administrator\\Pictures\\fee.jpg";
    private static final String WATER_FILE_PATH = "C:\\Users\\Administrator\\Pictures\\invoiceH.png";
    private static final String SAVE_FILE_PATH = "C:\\Users\\Administrator\\Pictures\\overlyingImageNew.jpg";


    /**
     * @param fileUrl 文件绝对路径或相对路径
     * @return 读取到的缓存图像
     * @throws IOException 路径错误或者不存在该文件时抛出IO异常
     */
    public static BufferedImage getBufferedImage(String fileUrl)
            throws IOException {
        File f = new File(fileUrl);
        return ImageIO.read(f);
    }


    /**
     * 输出图片
     *
     * @param buffImg  图像拼接叠加之后的BufferedImage对象
     * @param savePath 图像拼接叠加之后的保存路径
     */
    public static void generateSaveFile(BufferedImage buffImg, String savePath) {
        int temp = savePath.lastIndexOf(".") + 1;
        try {
            File outFile = new File(savePath);
            if (!outFile.exists()) {
                outFile.createNewFile();
            }
            ImageIO.write(buffImg, savePath.substring(temp), outFile);
            System.out.println("ImageIO write...");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    /**
     * Java 测试图片合并方法
     */
    public static void imageMargeTest() {
        // 读取待合并的文件
        BufferedImage bi1 = null;
        BufferedImage bi2 = null;
        // 调用mergeImage方法获得合并后的图像
        BufferedImage destImg = null;
        System.out.println("下面是垂直合并的情况:");
        String saveFilePath = WATER_FILE_PATH;
        String divingPath = SOURCE_FILE_PATH;
        String margeImagePath = SAVE_FILE_PATH;
        try {
            bi1 = getBufferedImage(saveFilePath);
            bi2 = getBufferedImage(divingPath);
            // 调用mergeImage方法获得合并后的图像
            destImg = mergeImage(bi1, bi2);
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 保存图像
        generateSaveFile(destImg, margeImagePath);
        System.out.println("垂直合并完毕!");
    }

    public static void main(String[] args) {
        // 测试图片的垂直合并
        imageMargeTest();
    }

}
相关推荐
gywl7 分钟前
openEuler VM虚拟机操作(期末考试)
linux·服务器·网络·windows·http·centos
苹果醋31 小时前
React源码02 - 基础知识 React API 一览
java·运维·spring boot·mysql·nginx
某柚啊1 小时前
Windows开启IIS后依然出现http error 503.the service is unavailable
windows·http
Hello.Reader1 小时前
深入解析 Apache APISIX
java·apache
菠萝蚊鸭2 小时前
Dhatim FastExcel 读写 Excel 文件
java·excel·fastexcel
算法小白(真小白)2 小时前
低代码软件搭建自学第二天——构建拖拽功能
python·低代码·pyqt
唐小旭2 小时前
服务器建立-错误:pyenv环境建立后python版本不对
运维·服务器·python
码农君莫笑2 小时前
信管通低代码信息管理系统应用平台
linux·数据库·windows·低代码·c#·.net·visual studio
旭东怪2 小时前
EasyPoi 使用$fe:模板语法生成Word动态行
java·前端·word
007php0072 小时前
Go语言zero项目部署后启动失败问题分析与解决
java·服务器·网络·python·golang·php·ai编程