java图片合并以及拼接

    714
    package com.cjbdi.util;
    
    import java.awt.AlphaComposite;
    import java.awt.Graphics2D;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.IOException;
    import java.net.HttpURLConnection;
    import java.net.URL;
    
    import javax.imageio.ImageIO;
    
    /**
     * 该类实现了图片的合并功能,可以选择水平合并或者垂直合并。
     * 当然此例只是针对两个图片的合并,如果想要实现多个图片的合并,只需要自己实现方法 BufferedImage
     * mergeImage(BufferedImage[] imgs, boolean isHorizontal)即可;
     * 而且这个方法更加具有通用性,但是时间原因不实现了,方法和两张图片实现是一样的
     */
    
    public class ImageMerge {
    
        /**
         * @param fileUrl 文件绝对路径或相对路径
         * @return 读取到的缓存图像
         * @throws IOException 路径错误或者不存在该文件时抛出IO异常
         */
        public static BufferedImage getBufferedImage(String fileUrl)
                throws IOException {
            File f = new File(fileUrl);
            return ImageIO.read(f);
        }
    
    
        /**
         * 远程图片转BufferedImage
         *
         * @param destUrl 远程图片地址
         * @return
         */
        public static BufferedImage getBufferedImageDestUrl(String destUrl) {
            HttpURLConnection conn = null;
            BufferedImage image = null;
            try {
                URL url = new URL(destUrl);
                conn = (HttpURLConnection) url.openConnection();
                if (conn.getResponseCode() == 200) {
                    image = ImageIO.read(conn.getInputStream());
                    return image;
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                conn.disconnect();
            }
            return image;
        }
    
        /**
         * 输出图片
         *
         * @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();
            }
        }
    
        /**
         * @param buffImg   源文件(BufferedImage)
         * @param waterFile 水印文件(BufferedImage)
         * @param x         距离右下角的X偏移量
         * @param y         距离右下角的Y偏移量
         * @param alpha     透明度, 选择值从0.0~1.0: 完全透明~完全不透明
         * @return BufferedImage
         * @throws IOException
         * @Title: 构造图片
         * @Description: 生成水印并返回java.awt.image.BufferedImage
         */
        public static BufferedImage overlyingImage(BufferedImage buffImg, BufferedImage waterImg, int x, int y, float alpha) throws IOException {
    
            // 创建Graphics2D对象,用在底图对象上绘图
            Graphics2D g2d = buffImg.createGraphics();
            int waterImgWidth = waterImg.getWidth();// 获取层图的宽度
            int waterImgHeight = waterImg.getHeight();// 获取层图的高度
            // 在图形和图像中实现混合和透明效果
            g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
            // 绘制
            g2d.drawImage(waterImg, x, y, waterImgWidth, waterImgHeight, null);
            g2d.dispose();// 释放图形上下文使用的系统资源
            return buffImg;
        }
    
    
        /**
         * 待合并的两张图必须满足这样的前提,如果水平方向合并,则高度必须相等;如果是垂直方向合并,宽度必须相等。
         * mergeImage方法不做判断,自己判断。
         *
         * @param img1         待合并的第一张图
         * @param img2         带合并的第二张图
         * @param isHorizontal 为true时表示水平方向合并,为false时表示垂直方向合并
         * @return 返回合并后的BufferedImage对象
         * @throws IOException
         */
        public static BufferedImage mergeImage(BufferedImage img1,
                                               BufferedImage img2, boolean isHorizontal) throws IOException {
            int w1 = img1.getWidth();
            int h1 = img1.getHeight();
            int w2 = img2.getWidth();
            int h2 = img2.getHeight();
    
            // 从图片中读取RGB
            int[] ImageArrayOne = new int[w1 * h1];
            ImageArrayOne = img1.getRGB(0, 0, w1, h1, ImageArrayOne, 0, w1); // 逐行扫描图像中各个像素的RGB到数组中
            int[] ImageArrayTwo = new int[w2 * h2];
            ImageArrayTwo = img2.getRGB(0, 0, w2, h2, ImageArrayTwo, 0, w2);
    
            // 生成新图片
            BufferedImage DestImage = null;
            if (isHorizontal) { // 水平方向合并
                DestImage = new BufferedImage(w1 + w2, h1, BufferedImage.TYPE_INT_RGB);
                DestImage.setRGB(0, 0, w1, h1, ImageArrayOne, 0, w1); // 设置上半部分或左半部分的RGB
                DestImage.setRGB(w1, 0, w2, h2, ImageArrayTwo, 0, w2);
            } else { // 垂直方向合并
                DestImage = new BufferedImage(w1, h1 + h2, BufferedImage.TYPE_INT_RGB);
                DestImage.setRGB(0, 0, w1, h1, ImageArrayOne, 0, w1); // 设置上半部分或左半部分的RGB
                DestImage.setRGB(0, h1, w2, h2, ImageArrayTwo, 0, w2); // 设置下半部分的RGB
            }
    
            return DestImage;
        }
    
        /**
         * Java 测试图片叠加方法
         */
        public static void overlyingImageTest(String fromImage1, int fromImage2) {
    
            String sourceFilePath = "/Users/gaotengfei/Library/Containers/com.tencent.xinWeChat/Data/Library/Application Support/com.tencent.xinWeChat/2.0b4.0.9/03f04497b9d216597c344638d77c156e/Message/MessageTemp/10944c44d02a8bab9912282f7a619448/File/1-1/" + fromImage1 + ".png";
            System.out.println(sourceFilePath);
            String waterFilePath = "/Users/gaotengfei/Library/Containers/com.tencent.xinWeChat/Data/Library/Application Support/com.tencent.xinWeChat/2.0b4.0.9/03f04497b9d216597c344638d77c156e/Message/MessageTemp/10944c44d02a8bab9912282f7a619448/File/1-1/1-" + fromImage2 + ".png";
            String saveFilePath = "/Users/gaotengfei/Library/Containers/com.tencent.xinWeChat/Data/Library/Application Support/com.tencent.xinWeChat/2.0b4.0.9/03f04497b9d216597c344638d77c156e/Message/MessageTemp/10944c44d02a8bab9912282f7a619448/File/1-1/new-1.png";
            try {
                BufferedImage bufferImage1 = getBufferedImage(sourceFilePath);
                BufferedImage bufferImage2 = getBufferedImage(waterFilePath);
    
                // 构建叠加层
                BufferedImage buffImg = overlyingImage(bufferImage1, bufferImage2, 0, 0, 1.0f);
                // 输出水印图片
                generateSaveFile(buffImg, saveFilePath);
            } 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 = "/Users/gaotengfei/Library/Containers/com.tencent.xinWeChat/Data/Library/Application Support/com.tencent.xinWeChat/2.0b4.0.9/03f04497b9d216597c344638d77c156e/Message/MessageTemp/10944c44d02a8bab9912282f7a619448/File/1-1/1-1.png";
            String divingPath = "/Users/gaotengfei/Library/Containers/com.tencent.xinWeChat/Data/Library/Application Support/com.tencent.xinWeChat/2.0b4.0.9/03f04497b9d216597c344638d77c156e/Message/MessageTemp/10944c44d02a8bab9912282f7a619448/File/1-1/1-2.png";
            String margeImagePath = "/Users/gaotengfei/Library/Containers/com.tencent.xinWeChat/Data/Library/Application Support/com.tencent.xinWeChat/2.0b4.0.9/03f04497b9d216597c344638d77c156e/Message/MessageTemp/10944c44d02a8bab9912282f7a619448/File/1-1/margeNew.png";
            try {
                bi1 = getBufferedImage(saveFilePath);
                bi2 = getBufferedImage(divingPath);
                // 调用mergeImage方法获得合并后的图像
                destImg = mergeImage(bi1, bi2, false);
            } catch (IOException e) {
                e.printStackTrace();
            }
            // 保存图像
            generateSaveFile(destImg, margeImagePath);
            System.out.println("垂直合并完毕!");
        }
    
        public static void main(String[] args) {
            for (int i = 1; i <= 7; i++) {
                System.out.println(i);
                if (i == 1) {
                    overlyingImageTest("1-"+i + "", i + 1 );
                }
                if (i + 2 < 10 && i != 1) {
                    overlyingImageTest("new-1", i + 1 );
                }
            }
    //        //1-
    //        overlyingImageTest( "new-1", 8);
        }
    
    }
    

    效果图
    new-1