Java 实现合并图片 简易测试

本文介绍了使用Java进行图片合并的实现过程,包括代码修改和效果展示,通过透明度调整来实现图片的融合。
摘要由CSDN通过智能技术生成

JAVA 实现两张图片合并(可多张未实现)

package edu.sdut.Picture.Main;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;

/**
 * @author qingyun
 * @version 1.0
 * @date 2021/9/28 20:13
 */
//实现图片合并
public class PictureMerge {


    private  Graphics2D g        = null;

    //读取网络图片
//    public static BufferedImage readUrl(String ImageUrl){
//        BufferedImage bf = null;
//        try{
//            URL urlfile = new URL(ImageUrl);
//            InputStream inStream = urlfile.openStream();
//            bf = ImageIO.read(inStream);
//        }catch (IOException e) {
//            e.printStackTrace();
//        }
//        return bf;
//    }


    /**
     * 导入本地图片到缓冲区
     */
    public BufferedImage loadImageLocal(String imgName) {
        try {
            return ImageIO.read(new File(imgName));
        } catch (IOException e) {
            System.out.println(e.getMessage());
        }
        return null;
    }

    /**
     * 将两张图片合并在一起
     * @param b
     * @param d
     * @return
     */
    public BufferedImage modifyImagetogeter(BufferedImage b, BufferedImage d) {
        try {
            int w = b.getWidth();
            int h = b.getHeight();
            //进行图片绘制
            g = d.createGraphics();
            g.drawImage(b, 300, -800, w, h, null);
            g.dispose();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        return d;
    }


    /**
     * 生成新图片到本地
     */
    public void writeImageLocal(String newImage, BufferedImage img) {
        if (newImage != null && img != null) {
            try {
                File outputfile = new File(newImage);
                ImageIO.write(img, "jpg", outputfile);
            } catch (IOException e) {
                System.out.println(e.getMessage());
            }
        }
    }

    /**
     * 图片测试
     * @param args
     */
    public static void main(String[] args) {
        PictureMerge pictureMerge = new PictureMerge();
        //图片A
        BufferedImage d = pictureMerge.loadImageLocal("D:\\GIF\\jpg\\1.jpg");
        //t
        BufferedImage b = pictureMerge.loadImageLocal("D:\\GIF\\jpg\\2.jpg");
        pictureMerge.writeImageLocal("D:\\GIF\\gif\\10.jpg", pictureMerge.modifyImagetogeter(b, d));
        //将多张图片合在一起
        System.out.println("success");
    }
}

测试图片1

2

生成图片如下

10

不符合期望,故进行代码修改

修改后代码如下

package edu.sdut.Picture.Main;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;

/**
 * @author qingyun
 * @version 1.0
 * @date 2021/9/28 20:13
 */
//实现图片合并
public class PictureMerge {


    private  Graphics2D g        = null;

    //读取网络图片
//    public static BufferedImage readUrl(String ImageUrl){
//        BufferedImage bf = null;
//        try{
//            URL urlfile = new URL(ImageUrl);
//            InputStream inStream = urlfile.openStream();
//            bf = ImageIO.read(inStream);
//        }catch (IOException e) {
//            e.printStackTrace();
//        }
//        return bf;
//    }


    /**
     * 导入本地图片到缓冲区
     */
    public BufferedImage loadImageLocal(String imgName) {
        try {
            return ImageIO.read(new File(imgName));
        } catch (IOException e) {
            System.out.println(e.getMessage());
        }
        return null;
    }

    /**
     * 将两张图片合并在一起
     * @param b
     * @param d
     * @return
     */
    public BufferedImage modifyImagetogeter(BufferedImage b, BufferedImage d) {
        try {
            int w = d.getWidth();
            int h = d.getHeight();
            //进行图片绘制
            g = d.createGraphics();
            //更改生成的位置  图片进行覆盖
            g.drawImage(b, 0, 0, w, h, null);
            g.dispose();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        return d;
    }


    /**
     * 生成新图片到本地
     */
    public void writeImageLocal(String newImage, BufferedImage img) {
        if (newImage != null && img != null) {
            try {
                File outputfile = new File(newImage);
                ImageIO.write(img, "jpg", outputfile);
            } catch (IOException e) {
                System.out.println(e.getMessage());
            }
        }
    }



    /**
     * 将背景替换为透明
     *
     * @return
     * @throws IOException the io exception
     * @author Jack Que
     * @created 2021 -07-08 10:25:10 Change img color.
     */
    public static BufferedImage changeImgColor(BufferedImage bi) throws IOException {
        Image image = (Image) bi;
        //将原图片的二进制转化为ImageIcon
        ImageIcon imageIcon = new ImageIcon(image);
        int width = imageIcon.getIconWidth();
        int height = imageIcon.getIconHeight();
        //图片缓冲流
        BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);
        Graphics2D graphics2D = (Graphics2D) bufferedImage.getGraphics();
        graphics2D.drawImage(imageIcon.getImage(), 0, 0, imageIcon.getImageObserver());
        int alpha = 255;
        //这个背景底色的选择,我这里选择的是比较偏的位置,可以修改位置。背景色选择不知道有没有别的更优的方式(比如先过滤一遍获取颜色次数最多的,但是因为感觉做起来会比较复杂没去实现),如果有可以评论。
        int RGB=bufferedImage.getRGB(width-1, height-1);
        for(int i = bufferedImage.getMinX(); i < width; i++) {
            for(int j = bufferedImage.getMinY(); j < height; j++) {
                int rgb = bufferedImage.getRGB(i, j);
                int r = (rgb & 0xff0000) >>16;
                int g = (rgb & 0xff00) >> 8;
                int b = (rgb & 0xff);
                int R = (RGB & 0xff0000) >>16;
                int G = (RGB & 0xff00) >> 8;
                int B = (RGB & 0xff);
                //a为色差范围值,渐变色边缘处理,数值需要具体测试,50左右的效果比较可以
                int a = 45;
                if(Math.abs(R-r) < a && Math.abs(G-g) < a && Math.abs(B-b) < a ) {
                    alpha = 0;
                } else {
                    alpha = 255;
                }
                rgb = (alpha << 24)|(rgb & 0x00ffffff);
                bufferedImage.setRGB(i,j,rgb);
            }
        }
            return bufferedImage;
    }
    public static String convertRgbStr(int color) {
        // 获取color(RGB)中R位
        int red = (color & 0xff0000) >> 16;
        // 获取color(RGB)中G位
        int green = (color & 0x00ff00) >> 8;
        // 获取color(RGB)中B位
        int blue = (color & 0x0000ff);
        return red + "," + green + "," + blue;
    }


