zoukankan      html  css  js  c++  java
  • java画海报二维码

    package cn.com.yitong.ares.qrcode;

    import java.awt.BasicStroke;
    import java.awt.Color;
    import java.awt.Font;
    import java.awt.Graphics2D;
    import java.awt.RenderingHints;
    import java.awt.geom.RoundRectangle2D;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.IOException;
    import java.nio.file.Path;
    import java.util.HashMap;
    import java.util.Hashtable;

    import javax.imageio.ImageIO;

    import com.google.zxing.BarcodeFormat;
    import com.google.zxing.Binarizer;
    import com.google.zxing.BinaryBitmap;
    import com.google.zxing.EncodeHintType;
    import com.google.zxing.LuminanceSource;
    import com.google.zxing.MultiFormatReader;
    import com.google.zxing.MultiFormatWriter;
    import com.google.zxing.Result;
    import com.google.zxing.WriterException;
    import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
    import com.google.zxing.client.j2se.MatrixToImageWriter;
    import com.google.zxing.common.BitMatrix;
    import com.google.zxing.common.HybridBinarizer;
    import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;


    /**
    * 二维码的工具类
    * @author fyh
    *
    */

    public class ZXingUtil {
    //定义int类型的常量用于存放生成二维码时的类型
    private static final int BLACK = 0xFF000000;
    private static final int WHITE = 0xFFFFFFFF;

    /**
    * 加密:文字-->图片 将文本变成二维数组,
    * @param imagePath
    * @param format:文件格式及后缀名
    * @param content
    * @throws WriterException
    * @throws IOException
    */
    public static void encodeimage(String imagePath , String format , String content , int width , int height , String logo) throws WriterException, IOException{

    Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType , Object>();
    //容错率:L(7%)<M(15%)<Q(25%)<H(35%);H容错率最高
    hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
    //编码格式
    hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
    //外边距
    hints.put(EncodeHintType.MARGIN, 1);

    /***
    * BarcodeFormat.QR_CODE:解析什么类型的文件:要解析的二维码的类型
    * content:解析文件的内容
    * width:生成二维码的宽
    * height:生成二维码的高
    * hints:涉及到加密用到的参数: 即 编码 和容错率
    */
    BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height , hints);
    //使BufferedImage勾画QRCode (matrixWidth 是行二维码像素点)
    int matrixWidth = bitMatrix.getWidth();

    /**
    * 内存中的一张图片:是RenderedImage的子类,而RenderedImage是一个接口
    * 此时需要的图片是一个二维码-->需要一个boolean[][]数组存放二维码 --->Boolean数组是由BitMatrix产生的
    * BufferedImage.TYPE_INT_RGB : 表示生成图片的类型: 此处是RGB模式
    */
    BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    //生成二维数组
    for(int x=0;x<matrixWidth;x++){
    for(int y=0 ; y<matrixWidth;y++){
    //二维坐标整个区域:画什么颜色
    img.setRGB(x, y, bitMatrix.get(x, y) ? BLACK : WHITE);
    }
    }

    //画log
    img = logoImg(img, logo);

    //将二维码图片转换成文件
    File file = new File(imagePath);
    //生成图片
    ImageIO.write(img, format, file);

    }

    /**
    * 解密,将生成的二维码转换成文字
    * @param file:二维码文件
    * @throws Exception
    */
    public static String decodeImage(File file) throws Exception{

    //首先判断文件是否存在
    if(!file.exists()){
    return "";
    }
    //将file转换成内存中的一张图片
    BufferedImage image = ImageIO.read(file);
    MultiFormatReader formatter = new MultiFormatReader();
    LuminanceSource source = new BufferedImageLuminanceSource(image);
    Binarizer binarizer = new HybridBinarizer(source);
    BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);
    //将图片的文字信息解析到result中
    Result result = formatter.decode(binaryBitmap);
    System.out.println(result.getText());
    return result.getText();
    }

    /**
    * 传logo和二维码,生成-->带logo的二维码
    * @param matrixImage :二维码
    * @param logo : 中间的logo
    * @return
    * @throws IOException
    */
    public static BufferedImage logoImg(BufferedImage matrixImage ,String logo) throws IOException{
    //在二维码上画logo:产生一个二维码画板
    Graphics2D g2 = matrixImage.createGraphics();
    //画logo,将String类型的logo图片存放入内存中;即 string-->BufferedImage
    BufferedImage logoImage = ImageIO.read(new File(logo));
    //获取二维码的高和宽
    int height = matrixImage.getHeight();
    int width = matrixImage.getWidth();
    /**
    * 纯log图片
    * logoImage:内存中的图片
    * 在二维码的高和宽的2/5,2/5开始画log,logo占用整个二维码的高和宽的1/5,1/5
    */
    g2.drawImage(logoImage,width*2/5, height*2/5, width*1/5, height*1/5, null);

    /**
    * 画白色的外边框
    * 产生一个画白色圆角正方形的画笔
    * BasicStroke.CAP_ROUND:画笔的圆滑程度,此处设置为圆滑
    * BasicStroke.JOIN_ROUND:在边与边的连接点的圆滑程度,此处设置为圆滑
    */
    BasicStroke stroke = new BasicStroke(5,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND);
    //将画板和画笔关联起来
    g2.setStroke(stroke);

    /**
    * 画一个正方形
    * RoundRectangle2D是一个画长方形的类,folat是他的内部类
    */
    RoundRectangle2D.Float round = new RoundRectangle2D.Float(width*2/5, height*2/5, width*1/5, height*1/5,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND);
    //设置为画白色
    g2.setColor(Color.WHITE);
    g2.draw(round);

    //画灰色的内边框,原理与画白色边框相同
    BasicStroke stroke2 = new BasicStroke(1,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND);
    g2.setStroke(stroke2);

    RoundRectangle2D.Float round2 = new RoundRectangle2D.Float(width*2/5+2, height*2/5+2, width*1/5-4, height*1/5-4,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND);
    //另一种设置灰色的方法:Color color = new Color(128,128,128);其中三个参数是 R G B
    g2.setColor(Color.GRAY);
    g2.draw(round2);

    //释放内存
    g2.dispose();
    //刷新二维码
    matrixImage.flush();
    return matrixImage;
    }
    /**
    * 没有logo
    *
    * @param content 文字→二维码
    * @param path 二维码图片储存位置
    * @param format
    * @param height2
    * @param width2
    * @return
    */
    @SuppressWarnings("unused")
    static
    boolean orCode(String content, String path, int width, int height, String format) {
    /*
    * 图片的宽度和高度
    */
    // int width = 100;
    // int height = 100;
    // // 图片的格式
    // String format = "png";
    // 定义二维码的参数
    HashMap<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>();
    // 定义字符集编码格式
    hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
    // 纠错的等级 L > M > Q > H 纠错的能力越高可存储的越少,一般使用M
    hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
    // 设置图片边距
    hints.put(EncodeHintType.MARGIN, 1);

    try {
    // 最终生成 参数列表 (1.内容 2.格式 3.宽度 4.高度 5.二维码参数)
    BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints);
    // 写入到本地
    int matrixWidth = bitMatrix.getWidth();

    /**
    * 内存中的一张图片:是RenderedImage的子类,而RenderedImage是一个接口
    * 此时需要的图片是一个二维码-->需要一个boolean[][]数组存放二维码 --->Boolean数组是由BitMatrix产生的
    * BufferedImage.TYPE_INT_RGB : 表示生成图片的类型: 此处是RGB模式
    */
    BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    //生成二维数组
    for(int x=0;x<matrixWidth;x++){
    for(int y=0 ; y<matrixWidth;y++){
    //二维坐标整个区域:画什么颜色
    img.setRGB(x, y, bitMatrix.get(x, y) ? BLACK : WHITE);
    }
    }
    // Path file = new File(path).toPath();
    // MatrixToImageWriter.writeToPath(bitMatrix, format, file);
    File file = new File(path);
    //生成图片
    ImageIO.write(img, format, file);
    return true;
    } catch (Exception e) {
    e.printStackTrace();
    return false;
    }

    }
    public static BufferedImage compositePicature(String beijingPath,String imagePath,String finalImagePath,String format) {

    int fontSize=13;
    //在背景里画二维码,将String类型的图片存放入内存中;即 string-->BufferedImage
    BufferedImage beijingImage = null;
    try {
    beijingImage = ImageIO.read(new File(beijingPath));

    BufferedImage logoImage = ImageIO.read(new File(imagePath)); //100*100
    //获取二维码的高和宽
    int height = logoImage.getHeight();
    int width = logoImage.getWidth();
    /**
    * 获取背景图的高和宽
    */
    int height2 = beijingImage.getHeight();
    int width2 = beijingImage.getWidth();
    Graphics2D g = beijingImage.createGraphics();
    g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    g.drawImage(logoImage, width2-width-30, height2-height-30, width, height, null);

    // 消除文字锯齿
    // g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
    // 在背景添加二维码图片(地址,左边距,上边距,图片宽度,图片高度,未知)
    // Font font1 = new Font("微软雅黑", Font.BOLD, fontSize);// 添加字体的属性设置
    // g.setFont(font1);
    // Color color1 = new Color(100,0,0);
    // g.drawString("扫码了解详情",width2-width+5, height2-10);
    // g.drawString("扫码了解详情",width2-width+5, height2-10);
    // g.setColor(color1);
    // 抗锯齿
    Font font = new Font("微软雅黑", Font.BOLD, 13);
    g.setFont(font);
    g.setPaint(new Color(0, 0, 0, 64));
    // 先绘制一遍底色
    g.drawString("扫码了解详情", width2-width-20, height2-10);
    g.setPaint(new Color(100,0,0));
    // 再绘制一遍文字
    // 由于部分情况会出现文字模糊的情况,保险起见才出此对策。
    g.drawString("扫码了解详情", width2-width-20, height2-10);
    g.dispose();
    //将二维码图片转换成文件
    File file = new File(finalImagePath);
    //生成图片
    ImageIO.write(beijingImage, format, file);
    } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    } // 335*459
    return beijingImage;

    }

    }

    package cn.com.yitong.ares.qrcode;
    import java.awt.image.BufferedImage;
    import java.io.IOException;

    import com.google.zxing.WriterException;

    import cn.com.yitong.ares.qrcode.ZXingUtil;
    import cn.com.yitong.ares.test2.IGraphics2D;
    public class ZXingQR_code {
    /**
    * 生成二维码(带内嵌的logo)
    * @param imagePath
    * @param format
    * @param content
    * @param width
    * @param height
    * @param logopath
    */
    public void drawWord(String imagePath, String format, String content,int width, int height,String logopath) {
    try {
    ZXingUtil.encodeimage(imagePath, "JPEG", content, 100, 100 , logopath);
    } catch (WriterException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }
    /**
    * 1.生成二维码 (不带logo)
    * 2. 合并图片 二维码图片和海报图片
    * @param beijingPath
    * @param logoPath
    * @param imagePath
    * @param format
    * @param content
    */
    public void compositionDrawWord(String url,String imagePath,String beijingPath,String finalImagePath, int width, int height, String format) {
    try {
    if (ZXingUtil.orCode(url, imagePath, width, height,format)) {
    System.out.println("ok,成功");
    BufferedImage image=ZXingUtil.compositePicature(beijingPath, imagePath, finalImagePath, format);
    } else {
    System.out.println("no,失败");
    }

    } catch (Exception e) {
    // TODO: handle exception
    }

    }
    public static void main(String[] args) throws Exception {
    /**
    * 生成二维码(带内嵌的logo)
    * 加密:将文字其他东西放在图片里面
    * 解密:反之
    */
    //1.此处要根据用户id+产品类型海报+ 命名图片名称
    //2.图片存在哪里呢?
    // String imagePath = "src/main/resources/webapp1.jpg";
    // String logo = "src/main/resources/smartLogo.png";
    // String content = "https://blog.csdn.net/q15102780705/article/details/100060137";
    // // String content = "https://www.baidu.com.cn";
    // ZXingUtil.encodeimage(imagePath, "JPEG", content, 100, 100 , logo);

    int width = 100;
    int height = 100;
    String url = "https://www.baidu.com.cn?谁是世界上最美的人";
    String imagePath="src/main/resources/imagePath.png";
    String beijingPath="src/main/resources/beijing.png";
    String finalImagePath="src/main/resources/finalImagePath.png";
    String format="png";

    /**
    * 1.生成二维码 (不带logo)
    * 2. 合并图片 二维码图片和海报图片
    */
    // 传参:二维码内容和生成路径
    if (ZXingUtil.orCode(url, imagePath, width, height,format)) {
    System.out.println("ok,成功");

    BufferedImage image=ZXingUtil.compositePicature(beijingPath, imagePath, finalImagePath, format);
    } else {
    System.out.println("no,失败");
    }


    /**
    * 解密 -->将二维码内部的文字显示出来
    */
    // ZXingUtil.decodeImage(new File(imagePath));

    }
    }

    Java画图 给图片底部添加文字标题

    import java.awt.Color;
    import java.awt.Font;
    import java.awt.Graphics2D;
    import java.awt.Image;
    import java.awt.RenderingHints;
    import java.awt.font.FontRenderContext;
    import java.awt.geom.Rectangle2D;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.IOException;
    
    import javax.imageio.ImageIO;
    
    /**
     * JAVA 画图(生成文字水印)
     * 
     * @author 杰宝宝
     * 
     */
    public class ImageUtil {
    
        /**
         * @param str
         *            生产的图片文字
         * @param oldPath
         *            原图片保存路径
         * @param newPath
         *            新图片保存路径
         * @param width
         *            定义生成图片宽度
         * @param height
         *            定义生成图片高度
         * @return
         * @throws IOException
         */
        public void create(String str, String oldPath, String newPath, int width, int height){
            try {
                File oldFile = new File(oldPath);
                Image image = ImageIO.read(oldFile);
    
                File file = new File(newPath);
                BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
                Graphics2D g2 = bi.createGraphics();
                g2.setBackground(Color.WHITE);
                g2.clearRect(0, 0, width, height);
                g2.drawImage(image, 0, 0, width - 25, height - 25, null); //这里减去25是为了防止字和图重合
                /** 设置生成图片的文字样式 * */
                Font font = new Font("黑体", Font.BOLD, 25);
                g2.setFont(font);
                g2.setPaint(Color.BLACK);
    
                /** 设置字体在图片中的位置 在这里是居中* */
                FontRenderContext context = g2.getFontRenderContext();
                Rectangle2D bounds = font.getStringBounds(str, context);
                double x = (width - bounds.getWidth()) / 2;
                //double y = (height - bounds.getHeight()) / 2; //Y轴居中
                double y = (height - bounds.getHeight());
                double ascent = -bounds.getY();
                double baseY = y + ascent;
    
                /** 防止生成的文字带有锯齿 * */
                g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
    
                /** 在图片上生成文字 * */
                g2.drawString(str, (int) x, (int) baseY);
    
                ImageIO.write(bi, "jpg", file);
            } catch (IOException e) {
                e.printStackTrace();
            } 
        }
    
        public static void main(String[] args) {
        
            try {
                ImageUtil img = new ImageUtil();
                img.create("编号:0011", "E:\111.png", "E:\222.png", 455, 455);
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
  • 相关阅读:
    IO 单个文件的多线程拷贝
    day30 进程 同步 异步 阻塞 非阻塞 并发 并行 创建进程 守护进程 僵尸进程与孤儿进程 互斥锁
    day31 进程间通讯,线程
    d29天 上传电影练习 UDP使用 ScketServer模块
    d28 scoket套接字 struct模块
    d27网络编程
    d24 反射,元类
    d23 多态,oop中常用的内置函数 类中常用内置函数
    d22 封装 property装饰器 接口 抽象类 鸭子类型
    d21天 继承
  • 原文地址:https://www.cnblogs.com/jishumonkey/p/13261574.html
Copyright © 2011-2022 走看看