二维码合图

简介: 二维码合图,是为二维码套上一个好看的模版底图,再配上一定的文案,这种图片常见于线下地推业务中,例如扫码领鸡蛋等场景~ 下面是如何得到这个图片生成二维码二维码的本质是一个url,通过二维码插件szxing就可以得到一个二维码pom文件<dependency>    <groupId>com.taobao.xcode.szxing</groupId>    &l

二维码合图,是为二维码套上一个好看的模版底图,再配上一定的文案,这种图片常见于线下地推业务中,例如扫码领鸡蛋等场景~ 下面是如何得到这个图片

生成二维码

二维码的本质是一个url,通过二维码插件szxing就可以得到一个二维码

pom文件

<dependency>
    <groupId>com.taobao.xcode.szxing</groupId>
    <artifactId>szxing</artifactId>
</dependency>

生成二维码java核心代码

// 要生成二维码的url
String url="http://taobao.com";
// 二维码的宽
int width = 248;
// 二维码的高
int height = 252;

ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
// 通过QRCodeWriter.encode生成的输出流
QRCodeWriter.encode(url, width, height, null, byteArrayOutputStream);

// 根据 QRCodeWriter.encode生成的输出流,生成BufferedImage
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
BufferedImage qrImage = ImageIO.read(byteArrayInputStream);

// 根据BufferedImage,生成图片文件
File file = new File();
ImageIO.write(qrImage, "jpg", file);

通过跑代码,可以得到一个二维码

 

二维码合图

一般二维码都会有一个漂亮的模版,并且会有些文字描述,如下图,图1是模版,图2是根据模版合图后的图,且“淘宝福利码”上方有一个很小的说明。接下来将这是如何实现的,我是通过java.awt包下的Graphics2D工具实现的,主要思路是,可以把Graphics2D理解成一个画板,以模版图片为画板的底图,把二维码图片贴到画板中间合适位置(主要是调整x轴、y轴坐标),再把要加的文字贴到合适的位置。

   

以下是代码实现

ImageUtil工具类


public class ImageUtil {

    /**
     * 合图
     *
     * @param drawBoardDTO           画板
     * @param templatePositionDTO    合图模版
     * @param masterImagePositionDTO 主图
     * @param imageTexts             合图文案
     * @return
     */
    public static BufferedImage drawImageBase(DrawBoardDTO drawBoardDTO, ImagePositionDTO templatePositionDTO,
        ImagePositionDTO masterImagePositionDTO, java.util.List<ImageText> imageTexts) {
        // RGB形式
        BufferedImage bgBufImage = new BufferedImage(drawBoardDTO.getWidth(), drawBoardDTO.getHeight(),
            BufferedImage.TYPE_INT_RGB);
        Graphics2D bgBufImageGraphics = bgBufImage.createGraphics();
        // 设置背景色
        bgBufImageGraphics.setBackground(drawBoardDTO.getBackgroundColor());
        // 通过使用当前绘图表面的背景色进行填充来清除指定的矩形
        bgBufImageGraphics.clearRect(0, 0, drawBoardDTO.getWidth(), drawBoardDTO.getHeight());

        // 画模版
        bgBufImageGraphics.drawImage(templatePositionDTO.getBufferedImage(), templatePositionDTO.getX(),
            templatePositionDTO.getY(), templatePositionDTO.getWidth(), templatePositionDTO.getHeight(), null);

        // 画主图
        bgBufImageGraphics.drawImage(masterImagePositionDTO.getBufferedImage(), masterImagePositionDTO.getX(),
            masterImagePositionDTO.getY(), masterImagePositionDTO.getWidth(), masterImagePositionDTO.getHeight(), null);

        // 设置画笔,设置Paint属性
        // 抗锯齿
        bgBufImageGraphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        bgBufImageGraphics.setPaint(Color.WHITE);
        // 画文案
        for (ImageText imageText : imageTexts) {
            bgBufImageGraphics.setFont(imageText.getFont());

            if (Objects.nonNull(imageText.getColor())) {
                bgBufImageGraphics.setColor(imageText.getColor());
            }

            // 计算文字长度,计算居中的x点坐标
            Integer x = imageText.getX();
            if (Objects.isNull(x)) {
                FontMetrics fm = bgBufImageGraphics.getFontMetrics(imageText.getFont());
                int textWidth = fm.stringWidth(imageText.getData());
                x = (drawBoardDTO.getWidth() - textWidth) / 2;
            }

            bgBufImageGraphics.drawString(imageText.getData(), x, imageText.getY());
        }

        bgBufImageGraphics.dispose();
        return bgBufImage;
    }
}    

