JAVA生成九宫格图片 微信群头像(不限制张数)拿走即可用

废话不多说 先上效果 再上代码

在这里插入图片描述

package cn.specil.util.file;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

public class MakeGropHeadPicUtil {
    /**图片宽度*/
    private final Integer PIC_WIDTH = 422;
    /**图片高度*/
    private final Integer PIC_HEIGHT = 422;
    /**空白宽度*/
    private final Integer PIC_SPACE = 14;

    /**小图片宽度*/
    private Double LUMP_WIDTH = null;
    /**小图片起始点横坐标*/
    private Double LUMP_POINT_X = null;
    /**小图片起始点纵坐标*/
    private Double LUMP_POINT_Y = null;

    /***  思考笔记  可以跳过
     *  2 和 4 的区别  向下偏移量          0.5 LUMP_WIDTH+  0.5 PIC_SPACE
     *  3 和 4 的区别 第一张图向右偏移量   0.5 LUMP_WIDTH + 0.5 PIC_SPACE
     *  5 和 6 的区别 第一张图向右偏移量   0.5 LUMP_WIDTH+ 0.5 PIC_SPACE
     *  6 和 9 的区别 向下偏移量          0.5 LUMP_WIDTH+ 0.5 PIC_SPACE
     *  7 和 9 的区别 第一张图向右偏移量  LUMP_WIDTH+PIC_SPACE
     *  8 和 9 的区别 第一张图向右偏移量  0.5 LUMP_WIDTH+ 0.5 PIC_SPACE
     */

    // 围边使用的灰色
    private final int [] COLOR_GREY_BGR = new int[] {230, 230, 230};

    //校对数组使用下标
    private int flg = 0;

    public static void main(String[] args) {
        MakeGropHeadPicUtil picUtil = new MakeGropHeadPicUtil();

        //添加测试图片
        List<String> pics = new ArrayList<>();
        pics.add("C:/Users/specil/Desktop/Cross/小测试/1.jpg");
        pics.add("C:/Users/specil/Desktop/Cross/小测试/2.jpg");
        pics.add("C:/Users/specil/Desktop/Cross/小测试/3.jpg");
        pics.add("C:/Users/specil/Desktop/Cross/小测试/4.jpg");
        pics.add("C:/Users/specil/Desktop/Cross/小测试/5.jpg");
        pics.add("C:/Users/specil/Desktop/Cross/小测试/6.jpg");
        pics.add("C:/Users/specil/Desktop/Cross/小测试/7.jpg");
        pics.add("C:/Users/specil/Desktop/Cross/小测试/8.jpg");
//        pics.add("C:/Users/specil/Desktop/Cross/小测试/9.jpg");

        //注意 存储位置最后记得加“/”
        picUtil.getCombinationOfhead(pics,"C:/Users/specil/Desktop/Cross/小测试/","八张图");
    }

