Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >回敬Python蹭女神热度助发朋友圈,Java实现头像分成九宫图,再生成拼图头像

回敬Python蹭女神热度助发朋友圈,Java实现头像分成九宫图,再生成拼图头像

作者头像
软件测试君
发布于 2020-07-31 09:35:49
发布于 2020-07-31 09:35:49
80900
代码可运行
举报
文章被收录于专栏:测试人生测试人生
运行总次数:0
代码可运行

前言:

晚上刷朋友圈,看到这样一条朋友圈挺有意思的,如下图所示:

于是,我点开文章后,大概看了下文章的意思,其实就是把一个图片分成九宫图,即拼图的碎片,既然Python都能实现,作为回应,java必然也是可以做到的。

结果,一时技痒,整理了下思路。就马上打开IDEA开始编码,于是,就有了这篇文章。

某号文章实现:

将一张完整的图片分割成9张小图片,制作成朋友圈九宫格的图片。

追加实现:

将分割成的九个小图片,在生成一个拼图头像图片。

最终实现效果在万圈:

主要思路:

  1. 一个待绘制的BufferedImage,长宽都是原图的1/3
  2. 使用graphics,通过偏移量选择绘制原图的区域
  3. 绘制结束就可以输出到文件
  4. 通过两层循环,绘制9个位置的全部图片
  5. 将生成九个拼图碎片进行图片合成

实现代码:

1、生成拼图碎片 具体示例代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;

/**
 * @author rongrong
 * @version 1.0
 * @description 将图片分成九个拼图碎片
 * @date 2020/7/28 20:20
 */