DrawBoardDTO类 画板类(画板宽高、背景颜色等)

@Data
@AllArgsConstructor
public class DrawBoardDTO {

    // 画板的宽
    private int width;

    // 画板的高
    private int height;

    // 画板的背景颜色
    private Color backgroundColor;
}

ImagePositionDTO类 图片位置类(即二维码在画板的坐标)

@Data
@AllArgsConstructor
public class ImagePositionDTO {
    // 图片信息
    private BufferedImage bufferedImage;

    // 二维码x坐标位置
    private int x;

    // 二维码y坐标位置
    private int y;

    // 二维码宽度
    private int width;

    // 二维码高度
    private int height;
}

ImageText类 文案信息(文案描述、文案横纵坐标、字体、颜色等)

@Data
@Builder
public class ImageText {
    // 实际文本
    private String data;

    // 文本x坐标位置, 填null则表示水平居中
    private Integer x;

    // 文本y坐标位置
    private Integer y;

    // 字体
    private Font font;

    // 颜色
    private Color color;

    public ImageText(String data, Integer y, Font font) {
        this.data = data;
        this.y = y;
        this.font = font;
    }

    public ImageText(String data, Integer x, Integer y, Font font, Color color) {
        this.data = data;
        this.x = x;
        this.y = y;
        this.font = font;
        this.color = color;
    }
}

使用ImageUtil.drawImageBase实现合图的调用

// 二维码的在oss上的url
String qrOssUrl="";

BufferedImage bufferedImage = null;
try {
    // 定义画板
    DrawBoardDTO drawBoardDTO = new DrawBoardDTO(672, 1264, Color.WHITE);

    // 定义合图模版
    InputStream InputStream = ImageUtil.class.getResourceAsStream("/newBenefitCodeTemplate.jpg");
    ImagePositionDTO templatePositionDTO = new ImagePositionDTO(ImageIO.read(InputStream), 0, 0, 672,
        1264);

    // 定义主图
    ImagePositionDTO qrPositionDTO = new ImagePositionDTO(ImageIO.read(new URL(qrOssUrl)),
        90, 430, 500, 500);

    // 定义合图文案
    List<ImageText> imageTexts = Lists.newArrayList(
        new ImageText("PromoterID:XXX", 150, new Font("宋体", Font.PLAIN, 15)),
        new ImageText("PromoterID:YYY", 150, new Font("阿里巴巴普惠体", Font.PLAIN, 20)),
    );

    bufferedImage = ImageUtil.drawImageBase(drawBoardDTO, templatePositionDTO, qrPositionDTO, imageTexts);
} catch (Throwable throwable) {
    // 记录日志
}

字体安装

