记一次操作图片

有一次做个投票项目需要用到分享合成二维码图片。所以就用到了这个功能,记录下。

用到jar包如下

<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.6.6</version>
</dependency>
<dependency>
   <groupId>com.google.zxing</groupId>
   <artifactId>core</artifactId>
   <version>3.3.3</version>
</dependency>

代码如下

 

/**
     * 在背景图片上放一张图片和一个二维码和文字
     * content 二维码内容
     * title   标题
     * path  在背景上自定义的图片
     * start 2排文字的开始第一排
     * end   2排文字的开始第二排
     * exportUrl 导出文件的路径
     * background 背景图片
     */
    public static void drawString(String content, String title, String path, String start, String end,
                                    String exportUrl, String background) throws IOException {
        BufferedImage image = addWater(content,path, background);
        if(image==null){
            return null;
        }
        Graphics2D gd = image.createGraphics();
        // 3、设置对线段的锯齿状边缘处理
        gd.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        // 5、设置水印文字颜色
        gd.setColor(new Color(51,51,51));
        // 6、设置水印文字Font
        Font font=new Font("宋体", Font.ITALIC, 34);
        gd.setFont(font);
        FontMetrics fm = gd.getFontMetrics(font);
        //计算出文字在背景图上所占宽度
        int textWidth = fm.stringWidth(title);
        //获取包背景图的宽用于计算文字这样居中的间隔
        int width=image.getWidth();

        int widthX = (width - textWidth) / 2;
        // 8、第一参数->设置的内容,后面两个参数->文字在图片上的坐标位置(x,y)   注意这里的高500是因为我本地图片前面高占用了近500  按自己实际情况来顶
        int height=500;
        gd.drawString(title, widthX, height);
        font=new Font("宋体", Font.ITALIC, 30);
        gd.setFont(font);
        fm = gd.getFontMetrics(font);
        title="第一排:"+start;
        textWidth = fm.stringWidth(title);
        widthX = (width - textWidth) / 2;
        gd.drawString(title, widthX, height+60);
        title="第二排:"+end;
        gd.drawString(title, widthX, height+ 100);
        gd.dispose();
        ImageIO.write(image, "png",new File(exportUrl) );
    }


/***
 * 在一张背景图上添加二维码
 */
public static BufferedImage addWater(String content, String path, String background){
    try {
        // 读取原图片信息
        //得到文件
        File file = ResourceUtils.getFile(background);
        //文件转化为图片
        BufferedImage srcImg = ImageIO.read(file);
        //获取图片的宽
        int srcImgWidth = srcImg.getWidth(null);
        //获取图片的高
        int srcImgHeight = srcImg.getHeight(null);
        // 加上想要展示的图片
        BufferedImage bufImg = new BufferedImage(srcImgWidth, srcImgHeight, BufferedImage.TYPE_INT_RGB);
        Graphics2D g = bufImg.createGraphics();
        g.drawImage(srcImg, 0, 0, srcImgWidth, srcImgHeight, null);
        //贴上指定的展示图片
        BufferedImage img=ImageIO.read(new File(path));

        //需要再背景图上展示的图片宽高
        int width=570;
        int height=250;

        BufferedImage imgBuff = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics2D buff = imgBuff.createGraphics();
        buff.drawImage(img, 0, 0, width, height, null);
        img=makeRoundedCorner(imgBuff);
        //使用工具类生成二维码
        BufferedImage image = createQrCode(content,300,300);
        //将小图片绘到大图片上,500,300 .表示你的小图片在大图片上的位置。
        g.drawImage(img, 40, 170,null);
        g.drawImage(image, (srcImgWidth-300)/2, 630, null);
        //设置颜色。
        g.setColor(Color.WHITE);
        g.dispose();
        return bufImg;
    } catch (IOException e) {
        e.printStackTrace();
    }
    return null;
}


public static BufferedImage makeRoundedCorner(BufferedImage bi1) {
    try{
        // 根据需要是否使用 BufferedImage.TYPE_INT_ARGB
        BufferedImage image = new BufferedImage(bi1.getWidth(), bi1.getHeight(),
                BufferedImage.TYPE_INT_ARGB);

        Ellipse2D.Double shape = new Ellipse2D.Double(0, 0, bi1.getWidth(), bi1
                .getHeight());

        Graphics2D g2 = image.createGraphics();
        image = g2.getDeviceConfiguration().createCompatibleImage(bi1.getWidth(), bi1.getHeight(), Transparency.TRANSLUCENT);
        g2 = image.createGraphics();
        g2.setComposite(AlphaComposite.Clear);
        g2.fill(new Rectangle(image.getWidth(), image.getHeight()));
        g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC, 1.0f));
        g2.setClip(shape);
        // 使用 setRenderingHint 设置抗锯齿
        g2 = image.createGraphics();
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        //  40为倒圆角的值  按自己情况而定
        g2.fillRoundRect(0, 0,bi1.getWidth(), bi1.getHeight(), 40, 40);
        g2.setComposite(AlphaComposite.SrcIn);
        g2.drawImage(bi1, 0, 0, bi1.getWidth(), bi1.getHeight(), null);
        g2.dispose();
        return image;
    } catch (Exception e) {
        System.out.println(e.getMessage());
        return null;
    }
}

private static BufferedImage createQrCode(String content, int width, int height) throws IOException {
    QrConfig config = new QrConfig(width, height);
    config.setErrorCorrection(ErrorCorrectionLevel.H);
    return QrCodeUtil.generate(content,config);
}

 

效果

 

 

点赞

发表回复

电子邮件地址不会被公开。必填项已用 * 标注