java BufferedImage 合成图片 半透明底图 二维码生成

复制粘贴就能用!!!
需求:好几张图片合成一张分享海报.其中还有半透明照片的生成与合成.不复杂调整比例比较耗时间

java BufferedImage 合成图片 半透明底图 二维码生成_第1张图片

package com.web.controller.online;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
import org.apache.commons.codec.binary.Base64;

import javax.imageio.ImageIO;
import javax.imageio.stream.ImageInputStream;
import java.awt.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;


public class muban2 {

//    private Logger logger = LoggerFactory.getLogger(this.getClass());

    public static void main(String[] args) {

        byte[] bytes = compositePicture();
        String base64String = Base64.encodeBase64String(bytes);
//        logger.info("{} encodeBase64String编码后:{}",companyKey, base64String.getBytes().length ,base64String.getBytes().length / 1024);
        System.out.println("data:image/png;base64,"+base64String);
    }


    //调用底图  有头像就使用头像粘贴
    public static byte[] compositePicture( )  {
        try {
        	//生成了一张底图后 再次进行后面拼接
            BufferedImage ditu = ditu();
            Graphics2D g = ditu.createGraphics();//另起一个设置

            //如果有头像信息
            //头像跟用户名背景区域    创建黑色遮罩层
            BufferedImage touxiang = new BufferedImage(386, 122, BufferedImage.TYPE_INT_RGB);
            Graphics2D gTouxiang = touxiang.createGraphics();
            gTouxiang.setColor(Color.BLACK);//设置这个图片对象的颜色
            gTouxiang.fillRect(0, 0, 386, 122);//设置这个图片对象的颜色范围
            gTouxiang.dispose();

            //开启透明度  透明度必须在单独的一个配置中开启  否则会与其他东西共用透明  导致其他导入的图片字体也会透明
            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.5f));//设置本次导入的所有图片与字体透明
            Rectangle rectangleTouxiang = new Rectangle(24, 24, 386, 122);
            BufferedImage touxiangBeijing = setClip(touxiang, 122);//头像背景切圆角

            g.drawImage(touxiangBeijing.getScaledInstance(rectangleTouxiang.width, rectangleTouxiang.height, Image.SCALE_SMOOTH), rectangleTouxiang.x, rectangleTouxiang.y, null);//把透明头像背景放到指定的位置
            g.dispose();

            Graphics2D bg = ditu.createGraphics();//另起一个设置

            //头像的底部
            BufferedImage touxiangD = new BufferedImage(100, 100 , BufferedImage.TYPE_INT_RGB);
            Graphics2D gTouxiangD = touxiangD.createGraphics();
            gTouxiangD.setColor(Color.WHITE);//设置这个图片对象的颜色
            gTouxiangD.fillRect(0, 0, 100, 100);//设置这个图片对象的颜色范围
            BufferedImage bufferedImageTouXiangD = roundImage(touxiangD, 100, 100);//头像背景变圆
            Graphics2D yuanDi = bufferedImageTouXiangD.createGraphics();
            //头像变圆
            BufferedImage guanxiaotong = new BufferedImage(96, 96, BufferedImage.TYPE_INT_RGB);
            guanxiaotong.getGraphics().drawImage(
                    ImageIO.read(new File("C:\\Users\\Administrator\\Desktop\\timg.jpg")).getScaledInstance(96, 96, Image.SCALE_SMOOTH), 0, 0, null);
            
//            BufferedImage guanxiaotong = JqzImageUtils.resizeImage(96, 96, ImageIO.read(new Url("www.某一张图片地址.com")));//调用网上图片
            BufferedImage bufferedImage = roundImage(guanxiaotong, 96, 96);//变圆  设置大小尺寸
            Rectangle rectangleG = new Rectangle(2, 2, 96, 96);//设置头像尺寸与在白背景内与边框的距离

            yuanDi.drawImage(bufferedImage.getScaledInstance(rectangleG.width, rectangleG.height, Image.SCALE_SMOOTH), rectangleG.x, rectangleG.y, null);//把圆头像放到白色底部后面

            Rectangle rectangletouxiangD = new Rectangle(34, 34, 100, 100);