    /**
     * 图片测试
     * @param args
     */
    public static void main(String[] args) throws IOException {
        PictureMerge pictureMerge = new PictureMerge();
        //图片A
        BufferedImage d = pictureMerge.loadImageLocal("D:\\GIF\\gif\\1.jpg");
        //t
        BufferedImage b = pictureMerge.loadImageLocal("D:\\GIF\\jpg\\2.jpg");
        //实现图片透明
//        d = changeImgColor(d);
        b = changeImgColor(b);
        pictureMerge.writeImageLocal("D:\\GIF\\gif\\10.jpg", pictureMerge.modifyImagetogeter(b, d));
        //将多张图片合在一起
        System.out.println("success");
    }
}

产生效果如下 (修改了背景图片素描画并且进行了透明化但不符合期望,继续修改)

11

替换了另一套代码 使用透明度进行图片合并 代码如下

package edu.sdut.Picture.Main;
import java.awt.AlphaComposite;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;

/**
 * @author qingyun
 * @version 1.0
 * @date 2021/9/28 22:23
 */
public class ImageMarkLogoByIcon {

    /**
     * @param args
     */
    public static void main(String[] args) {
        String srcImgPath = "D:\\GIF\\jpg\\1.jpg";
        String iconPath = "D:\\GIF\\jpg\\2.jpg";
        String targerPath = "D:\\GIF\\gif\\3.jpg" ;
        // 给图片添加水印
        ImageMarkLogoByIcon.markImageByIcon(iconPath, srcImgPath, targerPath , 0);
    }
    /**
     * 给图片添加水印
     * @param iconPath 水印图片路径
     * @param srcImgPath 源图片路径
     * @param targerPath 目标图片路径
     */
    public static void markImageByIcon(String iconPath, String srcImgPath,
                                       String targerPath) {
        markImageByIcon(iconPath, srcImgPath, targerPath, null) ;
    }
    /**
     * 给图片添加水印、可设置水印图片旋转角度
     * @param iconPath 水印图片路径
     * @param srcImgPath 源图片路径
     * @param targerPath 目标图片路径
     * @param degree 水印图片旋转角度
     */
    public static void markImageByIcon(String iconPath, String srcImgPath,
                                       String targerPath, Integer degree) {
        OutputStream os = null;
        try {
            Image srcImg = ImageIO.read(new File(srcImgPath));
            BufferedImage buffImg = new BufferedImage(srcImg.getWidth(null),
                    srcImg.getHeight(null), BufferedImage.TYPE_INT_RGB);
            // 得到画笔对象
            // Graphics g= buffImg.getGraphics();
            Graphics2D g = buffImg.createGraphics();

            // 设置对线段的锯齿状边缘处理
            g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
                    RenderingHints.VALUE_INTERPOLATION_BILINEAR);

            g.drawImage(srcImg.getScaledInstance(srcImg.getWidth(null), srcImg
                    .getHeight(null), Image.SCALE_SMOOTH), 0, 0, null);

            if (null != degree) {
                // 设置水印旋转
                g.rotate(Math.toRadians(degree),
                        (double) buffImg.getWidth() / 2, (double) buffImg
                                .getHeight() / 2);
            }
            // 水印图象的路径 水印一般为gif或者png的,这样可设置透明度
            ImageIcon imgIcon = new ImageIcon(iconPath);
            // 得到Image对象。
            Image img = imgIcon.getImage();
            float alpha = 0.65f; // 透明度
            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,
                    alpha));
            // 表示水印图片的位置
            g.drawImage(img, 0, 0,buffImg.getWidth(),buffImg.getHeight(), null);
            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
            g.dispose();
            os = new FileOutputStream(targerPath);
            // 生成图片
            ImageIO.write(buffImg, "JPG", os);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != os){
                    os.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

效果如下

3

本次处理到此为止,后续更改再次更新

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值