在图片上写文案的时候,可以设置漂亮的字体,以下是服务器安装字体的说明,以下是几个的字体包(阿里巴巴普惠体

[文件: Alibaba-PuHuiTi-Bold.ttf] 请在PC端预览或下载

[文件: Alibaba-PuHuiTi-Heavy.ttf] 请在PC端预览或下载

[文件: Alibaba-PuHuiTi-Light.ttf] 请在PC端预览或下载

[文件: Alibaba-PuHuiTi-Medium.ttf] 请在PC端预览或下载

[文件: Alibaba-PuHuiTi-Regular.ttf] 请在PC端预览或下载

  

相关文章
|
7天前
|
云安全 人工智能 运维
阿里云联动百位企业安全专家,共识Agent防御最佳实践
当Agent成为新员工,你的安全边界在哪里?
1922 6
阿里云联动百位企业安全专家,共识Agent防御最佳实践
|
5天前
|
存储 人工智能 关系型数据库
阿里云AI产品与云产品最新组合套餐:Token Plan、AI coding及云服务器和建站等组合优惠价
阿里云推出全新“算力+模型+应用”一站式云与AI组合套餐活动,覆盖从个人开发者到中大型企业的全场景需求。核心亮点为分三档定价的Token Plan订阅服务,支持Qwen3.8-Max-Preview大模型调用,错峰时段最低可享0.2折优惠。活动同步推出AI Coding、智能体部署、云电脑托管、0代码建站等十余类场景化组合,搭配99元/年的普惠云服务器、88元/年的入门数据库等经典特惠产品,还为企业提供1V1定制化AI转型方案,大幅降低了不同用户群体拥抱AI的技术门槛与采购成本。
652 111
|
15天前
|
人工智能 JSON 安全
Fastjson远程代码执行漏洞,阿里云AI安全为您保驾护航
阿里云AI安全产品联动防御Fastjson攻击
2556 13
Fastjson远程代码执行漏洞,阿里云AI安全为您保驾护航
|
7天前
|
人工智能 弹性计算 数据库
阿里云优惠券种类解析:主要券种区别和适用群体及领取和使用指南
2026年阿里云构建了覆盖全用户的七类优惠券,本文逐一拆解了每类优惠券的核心规则、适用人群与使用技巧:大促限定的阶梯满减券分个人、企业双通道,最高可减800元;学生专属300元无门槛券支持全品类通用;按量付费用户可参与消费达标返券形成循环优惠;新用户有低门槛专享满减券尝鲜;老用户可领取系统自动发放的随机福利券;中大型企业迁云可申请最高100万元的专项补贴;云产品通用券还能在活动价基础上实现折上折。不同身份、不同采购场景的用户均可通过精准匹配对应优惠券,最大化享受优惠力度。
462 110
阿里云优惠券种类解析:主要券种区别和适用群体及领取和使用指南
|
13天前
|
人工智能 前端开发 Linux
Codex 桌面版安装 + CC Switch 接入第三方 API 完整教程(2026 最新)
2026最新教程:手把手教你安装Codex桌面版,通过CC Switch v3.17.0一键接入Fenno等国产API(兼容OpenAI Responses格式),跳过账号登录,完整启用代码审查、多步任务与上下文感知功能。零基础友好,全程图文实操。(239字)
1623 2
|
15天前
|
人工智能 自然语言处理 数据挖掘
Qwen3.8-Max-Preview深度全解析:2.4万亿参数旗舰MoE模型+Token Plan限时优惠完整落地指南
2026年7月,全新旗舰级混合专家大模型Qwen3.8-Max-Preview正式开放抢先体验,作为通义千问Qwen3系列规格最高、综合推理能力顶尖的新一代模型,该模型总参数量达到2.4万亿(2.4T),是当前线上可调用的原生多模态旗舰模型,综合推理水准对标海外顶级Fable 5模型,在复杂工程开发、长文档深度分析、多步骤智能体自治、跨境多语言创作、海量数据挖掘五大高难度业务场景实现跨越式性能提升。
1428 2
|
17天前
|
人工智能
Qwen3.8抢先体验!正式版即将发布并开源!
千问Qwen3.8即将开源,参数达2.4T,进化速度以“天”计,实力媲美Fable 5。预览版Qwen3.8-Max已上线阿里Token Plan等平台,限时优惠:日间Credits低至1折,夜间更优,个人/团队版月付仅35元起!
1500 55
|
2天前
Qoder 一周年 × Qwen3.8-Max 正式上线,多重好礼限时领
8月3日,Qwen3.8-Max 正式上线Qoder,迎来Qoder一周年。新老用户可领800次免费调用,下单再赠2000次;夜间(22:00–08:00)调用5折;邀请好友双方得积分与调用额度。
250 0