            bg.drawImage(bufferedImageTouXiangD.getScaledInstance(rectangletouxiangD.width, rectangletouxiangD.height, Image.SCALE_SMOOTH), rectangletouxiangD.x, rectangletouxiangD.y, null);//把贴好白色背景的头像放到头像背景后面

            // 金额
            bg.setFont(new Font("Microsoft YaHei", Font.BOLD, 30));//设置字体大小
            bg.setColor(Color.WHITE);//设置字体颜色
            bg.drawString("关晓彤", 150, 75);//设置字体位置

            bg.setFont(new Font("Microsoft YaHei", Font.BOLD, 20));//设置字体大小
            bg.setColor(Color.WHITE);//设置字体颜色
            bg.drawString("给您分享了一个商品", 150, 110);//设置字体位置


            ByteArrayOutputStream output = new ByteArrayOutputStream();
            JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(output);
            JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(ditu);
            param.setQuality(0.98f, true);
            encoder.encode(ditu, param);
            return output.toByteArray();


        } catch (IOException e) {
            System.out.println("合成图片失败"+e.getMessage());
            return null;
        }
    }


    //生成底图
    public static   BufferedImage ditu(){
        try {
            //TODO
            // 透明底
            BufferedImage bg = new BufferedImage(664, 988, BufferedImage.TYPE_INT_RGB);
            Graphics2D g = bg.createGraphics();
            g.setColor(Color.WHITE);
            g.fillRect(0, 0, 664, 988);// 填充整个屏幕
            g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);		// 消除画图锯齿
            g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);	// 消除文字锯齿



            // 写入商品图
			 BufferedImage bufferedImageG =  ImageIO.read(new URL(backgroundUrl));

            int widthG = bufferedImageG.getWidth();
            int heightG = bufferedImageG.getHeight();

			BufferedImage goodsIm = new BufferedImage(widthG, heightG, 1);
        	goodsIm .getGraphics().drawImage(bufferedImageG .getScaledInstance(widthG,widthG, 4), 0, 0, (ImageObserver)null);


            BufferedImage back;
            if (widthG >= heightG) {//图片宽比高大(宽图)   取高的值 截成一个正方形
                int x = 0;
                if ((widthG - heightG) >= 2) {//像素大于2  才调整截图值
                    x = (widthG - heightG) / 2;//调整Y的值 截取图片中间
                }

                back = goodsIm.getSubimage(x, 0, heightG, heightG);//截取图片重新调整
            } else {//图片高比宽大(高图)   取宽的值 截成一个正方形
                int y = 0;
                if ((heightG - widthG) >= 2) {//像素大于2  才调整截图值
                    y = (heightG - widthG) / 2;//调整Y的值 截取图片中间
                }

                back = goodsIm.getSubimage(0, y, widthG, widthG);//截取图片重新调整
            }


               Rectangle rectangle = new Rectangle(50, 168, 566, 556);//有头像
                g.drawImage(back.getScaledInstance(rectangle.width, rectangle.height, Image.SCALE_SMOOTH), rectangle.x, rectangle.y, null);

            // 写入二维码
            BufferedImage qrcode = null;
            try {
                Map<EncodeHintType, String> hints = new HashMap<>();
                hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
                BitMatrix bitMatrix = new MultiFormatWriter().encode("www.baidu.com", BarcodeFormat.QR_CODE, 462, 462, hints);
                qrcode = toBufferedImage(bitMatrix);
            } catch (WriterException e) {
                e.printStackTrace();
            }


            g.drawImage(qrcode, 438, 714, 198, 198, null);

            //人民币图标
            g.setFont(new Font("Microsoft YaHei", Font.PLAIN, 36));
            g.setColor(Color.red);
            g.drawString("¥" , 54, 852);

            // 金额
            g.setFont(new Font("Microsoft YaHei", Font.BOLD, 60));
            g.setColor(Color.red);
            g.drawString("100", 76, 852);


            // 重量
            g.setFont(new Font("Microsoft YaHei", Font.PLAIN, 25));
            g.setColor(new Color(89, 89, 89));
            g.drawString("500g" , 210, 852);

            g.setFont(new Font("Microsoft YaHei", Font.PLAIN, 25));
            g.setColor(Color.gray);
            g.drawString("XXXXXXXXXXX", 50, 728);

            g.setFont(new Font("Microsoft YaHei", Font.PLAIN, 25));
            g.setColor(Color.gray);
            g.drawString("XXXXX", 50, 775);


            g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);						// 消除画图锯齿
            g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);	// 消除文字锯齿

            g.dispose();

            return bg;

        } catch (IOException e) {
            System.out.println("合成图片失败"+e.getMessage());
            return null;
        }
    }


    //将二维码转换成图片
    public static BufferedImage toBufferedImage(BitMatrix matrix){
        int width = matrix.getWidth();
        int height = matrix.getHeight();
        int BLACK = 0xFF000000;
        int WHITE = 0xFFFFFFFF;
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        for (int i = 0;i < width; i++){
            for (int j = 0;j < height; j++){
                image.setRGB(i, j, matrix.get(i, j) ? BLACK : WHITE);
            }
        }
        return image;
    }

    /***
     * 做圆图片方法
     * @param targetSize 文件的边长,单位:像素,最终得到的是一张正方形的图,所以要求targetSize<=源文件的最小边长  新构造的高度
     * @param cornerRadius 圆角半径,单位:像素。如果=targetSize那么得到的是圆形图                             圆角的宽度
     * @return  文件的保存路径
     * @throws IOException
     */
    private static BufferedImage roundImage(BufferedImage image, int targetSize, int cornerRadius) {
        BufferedImage outputImage = new BufferedImage(targetSize, targetSize, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2 = outputImage.createGraphics();
        g2.setComposite(AlphaComposite.Src);
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setColor(Color.WHITE);
        g2.fill(new RoundRectangle2D.Float(0, 0, targetSize, targetSize, cornerRadius, cornerRadius));
        g2.setComposite(AlphaComposite.SrcAtop);
        g2.drawImage(image, 0, 0, null);
        g2.dispose();
        return outputImage;
    }

    /**
     * 图片设置圆角
     * @param srcImage
     * @return
     * @throws IOException
     */
    public static BufferedImage setRadius(BufferedImage srcImage) throws IOException{
        int radius = (srcImage.getWidth() + srcImage.getHeight()) / 6;
        return setRadius(srcImage, radius, 2, 5);
    }

    /**
     * 图片设置圆角
     * @param srcImage
     * @param radius
     * @param border
     * @param padding
     * @return
     * @throws IOException
     */
    public static BufferedImage setRadius(BufferedImage srcImage, int radius, int border, int padding) throws IOException{
        int width = srcImage.getWidth();
        int height = srcImage.getHeight();
        int canvasWidth = width + padding * 2;
        int canvasHeight = height + padding * 2;

        BufferedImage image = new BufferedImage(canvasWidth, canvasHeight, BufferedImage.TYPE_INT_ARGB);
        Graphics2D gs = image.createGraphics();
        gs.setComposite(AlphaComposite.Src);
        gs.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        gs.setColor(Color.WHITE);
        gs.fill(new RoundRectangle2D.Float(0, 0, canvasWidth, canvasHeight, radius, radius));
        gs.setComposite(AlphaComposite.SrcAtop);
        gs.drawImage(setClip(srcImage, radius), padding, padding, null);
        if(border !=0){
            gs.setColor(Color.GRAY);
            gs.setStroke(new BasicStroke(border));
            gs.drawRoundRect(padding, padding, canvasWidth - 2 * padding, canvasHeight - 2 * padding, radius, radius);
        }
        gs.dispose();
        return image;
    }

    /**
     * 图片切圆角  抗锯齿
     * @param srcImage
     * @param radius
     * @return
     */
    public static BufferedImage setClip(BufferedImage srcImage, int radius){
        int width = srcImage.getWidth();
        int height = srcImage.getHeight();
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2d = image.createGraphics();
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.fillRoundRect(0, 0, width, height, radius, radius);
        g2d.setComposite(AlphaComposite.SrcIn);//抗锯齿
        g2d.drawImage(srcImage, 0, 0, width, height, null);
        return image;
    }
}

你可能感兴趣的:(图片合成,二维码生成)