二维码在我们目前的生活工作中,随处可见,日常开发中难免会遇到需要生成二维码的场景,网上也有很多开源的平台可以使用,不过这里我们可以通过几个开源组件,自己来实现一下。

在动手之前我们先思考一下需要进行的操作,首先我们需要生成一个二维码,其次我们需要在这里二维码中间添加一个头像。

这里我们生成二维码使用工具 zxing,合成图片我们采用 thumbnailator,接下来我们实操一下吧。

生成二维码

首先我们先根据目标地址,生成一个二维码,这里我们使用的是组件 zxing,在 SpringBootpom依赖中,我们加入下面的依赖。

<dependency>  <groupId>com.google.zxing</groupId>  <artifactId>core</artifactId>  <version>3.4.0</version></dependency><dependency>  <groupId>com.google.zxing</groupId>  <artifactId>javase</artifactId>  <version>3.4.0</version></dependency>

然后编写工具类 QRCodeGenerator.java

import com.google.zxing.BarcodeFormat;import com.google.zxing.EncodeHintType;import com.google.zxing.MultiFormatWriter;import com.google.zxing.WriterException;import com.google.zxing.client.j2se.MatrixToImageWriter;import com.google.zxing.common.BitMatrix;

import java.io.IOException;import java.nio.file.FileSystems;import java.nio.file.Path;import java.util.HashMap;

public class QRCodeGenerator {