    /**
     * @param pics 图片列表
     * @param path 存储路径
     * @param fileName 存储图片名称
     * @return 成功 OR 失败
     */
    public boolean getCombinationOfhead(List<String> pics, String path, String fileName){
        List<BufferedImage> bufferedImages = new ArrayList<BufferedImage>();

        // BufferedImage.TYPE_INT_RGB可以自己定义可查看API
        BufferedImage outImage = new BufferedImage(PIC_WIDTH, PIC_HEIGHT, BufferedImage.TYPE_INT_RGB);

        Graphics2D gra = outImage.createGraphics();
        //设置背景为蓝灰色
        gra.setColor(toColor(COLOR_GREY_BGR));
        //填满图片
        gra.fillRect(0, 0, PIC_WIDTH, PIC_HEIGHT);

        // 开始拼凑 根据图片的数量判断该生成哪种样式组合头像

        Integer size = pics.size();//图片数量
        Integer sqrt = (int)Math.ceil(Math.sqrt(size));//宽度  一行几张图片
        //计算出 单张图片宽度
        LUMP_WIDTH = (PIC_WIDTH - ((sqrt + 1.0) * PIC_SPACE))/sqrt;

        System.out.println(LUMP_WIDTH);

        // 压缩图片所有的图片生成尺寸同意的 为 125*125
        for (int i = 0; i < pics.size(); i++) {
            BufferedImage resize2 = resize2(pics.get(i), LUMP_WIDTH.intValue(), LUMP_WIDTH.intValue(), true);
            bufferedImages.add(resize2);
        }

        //缺几个满伍
        int lack = 0;
        //计算起始点坐标
        if(size < sqrt*(sqrt-1)){//少一行 不满伍
            //缺几个满伍
            lack = sqrt*(sqrt-1) - size;
            //向右边偏移量
            LUMP_POINT_X = PIC_SPACE.doubleValue() + lack * (LUMP_WIDTH + PIC_SPACE) / 2;
            //向下偏移量
            LUMP_POINT_Y = PIC_SPACE.doubleValue() + LUMP_WIDTH/2.;
         }else if (size == sqrt*(sqrt-1)){//满伍少一行
            //向右边偏移量
            LUMP_POINT_X = PIC_SPACE.doubleValue();
            //向下偏移量
            LUMP_POINT_Y = PIC_SPACE.doubleValue() + LUMP_WIDTH/2.;
         }else if(size < sqrt*sqrt){//不满伍
            //缺几个满伍
            lack = sqrt*sqrt - size;
            //向右边偏移量
            LUMP_POINT_X = PIC_SPACE.doubleValue()+ lack * (LUMP_WIDTH + PIC_SPACE) / 2;
            LUMP_POINT_Y = PIC_SPACE.doubleValue();
         }else if (size == sqrt*sqrt){//满伍
            LUMP_POINT_X = PIC_SPACE.doubleValue();
            LUMP_POINT_Y = PIC_SPACE.doubleValue();
         }

        int line = lack==0?-1:0; //第几行图片
        int row = 0; //第几列图片
        for (int i = 0; i < bufferedImages.size(); i++){
            if ((i + lack) % sqrt == 0){
                line ++;
                row = 0;
            }
            if(line == 0){
                gra.drawImage(bufferedImages.get(i), LUMP_POINT_X.intValue() + (row++ * (PIC_SPACE+LUMP_WIDTH.intValue()))
                        , LUMP_POINT_Y.intValue(), null);
            }else{
                gra.drawImage(bufferedImages.get(i), PIC_SPACE + (row++ * (PIC_SPACE+LUMP_WIDTH.intValue()))
                        , LUMP_POINT_Y.intValue() + (line * (PIC_SPACE+LUMP_WIDTH.intValue())), null);
            }
        }

        File file = new File(path+fileName+".png");
        //文件如果存在先删除,再创建
        try {
            if(!file.getParentFile().exists()) {
                file.getParentFile().mkdirs();
                if(file.exists()) {
                    file.delete();
                    if(!file.createNewFile()) {
                        System.out.println("创建失败!");
                    }
                }
            }
        }catch(IOException e) {
            e.printStackTrace();
        }

        //将图片写到文件
        try {
            return ImageIO.write(outImage, "png", file);
        } catch (IOException e) {
            return false;
        }
    }


