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();
    }

}
相关推荐
码蜂窝编程官方1 分钟前
【含开题报告+文档+PPT+源码】基于SpringBoot+Vue的虎鲸旅游攻略网的设计与实现
java·vue.js·spring boot·后端·spring·旅游
Viktor_Ye17 分钟前
高效集成易快报与金蝶应付单的方案
java·前端·数据库
hummhumm19 分钟前
第 25 章 - Golang 项目结构
java·开发语言·前端·后端·python·elasticsearch·golang
杜小满23 分钟前
周志华深度森林deep forest(deep-forest)最新可安装教程,仅需在pycharm中完成,超简单安装教程
python·随机森林·pycharm·集成学习
一二小选手23 分钟前
【Maven】IDEA创建Maven项目 Maven配置
java·maven
J老熊29 分钟前
JavaFX:简介、使用场景、常见问题及对比其他框架分析
java·开发语言·后端·面试·系统架构·软件工程
猿java34 分钟前
什么是 Hystrix?它的工作原理是什么?
java·微服务·面试
AuroraI'ncoding35 分钟前
时间请求参数、响应
java·后端·spring
所待.3831 小时前
JavaEE之线程初阶(上)
java·java-ee
Winston Wood1 小时前
Java线程池详解
java·线程池·多线程·性能