public class SetImage {
    public static void main(String[] args) {
        File imgfile;
        Image originimg;
        BufferedImage image;
        Graphics g;
        FileOutputStream out;
        JPEGImageEncoder encoder;
        try {
            // 获取原始图片
            imgfile = new File("D:\\picture\\original.jpg");
            originimg = ImageIO.read(imgfile);
            // 获取原始图片的宽和高
            int width = originimg.getWidth(null);
            int height = originimg.getHeight(null);
            // 如果输入为长方形,重新计算长宽
            int outputwidth = width > height ? height : width;
            int outputheight = outputwidth;
            for (int i = 0; i < 3; i++) {
                for (int j = 0; j < 3; j++) {
                    // 九宫格,每张图片大小都为原来的1/3
                    // 长方形,新建图片大小为计算后的正方型的1/3
                    image = new BufferedImage(outputwidth / 3,
                            outputheight / 3, BufferedImage.TYPE_INT_RGB);
                    // 创建图片
                    g = image.createGraphics();
                    // 绘制图片
                    // 长方形,计算偏移量的数据采用计算后的正方形
                    g.drawImage(originimg, outputwidth * -i / 3, outputheight
                            * -j / 3, width, height, null);
                    // 图片绘制完成,关闭g
                    g.dispose();
                    // 输出流和输出文件
                    out = new FileOutputStream("D:\\picture\\" + (i+1)+ "-" + j + ".jpg");
                    // 下面代码将输出图片转换为JPEG、JPG文件
                    encoder = JPEGCodec.createJPEGEncoder(out);
                    encoder.encode(image);
                    out.close();
                    System.out.println("拼图碎片已分拆成功");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

2、利用生成拼图碎片合成头像图片 具体示例代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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;
/**
 * @description 将九个拼图生成头像
 * @author rongrong
 * @version 1.0
 * @date 2020/7/28 21:18
 */
public class MakeGropHeadPic {
    /**图片宽度*/
    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;


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

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

    public static void main(String[] args) {
        MakeGropHeadPic picUtil = new MakeGropHeadPic();
        //添加拼图图片
        List<String> pics = new ArrayList<>();
        pics.add("D:\\picture\\1-0.jpg");
        pics.add("D:\\picture\\2-0.jpg");
        pics.add("D:\\picture\\3-0.jpg");
        pics.add("D:\\picture\\1-1.jpg");
        pics.add("D:\\picture\\2-1.jpg");
        pics.add("D:\\picture\\3-1.jpg");
        pics.add("D:\\picture\\1-2.jpg");
        pics.add("D:\\picture\\2-2.jpg");
        pics.add("D:\\picture\\3-2.jpg");
        picUtil.getCombinationOfhead(pics,"D:\\picture\\","拼图头像");
    }

    /**
     * @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;
        }
    }
}

整个过程分为两个部分:

  1. 转换图片、切割图片和保存图片
  2. 切割图片合成新图片

执行测试:

最后,我们找一张图片来做测试,比如:我把源文件放到D盘的picture文件夹下,如下图:

1、首先,运行先生成拼图图片,即九宫格的碎片。结果如下图所示:

从截图我们可以看到,我们的图片切割精准都是正方形,所以这段代码拿去尽管去用即可。

2、将九张拼图合成一个图片头像,在来运行第二个类,结果如下图所示:

最后

以上便是一个生成拼图碎片,再生成拼图头像的过程。感兴趣的朋友,还不赶紧去试试?

版权归软件测试君所有

欢迎同行转载开白

作者@糖小幽

编辑@糖小幽

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-07-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 软件测试君 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
java学习笔记(中级篇)—java实现高质量图片压缩
使用java几十行代码实现一个高质量图片压缩程序,再也不用去自己找网络的压缩程序啦!而且很多网上的工具还有水印或者其他的限制,自己动手写一个简单的应用,是再合适不过了。
chlinlearn
2019/08/06
2.2K0
Java 操作 Office:POI word之网络图片处理
在前面两篇,我们已经知道了Java通过POI生成Word表格、表格内插入图片,并在插入前对图片进行标注操作,本篇将再通过一个更贴近真实场景的案例的实现,来了解一下poi在word导出场景的实战应用。
程序员架构进阶
2021/08/23
1.4K0
java生成二维码例子及Qrcode.jar包(demo小例子)
java生成二维码例子及Qrcode.jar包 #######获取地址: http://note.youdao.com/noteshare?id=dd9ec8a63ab3b97eba58bf7b32
挑战者
2018/06/29
1.6K0
Java 实现灰度图转真彩图
一写代码就开心
2023/11/02
2460
Java 实现灰度图转真彩图
Java使用zxing生成二维码(带有logo)
首先要添加zxing依赖 <!-- 二维码生成依赖 --> <dependency> <groupId>com.google.zxing</groupId> <artifactId>core</artifactId> <version>3.4.0</version> </dependency> <dependency> <groupId>com.google.zxing</groupId> <artifactId>javase</artifactId> <ve
崔笑颜
2020/06/08
3.1K0
java实现在线预览–poi实现word、excel、ppt转html
###简介 java实现在线预览功能是一个大家在工作中也许会遇到的需求,如果公司有钱,直接使用付费的第三方软件或者云在线预览服务就可以了,例如永中office、office web 365(http://www.officeweb365.com/)他们都有云在线预览服务,就是要钱0.0 如果想要免费的,可以用openoffice,还需要借助其他的工具(例如swfTools、FlexPaper等)才行,可参考这篇文章http://blog.csdn.net/z69183787/article/details/17468039,写的挺细的,实现原理就是: 1.通过第三方工具openoffice,将word、excel、ppt、txt等文件转换为pdf文件; 2.通过swfTools将pdf文件转换成swf格式的文件; 3.通过FlexPaper文档组件在页面上进行展示。 当然如果装了Adobe Reader XI,那把pdf直接拖到浏览器页面就可以直接打开预览,这样就不需要步骤2、3了,前提就是客户装了Adobe Reader XI这个pdf阅读器。 我这里介绍通过poi实现word、excel、ppt转html,这样就可以放在页面上了。
全栈程序员站长
2022/09/06
2.2K0
Java 生成透明图片
设置图片透明import org.apache.commons.io.FilenameUtils;import org.apache.commons.io.IOUtils;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import javax.imageio.ImageIO;import javax.imageio.stream.ImageOutputStream;import javax.swing.\*;import java.awt.\*
IT小马哥
2022/12/31
1.1K0
高斯模糊的Java实现及优化
离散卷积是卷积对离散量的特殊形式,假设现有原图矩阵A,权值矩阵B,则点(x,y)处的离散卷积为
DearXuan
2022/01/19
7450
高斯模糊的Java实现及优化
Google zxing 生成带logo的二维码图片
SmileNicky
2023/10/19
4440
Google zxing 生成带logo的二维码图片
Java实现图片无损任意角度旋转
在做项目的时候遇到一个业务需要对图片进行旋转,于是找到一个工具类,亲测有效;在此与大家共享,需要用时可以直接用哈! 一、旋转工具类代码:
崔笑颜
2020/06/08
3.9K0
开源)嗨,Java,你可以生成金山词霸的二维码分享海报吗?
有那么一段时间,我特别迷恋金山词霸的每日一句分享海报。因为不仅海报上的图片美,文字也特别美,美得让我感觉生活都有了诗意。就像文章开头的那句中英文对照,中文和英文都妙极了。
沉默王二
2019/05/14
7530
开源)嗨,Java,你可以生成金山词霸的二维码分享海报吗?
自定义瓦片地图切图-基于腾讯地图
在腾讯地图上发一张自定义的手绘地图,由于手绘地图像素都比较高,加载一整张图速度极慢。将手绘地图按照地图的瓦片规则切片分开加载。
bug专8
2021/04/27
5.5K3
java贪吃蛇小游戏(详解)[通俗易懂]
首先给出代码下载地址(含素材):https://share.weiyun.com/8hkvy1Ja
全栈程序员站长
2022/09/07
1.8K0
java贪吃蛇小游戏(详解)[通俗易懂]
Java之二维码工具类
<dependency>     <groupId>com.google.zxing</groupId>     <artifactId>core</artifactId>     <version>3.3.0</version> </dependency>     <!-- https://mvnrepository.com/artifact/com.google.zxing/javase --> <dependency>     <groupId>com.google.zxing</groupId>     <artifactId>javase</artifactId>     <version>3.3.0</version>
周杰伦本人
2023/10/12
3630
Java之二维码工具类
JavaUtil_03_图片处理工具类
 一、源码 功能:缩放图像、切割图像、图像类型转换、彩色转黑白、文字水印、图片水印等 package com.ray.dingtalk.util; import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; import java.awt.Toolkit; i
shirayner
2018/08/10
1K0
java实现gif图片剪裁
最近负责组内的图片上传相关的业务,有了一个新的需求,大概要做的功能是要实现gif图片有裁剪的功能,一想到咋自个对图片这种数据结构不是很熟,所以找开源项目吧。终于找到了gif4j这样一个项目。于是乎作者立马将它fock了一下,然后改造成了自己的项目。最后的裁剪效果如下,基本达到了要求了。
写一点笔记
2022/08/11
1.2K0
java实现gif图片剪裁
javaCV视频取帧测试类,封装完整可直接使用,真香!!
前段时间我需要一个视频取帧工具,在网上查询一些单都或多或少有问题,于是自己总结了一下,并已经封装好,分享出来供大家需要时使用。
陈哈哈
2020/07/06
3.1K1
Java生成读取条形码和二维码图片
生成条形码,二维码图片,解析条形码,二维码图片的工具类,需要用到的jar包:core.jar,zxing-javase.jar
用户8983410
2021/09/23
1.3K1
微信小程序 带参二维码 纯Java实现
本文原创首发CSDN,链接 https://blog.csdn.net/qq_41464123/article/details/106335476 ,作者博客https://blog.csdn.net/qq_41464123 ,转载请带上本段内容,尤其是脚本之家、码神岛等平台,谢谢配合。 ----
Designer 小郑
2023/08/01
3480
微信小程序 带参二维码 纯Java实现
Java实现网页截屏
import java.awt.AWTException; import java.awt.Desktop; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Image; import java.awt.Rectangle; import java.awt.Robot; import java.awt.Toolkit; import java.awt.event.KeyEvent; import java.awt.im
用户8983410
2021/09/23
2.2K0
相关推荐
java学习笔记(中级篇)—java实现高质量图片压缩
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验