    /**
     * 图片缩放
     * @param picPath 本地或网络图片路径
     * @param height 缩放后高度
     * @param width 缩放后宽度
     * @param fill 是否填充灰色
     * @return BufferedImage
     */
    public BufferedImage resize2(String picPath, Integer height, Integer width, boolean fill){
        try {
            BufferedImage imageBuff =null;
            if(picPath.indexOf("https://")==0 || picPath.indexOf("http://")==0){ //简单判断是网络图片还是本地图片
                imageBuff = ImageIO.read(new URL(picPath));
            }else{
                imageBuff = ImageIO.read(new File(picPath));
            }

            Image itemp = imageBuff.getScaledInstance(width, height, Image.SCALE_SMOOTH);

            double ratio = 0; // 缩放比例
            // 计算比例
            if ((imageBuff.getHeight() > height) || (imageBuff.getWidth() > width)) {
                if (imageBuff.getHeight() > imageBuff.getWidth()) {
                    ratio = height.doubleValue()/ imageBuff.getHeight();
                } else {
                    ratio = width.doubleValue() / imageBuff.getWidth();
                }
                AffineTransformOp op = new AffineTransformOp(AffineTransform.getScaleInstance(ratio, ratio), null);

                itemp = op.filter(imageBuff, null);
            }

            if (fill) {
                BufferedImage image = new BufferedImage(width, height,
                        BufferedImage.TYPE_INT_RGB);

                Graphics2D g = image.createGraphics();

                g.setColor(toColor(COLOR_GREY_BGR));

                g.fillRect(0, 0, width, height);

                if (width == itemp.getWidth(null))
                    g.drawImage(itemp, 0, (height - itemp.getHeight(null)) / 2,
                            itemp.getWidth(null), itemp.getHeight(null),
                            Color.white, null);
                else
                    g.drawImage(itemp, (width - itemp.getWidth(null)) / 2, 0,
                            itemp.getWidth(null), itemp.getHeight(null),
                            Color.white, null);
                g.dispose();
                itemp = image;
            }
            return (BufferedImage) itemp;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * @toColor 颜色索引转为颜色
     * @param colorRoot 颜色索引
     * @return 颜色
     */
    private Color toColor(int[] colorRoot) {
        if(colorRoot.length>=3) {
            return new Color(colorRoot[0], colorRoot[1], colorRoot[2]);
        }else {
            return null;
        }
    }
}

Java可以通过使用第三方库来生成微信群头像,以下是一个示例: 1. 添加依赖 在项目的pom.xml文件中添加以下依赖: ```xml <dependency> <groupId>com.github.houbb</groupId> <artifactId>combine-image</artifactId> <version>0.0.3</version> </dependency> ``` 这个依赖是一个开源的Java库,用于将多张图片合并成一张图片。 2. 编写代码 下面是一个示例代码,将多张头像合并成一个微信群头像: ```java import com.github.houbb.combine.api.ICombineImage; import com.github.houbb.combine.core.impl.support.builder.CombineImageBuilder; import com.github.houbb.combine.core.impl.support.constant.CombineImageConst; import com.github.houbb.combine.core.impl.support.handler.CombineImageHandler; import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.File; import java.util.ArrayList; import java.util.List; public class WeChatGroupAvatarGenerator { /** * 生成微信群头像 * @param avatarFiles 头像文件列表 * @param outputFilePath 输出文件路径 * @param width 头像宽度 * @param height 头像高度 */ public static void generateGroupAvatar(List<File> avatarFiles, String outputFilePath, int width, int height) throws Exception { // 创建CombineImageBuilder对象 ICombineImage combineImage = CombineImageBuilder.newInstance() .setType(CombineImageConst.DEFAULT_TYPE) .setWidth(width) .setHeight(height) .setHandler(new CombineImageHandler() { @Override public BufferedImage handle(BufferedImage bufferedImage, int imageIndex) { return bufferedImage; } }) .build(); // 添加头像 for (File avatarFile : avatarFiles) { BufferedImage image = ImageIO.read(avatarFile); combineImage.addImage(image); } // 生成合并后的头像 BufferedImage groupAvatar = combineImage.combine(); // 保存合并后的头像 ImageIO.write(groupAvatar, "jpg", new File(outputFilePath)); } public static void main(String[] args) throws Exception { List<File> avatarFiles = new ArrayList<>(); avatarFiles.add(new File("avatar1.jpg")); avatarFiles.add(new File("avatar2.jpg")); avatarFiles.add(new File("avatar3.jpg")); avatarFiles.add(new File("avatar4.jpg")); avatarFiles.add(new File("avatar5.jpg")); generateGroupAvatar(avatarFiles, "group_avatar.jpg", 200, 200); } } ``` 这个示例中,首先创建一个CombineImageBuilder对象,并指定了头像的宽度和高度。然后遍历头像文件列表,将每个头像读取并添加到CombineImageBuilder中。最后调用combine方法生成合并后的头像,并保存到文件中。 注意:在实际应用中,应该根据头像数量来计算宽度和高度,以确保合并后的头像不会失真。同时,应该处理头像的边缘,以使合并后的头像看起来更自然。
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值