  /**   * 根据内容,大小生成二维码到指定路径   *   * @param contents 跳转的链接   * @param width    宽度   * @param height   高度   * @param filePath 路径   * @throws WriterException   * @throws IOException   */  public static void generateQrWithImage(String contents, int width, int height, String filePath) throws WriterException, IOException {    //构造二维码写码器    MultiFormatWriter mutiWriter = new com.google.zxing.MultiFormatWriter();    HashMap<EncodeHintType, Object> hint = new HashMap<>(16);    hint.put(EncodeHintType.CHARACTER_SET, "UTF-8");    hint.put(EncodeHintType.ERROR_CORRECTION, com.google.zxing.qrcode.decoder.ErrorCorrectionLevel.H);    hint.put(EncodeHintType.MARGIN, 1);    //生成二维码    BitMatrix bitMatrix = mutiWriter.encode(contents, BarcodeFormat.QR_CODE, width, height, hint);    Path path = FileSystems.getDefault().getPath(filePath);    MatrixToImageWriter.writeToPath(bitMatrix, "jpeg", path);  }}

这个静态方法有四个参数,分别是:

  1. 跳转的链接内容;
  2. 二维码的宽度;
  3. 二维码的高度;
  4. 生成的二维码后的存放路径;

代码中还有几个常量,EncodeHintType.CHARACTER_SET:表示编码;EncodeHintType.ERROR_CORRECTION 表示二维码的容错率;EncodeHintType.MARGIN 表示二维码的边框。

解释一下什么是二维码的容错率,大家在日常生活或者工作中应该会发现,有些二维码轻轻一扫就扫成功了,有的二维码却很难扫成功,这背后就是二维码的容错率的原因(对,有时候并不是你的网络问题!)。

不同密度的二维码所包含的信息其编码的字符、容错率均不同。密度越低,编码的字符个数越少、容错率越低,二维码容错率表示二维码图标被遮挡多少后,仍可以被扫描出来的能力。目前,典型的二维码的容错率分为 7%、15%、25%、30% 四个等级,容错率越高,越容易被快速扫描。“但是,容错率越高,二维码里面的黑白格子也就越多。因此,对于目前主流手机,在绝大多数扫描场景下,仍普遍应用 7% 容错率的二维码就能满足需求。

感兴趣的小伙伴也可以自己尝试几个不同的容错率,看看扫码的难度有没有变化。

接下来,我们编写一个 main 方法来生成一个二维码

public static void main(String[] args) {    try {      QRCodeGenerator.generateQrWithImage("https://mp.weixin.qq.com/mp/profile_ext?action=home&__biz=MzkzODE3OTI0Ng==&scene=124#wechat_redirect", 500, 500, "./QRCode.jpeg");    } catch (Exception e) {    }  }

运行完上面的 main 方法,我们可以得到一个二维码,到这里我们第一步已经完成了,接下来就是给这个二维码加上我们的头像。

添加头像

添加头像我们需要准备一个头像的照片,阿粉这里就用阿粉的头像了,如果这里有现成大小的头像就直接拿来使用就行,如果没有也没有关系,我们可以自己裁剪,这里我们就需要用来图片处理工具 thumbnailator 了。

先将头像处理成 100 x 100 的大小,然后再合成上去就行,代码如下:

public static void main(String[] args) {    try {      // 将大图片缩小到指定大小//    ThumbnailsImageUtils.size("./阿粉.jpeg", 100, 100, 1, "./阿粉100.png");      // 通过水印的形式,将头像加到生成的二维码上面      ThumbnailsImageUtils.watermark("./QRCode.jpeg",      500, 500, Positions.CENTER, "./阿粉100.png",        1f, 1f, "./result.png");    } catch (Exception e) {    }  }

这个就是最终生成的带头像的二维码啦,友情提示,扫码可以看到更多优质文章。

通过上面的代码可以看到,ThumbnailsImageUtils 是真的很多强大,一行代码就能搞定图片缩小和图片合成,更多关于 ThumbnailsImageUtils 工具类的完整代码如下,赶紧收藏起来。

import net.coobird.thumbnailator.Thumbnails;import net.coobird.thumbnailator.geometry.Positions;import org.slf4j.Logger;import org.slf4j.LoggerFactory;

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

/** * <br> * <b>功能:</b><br> * <b>作者:</b>@author ziyou<br> * <b>日期:</b>2018-05-25 16:17<br> * <b>详细说明:</b>使用google开源工具Thumbnailator实现图片的一系列处理<br> */public class ThumbnailsImageUtils {

    private final static Logger logger = LoggerFactory.getLogger(ThumbnailsImageUtils.class);

    /**     * 将原图根据指定大小生产新图     *     * @param sourceFilePath 原始图片路径     * @param width          指定图片宽度     * @param height         指定图片高度     * @param targetFilePath 目标图片路径     * @return 目标图片路径     * @throws IOException     */    public static String thumb(String sourceFilePath, Integer width, Integer height, String targetFilePath) throws IOException {        Thumbnails.of(sourceFilePath)                .forceSize(width, height)                .toFile(targetFilePath);        return targetFilePath;    }

    /**     * 按照比例进行缩放     *     * @param sourceFilePath 原始图片路径     * @param scale          scale(比例)     * @param targetFilePath 目标图片路径     * @return 目标图片路径     * @throws IOException     */    public static String scale(String sourceFilePath, Double scale, String targetFilePath) throws IOException {        Thumbnails.of(sourceFilePath)                .scale(scale)                .toFile(targetFilePath);        return targetFilePath;    }

    /**     * 不按照比例,指定大小进行缩放     *     * @param sourceFilePath 原始图片路径     * @param width          指定图片宽度     * @param height         指定图片高度     * @param targetFilePath 目标图片路径     *                       keepAspectRatio(false) 默认是按照比例缩放的     * @return 目标图片路径     * @throws IOException     */    public static String size(String sourceFilePath, Integer width, Integer height, float quality, String targetFilePath) throws IOException {        Thumbnails.of(sourceFilePath)                .size(width, height)                .outputQuality(quality)                .keepAspectRatio(false)                .toFile(targetFilePath);        return targetFilePath;    }

    /**     * 指定大小和角度旋转     *     * @param sourceFilePath 原始图片路径     * @param width          指定图片宽度     * @param height         指定图片高度     * @param rotate         rotate(角度),正数:顺时针 负数:逆时针     * @param targetFilePath 目标图片路径     * @return 目标图片路径     * @throws IOException     */    public static String rotate(String sourceFilePath, Integer width, Integer height, Double rotate, String targetFilePath) throws IOException {        Thumbnails.of(sourceFilePath)                .size(width, height)                .rotate(rotate)                .toFile(targetFilePath);        return targetFilePath;    }

    /**     * 指定角度旋转     *     * @param sourceFilePath 原始图片路径     * @param rotate         rotate(角度),正数:顺时针 负数:逆时针     * @param targetFilePath 目标图片路径     * @return 目标图片路径     * @throws IOException     */    public static String rotate(String sourceFilePath, Double rotate, String targetFilePath) throws IOException {        Thumbnails.of(sourceFilePath)                .rotate(rotate)                .toFile(targetFilePath);        return targetFilePath;    }

    /**     * @param sourceFilePath 原始图片路径     * @param width          指定图片宽度     * @param height         指定图片高度     * @param position       水印位置     * @param waterFile      水印文件     * @param opacity        水印透明度     * @param quality        输出文件的质量     * @param targetFilePath 目标图片路径     * @return 目标图片路径     * @throws IOException     */    public static String watermark(String sourceFilePath, Integer width, Integer height, Positions position, String waterFile, float opacity, float quality, String targetFilePath) throws IOException {        Thumbnails.of(sourceFilePath)                .size(width, height)                .watermark(position, ImageIO.read(new File(waterFile)), opacity)                .outputQuality(quality)                .toFile(targetFilePath);        return targetFilePath;    }

    public static BufferedImage watermarkList(BufferedImage buffImg, int length, File[] waterFileArray) throws IOException {        int x = 0;        int y = 0;        if (buffImg == null) {            // 获取底图            buffImg = new BufferedImage(1200, 1200, BufferedImage.SCALE_SMOOTH);        } else {            x = (length % 30) * 40;            y = (length / 30) * 40;        }        // 创建Graphics2D对象,用在底图对象上绘图        Graphics2D g2d = buffImg.createGraphics();        // 将图像填充为白色        g2d.setColor(Color.WHITE);        g2d.fillRect(x, y, 1200, 40 * (waterFileArray.length + length));        for (int i = 0; i < waterFileArray.length; i++) {            // 获取层图            BufferedImage waterImg = ImageIO.read(waterFileArray[i]);            // 获取层图的宽度            int waterImgWidth = waterImg.getWidth();            // 获取层图的高度            int waterImgHeight = waterImg.getHeight();            // 在图形和图像中实现混合和透明效果            g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 1));            // 绘制            Integer j = i / 30;            Integer index = i - j * 30;            g2d.drawImage(waterImg, waterImgWidth * index + 1, waterImgHeight * j, waterImgWidth, waterImgHeight, null);

        }

        // 释放图形上下文使用的系统资源        g2d.dispose();        return buffImg;    }

    /**     * @param sourceFilePath 原始图片路径     * @param waterFile      水印文件     * @param targetFilePath 目标图片路径     *                       透明度默认值0.5f,质量默认0.8f     * @return 目标图片路径     * @throws IOException     */    public static String watermark(String sourceFilePath, String waterFile, String targetFilePath) throws IOException {        Image image = ImageIO.read(new File(waterFile));        Integer width = image.getWidth(null);        Integer height = image.getHeight(null);        return watermark(sourceFilePath, width, height,                Positions.BOTTOM_RIGHT, waterFile, 0.5f, 0.8f, targetFilePath);    }

    /**     * 将图片转化为指定大小和格式的图片     *     * @param sourceFilePath     * @param width     * @param height     * @param format     * @param targetFilePath     * @return     * @throws IOException     */    public static String changeFormat(String sourceFilePath, Integer width, Integer height, String format, String targetFilePath) throws IOException {        Thumbnails.of(sourceFilePath)                .size(width, height)                .outputQuality(0.8f)                .outputFormat(format)                .toFile(targetFilePath);        return targetFilePath;    }

    /**     * 根据原大小转化指定格式     *     * @param sourceFilePath     * @param format     * @param targetFilePath     * @return     * @throws IOException     */    public static String changeFormat(String sourceFilePath, String format, String targetFilePath) throws IOException {        Image image = ImageIO.read(new File(sourceFilePath));        Integer width = image.getWidth(null);        Integer height = image.getHeight(null);        Thumbnails.of(sourceFilePath)                .size(width, height)                .outputFormat(format)                .toFile(targetFilePath);        return targetFilePath;    }

    /**     * 输出到输出流     *     * @param sourceFilePath     * @param targetFilePath     * @return     * @throws IOException     */    public static String toOutputStream(String sourceFilePath, String targetFilePath) throws IOException {        OutputStream os = new FileOutputStream(targetFilePath);        Thumbnails.of(sourceFilePath).toOutputStream(os);        return targetFilePath;    }

    /**     * 输出到BufferedImage     *     * @param sourceFilePath     * @param format     * @param targetFilePath     * @return     * @throws IOException     */    public static String asBufferedImage(String sourceFilePath, String format, String targetFilePath) throws IOException {        /**         * asBufferedImage() 返回BufferedImage         */        BufferedImage thumbnail = Thumbnails.of(sourceFilePath).size(1280, 1024).asBufferedImage();        ImageIO.write(thumbnail, format, new File(targetFilePath));        return targetFilePath;    }}

总结

今天阿粉通过两个组件带大家实践了一个二维码的生成和图片的合成,这两个技巧在工作中难免会使用到,赶紧保存使用起来吧。

来源:https://mp.weixin.qq.com/s/--CPn6KIYgp1uakAqgAkDQ

Java 代码基于开源组件生成带头像的二维码相关推荐

  1. Java 代码基于开源组件生成带头像的二维码,推荐收藏

    二维码在我们目前的生活工作中,随处可见,日常开发中难免会遇到需要生成二维码的场景,网上也有很多开源的平台可以使用,不过这里我们可以通过几个开源组件,自己来实现一下. 在动手之前我们先思考一下需要进行的 ...

  2. asp生成带参数的二维码并合成推广海报图片,asp合并合成推广海报图片asp代码

    最近做的一个项目中,客户要求用asp生成二维码,然后合并到一张背景图片上,合并生成一张推广海报来,可把我愁坏了,经过一个晚上的努力,成功了,下面把这个:asp生成带参数的二维码并合成推广海报,asp合 ...

  3. asp生成带参数的二维码并合成推广海报图片,asp合并合成推广海报图片asp代码...

    最近做的一个项目中,客户要求用asp生成二维码,然后合并到一张背景图片上,合并生成一张推广海报来,可把我愁坏了,经过一个晚上的努力,成功了,下面把这个:asp生成带参数的二维码并合成推广海报,asp合 ...

  4. jQuery生成带Logo的二维码

    用zxing生成二维码并解析:https://blog.csdn.net/qq_41879385/article/details/81320723 用QR Code生成和解析二维码文章地址:https ...

  5. zxing生成带logo的二维码

    倒Zxing依赖 implementation 'cn.bingoogolapple:bga-qrcode-zxing:1.2.1' 代码段 import android.graphics.Bitma ...

  6. 使用zxing生成带logo的二维码图片,自动调节logo图片相对二维码图片的大小

    使用zxing生成带logo的二维码图片,自动调节logo图片相对二维码图片的大小  * 可选是否带logo,可选是否保存二维码图片:结果返回base64编码的图片数据字符串  * 页面显示:< ...

  7. vue 生成带logo的二维码 qrcode-vue 支持下载图片 实例详解

    最近的项目上有个需求,生成带logo的二维码,网上大部分都是基于JQ插件jQuery.qrcode.对于vue项目并不适用,翻阅了大量资料后,我找到了qrcode-vue这款基于vue的生成二维码的插 ...

  8. Golang使用qrcode生成二维码,以及生成带logo的二维码

    添加并引用依赖 go get github.com/boombuler/barcodeimport ("github.com/skip2/go-qrcode" ) 1.生成字节形式 ...

  9. 微信公众号怎么生成带参数的二维码?

    每位运营过微信公众平台的野生小编都知道,微信提供给开发者的文档是很高深的,最近为了弄个带参数的二维码,同样技术小白的小编也死了不少脑细胞了,然而我终于知道官方生成带参数的二维码的方法了. 1.注意事项 ...

最新文章

  1. 12- Library at ROM
  2. 深度系统如何安装mysql_deepin 安装mysql apache
  3. 前端开发 容器标签 0226
  4. js 正则 正确的书写逻辑 中 德文小数点区别
  5. php学习笔记---php调试和开发工具整理
  6. python日志分割(转)
  7. 动态规划算法经典例题_c动态规划精简例题
  8. Atitit 软件开发方法论 attilax著 艾龙 著 1. 1.3 软件工程方法 软件工程方法论分为软件开发方法论和软件组织方法论两个部分。 1 2. 软件开发方法的演进  SP DOP PAM
  9. chrom浏览器配置,把跨域保护关闭
  10. 如何把静态成员导出_dll导入导出及local vftable问题
  11. php数组教程,PHP 数组入门教程小结
  12. 尚德机构季报图解:精细化运营降本增效 净利达1.15亿
  13. QIIME2教程. 03老司机上路指南Experience(2020.11)
  14. 如何通过Java下载远程文件到浏览器
  15. 【011】疫苗接种管理系统
  16. Anchor-based 与 Anchor-free
  17. 雷神笔记本做java,详细爆料雷神911Air星战三代 15.6寸笔记本好不好用?怎么样呢?大神吐槽真心话...
  18. python人工智能计算器_python游戏dnf_招募:基于python的召唤师全时段全技能(含均值AI)计算器全程测试......
  19. html5中拦截url,puppeteer 拦截页面请求
  20. 苹果手机自带软件删除了怎么恢复_手机照片删除了怎么恢复?莫慌,这才是正确恢复方法!_...

热门文章

  1. linux下鼠标主题以及gtk主题,图标主题,字体的设置
  2. ESP8266-Arduino编程实例-QRE1113红外反射传感器
  3. C#,图像二值化(04)——全局阈值的凯勒算法(Kittler Thresholding)及源程序
  4. UBUNTU使用硬解高清视频
  5. 如何关闭或开启隧道适配器
  6. Office 2003轻松安装
  7. 【电赛合集】19电磁炮.zip、17板球.zip、15风力摆.zip、13倒立摆.zip、(1994-2021)全国大学生电子设计竞赛历年真题.zip
  8. 一、Glade-3安装配置
  9. electron-vue 软件自动更新
  10. 北大青鸟消防设备类型编码_北大青鸟JBF4372E编码型火灾声光警报器