前言

Github:https://github.com/HealerJean

博客:http://blog.healerjean.com

项目中用到了生成二维码以及通过二维码制作为推广图片,如下,(用到了log,将logo放到了二维码中间)二维码和推广图片

duodianyouhuilogo

二维码

e78f92e5-4891-46bb-bb5a-0c21c19b6603

推广图片

WXfdsafasdfadsf

好了不废话了,开始制作,首先我们是要下载这个图片的


主要学习:BufferedImage

//整体图合成
BufferedImage bufferedImage = new BufferedImage(lovelyImageWidth, lovelyImageHeight, BufferedImage.TYPE_INT_RGB);
//设置图片的背景色
Graphics2D main = bufferedImage.createGraphics();
main.fillRect(0, 0, lovelyImageWidth, lovelyImageHeight);

制作好的图片写入输出流
ImageIO.write(bufferedImage, "jpg", response.getOutputStream());


网络图片获取
URL u = new URL(couponExpireChange.getImgUrl());
BufferedImage imageQR = ImageIO.read(u);

为文件中写入
FileOutputStream outputStreamContactmanager = new FileOutputStream(contactmanager);
URL ucontactmanager = new URL("http://image.dangqugame.cn/admin/webproject/contactmanager.jpg");
BufferedImage imageContactmanager = ImageIO.read(ucontactmanager);
ImageIO.write(imageContactmanager, "jpg", outputStreamContactmanager);
            

1、controlelr



@ApiOperation(value = "下载优惠券二维码",notes = "下载优惠券二维码",
        consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
@ApiImplicitParams({
        @ApiImplicitParam(name="couponItemGoodId",value = "优惠券商品主键Id",required =  true,dataTypeClass = Long.class,paramType = "query")

})
@GetMapping("downQcode")
public void downQcode(Long couponItemGoodId,HttpServletRequest request, HttpServletResponse response){
    log.debug("the imageName is : "+couponItemGoodId);
        //设置文件路径
            response.setContentType("application/force-download");// 设置强制下载不打开
            response.addHeader("Content-Disposition", "attachment;fileName="+UUIDGenerator.generate() +"jpg");// 设置文件名
            qrCodeService.downLoadErWeiMa(response,couponItemGoodId);


}

2、service中开始

    /**
     * 优惠券商品二维码制作输出流
     * @param response
     * @param couponItemGoodId
     * @return
     */
    public OutputStream downLoadErWeiMa(HttpServletResponse response, Long couponItemGoodId){

        if(couponItemGoodId==null){
            throw  new AppException("couponItemGoodId为空");
        }
        CouponItemGood couponItemGood = couponItemGoodRepository.findOne(couponItemGoodId);
        CouponItemGood couponItemGoodFinal = couponItemGood;
        if(couponItemGood==null){
            throw  new AppException("couponItemGoodId未找到对应主键的优惠券商品");
        }

        //我们后台自动匹配生成的,以及 失效后没有匹配的
        if(couponItemGood.getConnectParentItemGoodId()!=null||(couponItemGood.getStatus().compareTo(EnumValid.无效.status)==0&&couponItemGood.getConnectItemGoodId()==null)){
            throw new AppException("该优惠券无效或找不到匹配的优惠券");
        }


        //未进入转链接的进入转链接
        CouponExpireChange  couponExpireChange = null ;
        if(couponItemGood.getQCodeIs().compareTo(EnumQcodeUse.未使用.status)==0){
            changeLinkService.addCouponExpireChange(Long.valueOf(couponItemGoodId));
        }else {//已经在使用了
            if(couponItemGood.getConnectParentItemGoodId()!=null){
                couponExpireChange = couponExpireChangeRepository.findByPastItemGoodId(couponItemGood.getConnectParentItemGoodId());
                couponItemGoodFinal = couponItemGoodRepository.findOne(couponItemGood.getConnectParentItemGoodId());
            }else{
                couponExpireChange = couponExpireChangeRepository.findByPastItemGoodId(couponItemGoodId);
            }
        }

        WechatUrl wechatUrl = wechatUrlRepository.findByStatusIs(EnumValid.有效.status);
        OutputStream outputStream =null;
        if(couponExpireChange!=null){ //已经是二维码了
            try {
                //需要添加的图片(二维码中间的图片必须有)


                URL u = new URL(couponExpireChange.getImgUrl());
                BufferedImage imageQR = ImageIO.read(u);

                //需要添加的图片
//                String imageQRUrl = "/Users/healerjean/Desktop/images/itemgood.jpeg";
//                FileInputStream inputStream = new FileInputStream(imageQRUrl);
//                BufferedImage imageQR = ImageIO.read(inputStream);


                BufferedImage  ErWeiMaImage = QRCodeUtils.writeQRImg(response,wechatUrl.getUrl()+couponExpireChange.getPastItemGoodId(), WeChatMessageParams.WECHAT_DUODIANYOUHUI_LOGO);

                 String titleLab = "包邮";
                 String title = couponItemGoodFinal.getTitle();
                 BigDecimal originPrice = couponItemGoodFinal.getOriginPrice();
                 BigDecimal  nowPrice  =couponItemGoodFinal.getNowPrice();
                 BigDecimal couponPrice =couponItemGoodFinal.getCouponPrice();

                String description = couponItemGoodFinal.getItemDescription();


                BufferedImage bufferedImage =ChartGraphics. graphicsGenerationlovely(imageQR, ErWeiMaImage,titleLab,title,originPrice,nowPrice,couponPrice,description);


                ImageIO.write(bufferedImage, "jpg", response.getOutputStream());

                return  outputStream;

                //获取二维码图片,下面开始整合资源

            } catch (Exception e) {
                log.info(e.getMessage());
            }
        }


        return  outputStream;
    }

2.1、生成二维码

package com.duodian.youhui.admin.utils.qCode;

import com.google.zxing.*;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import org.springframework.web.bind.annotation.RequestAttribute;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.OutputStream;
import java.util.Hashtable;
import java.util.UUID;

public class QRCodeUtils {

    // 二维码宽度
    private static Integer WIDTH_PIX = 300;

    // 二维码高度
    private static Integer HEIGHT_PIX = 300;

    // 生成文件类型
    private static String TYPE = "jpg";

    // 编码格式
    private static String CHAR_TYPE = "UTF-8";

    /** 二维码填充颜色 BEGIN*/
    // 黑色
    private static Integer COLOR_BLACK = 0XFF000000;
    // 白色 0xFF是补码
    private static Integer COLOR_WHITE = 0XFFFFFFFF;
    /** 二维码填充颜色 END*/

    /**字体设定 BEGIN*/
    //设定写在二维码上的字体 样式
    private static String FONT_NAME = "Consolas";

    //字体颜色
    private static Color FONT_COLOR =  Color.gray;

    //字体 大小
    private static Integer FONT_SIZE =12;
    /**字体设定 END*/


    /**
     * 通过BufferedImage 来写入图片的操作,没有用到Google 的j2se包
     *
     * @param text
     *            写入的信息
     *            输出的文件地址
     * @return
     * @throws Exception
     */
    public static BufferedImage writeQRImg(HttpServletResponse response,String text, String... logoPath) throws Exception {
        // 配置参数
        Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
        // 字符编码
        hints.put(EncodeHintType.CHARACTER_SET, CHAR_TYPE);

        // 容错级别
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);

        // 设置空白边距的宽度
        hints.put(EncodeHintType.MARGIN, 3); // 默认是4

        // 1、生成二维码
        BitMatrix bitMatrix = new MultiFormatWriter().encode(text, BarcodeFormat.QR_CODE, WIDTH_PIX, HEIGHT_PIX, hints);

        // 2、获取二维码宽高
        int codeWidth = bitMatrix.getWidth();
        int codeHeight = bitMatrix.getHeight();

        // 3、将二维码放入缓冲流
        BufferedImage image = new BufferedImage(codeWidth, codeHeight, BufferedImage.TYPE_INT_RGB);

        for (int i = 0; i < codeWidth; i++) {
            for (int j = 0; j < codeHeight; j++) {
                // 4、循环将二维码内容定入图片
                //判断 BitMatrix 是否存在像素
                image.setRGB(i, j, bitMatrix.get(i, j) ? COLOR_BLACK : COLOR_WHITE);
            }
        }

        //判断是否写入logo图片
        if(logoPath != null && logoPath.length>0){
            File logoPic = new File(logoPath[0]);
            if (logoPic.exists()) {
                //在原来基础上,再添加一个图片
                Graphics2D g = image.createGraphics();
                BufferedImage logo = ImageIO.read(logoPic);
                int widthLogo = logo.getWidth(null) > image.getWidth() * 2 / 10 ?
                        (image.getWidth() * 2 / 10) : logo.getWidth(null);
                int heightLogo = logo.getHeight(null) > image.getHeight() * 2 / 10 ?
                        (image.getHeight() * 2 / 10) : logo.getHeight(null);

                //设定在图片中间
                int x = (image.getWidth() - widthLogo) / 2;
                int y = (image.getHeight() - heightLogo) / 2;

                // 开始绘制图片
                g.drawImage(logo, x, y, widthLogo, heightLogo, null);

                //绘制圆角矩形
                g.drawRoundRect(x, y, widthLogo, heightLogo, 15, 15);

                //边框宽度
                g.setStroke(new BasicStroke(2));

                //边框颜色
                g.setColor(Color.WHITE);
                g.drawRect(x, y, widthLogo, heightLogo);


                //最后一个参数用来设置字体的大小
                Font fontStyle = new Font(FONT_NAME,Font.PLAIN,FONT_SIZE);

                //设定颜色
                g.setColor(FONT_COLOR); //设定颜色
                g.setFont(fontStyle); //设定字体
                Integer fontStartIndex = image.getWidth()-(int) (text.length()*FONT_SIZE*0.7);
                g.drawString(text,fontStartIndex,image.getHeight()-FONT_SIZE);

                //释放图像资源
                g.dispose();
                logo.flush();
                image.flush();
            }
        }

        return image;
    }


//
//
//    public static void main(String[] args) throws Exception {
//        String logoPath = "/Users/healerjean/Desktop/images/duodianyouhuilogo.png";
//        String outPath = "/Users/healerjean/Desktop";
//        HttpServletResponse response = null;
//        OutputStream outputStream=  QRCodeUtils.writeQRImg(response,"http://test.dangqugame.cn/duodian/youhui/redirectTaoKouLing?taokouling=¥3hxo0EfH68X¥", outPath,logoPath);
//    }


}

2.2、将二维码和图片进行合成

package com.duodian.youhui.admin.utils.qCode;


import java.awt.*;
import java.awt.image.BufferedImage;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

public class ChartGraphics {


    public static List<String> getStrList(String inputString, int length) {
        int size = inputString.length() / length;
        if (inputString.length() % length != 0) {
            size += 1;
        }
        return getStrList(inputString, length, size);
    }


    public static List<String> getStrList(String inputString, int length,
                                          int size) {
        List<String> list = new ArrayList<String>();
        for (int index = 0; index < size; index++) {
            String childStr = substring(inputString, index * length,
                    (index + 1) * length);
            list.add(childStr);
        }
        return list;
    }


    public static String substring(String str, int f, int t) {
        if (f > str.length())
            return null;
        if (t > str.length()) {
            return str.substring(f, str.length());
        } else {
            return str.substring(f, t);
        }
    }




    public static BufferedImage graphicsGenerationlovely(BufferedImage imageQR,  BufferedImage ImageerWeiMa,
     String titleLab,
     String title ,
     BigDecimal originPrice ,
     BigDecimal  nowPrice  ,
     BigDecimal couponPrice       ,
     String description
    ) {
        //整体图的高度和宽度
        int lovelyImageWidth = 900;
        int lovelyImageHeight = 1428;
        //整体图合成
        BufferedImage bufferedImage = new BufferedImage(lovelyImageWidth, lovelyImageHeight, BufferedImage.TYPE_INT_RGB);
        //设置图片的背景色
        Graphics2D main = bufferedImage.createGraphics();
        main.fillRect(0, 0, lovelyImageWidth, lovelyImageHeight);


        Graphics graphicsQR = bufferedImage.getGraphics();
        graphicsQR.drawImage(imageQR, 0, 0, 900, 940, null);
        graphicsQR.drawImage(ImageerWeiMa, 591, 992, 249, 249, null);





        Graphics2D baoyou = bufferedImage.createGraphics();
        baoyou.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        baoyou.setColor(new Color(218, 83, 80));
        baoyou.fillRect(25,985,60,30);
        //固定文字 包邮
        Graphics2D fixBaoyou = bufferedImage.createGraphics();
        fixBaoyou.setColor(new Color(252, 250, 253));
        Font baoyouFont = new Font("黑体", Font.PLAIN, 26);
        fixBaoyou.setFont(baoyouFont);
        fixBaoyou.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        fixBaoyou.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);
        String baoyouWenzi = titleLab;
        fixBaoyou.drawString(baoyouWenzi, 25, 1010);



        //固定文字 title
        Graphics2D fixed = bufferedImage.createGraphics();
        fixed.setColor(new Color(51, 51, 51));
        Font fixedFont = new Font("黑体", Font.PLAIN, 37);
        fixed.setFont(fixedFont);
        //失真处理
        fixed.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        fixed.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);

        List<String> list = getStrList(title,14);

        int i = 1 ;
        for(String str:list){
            if(i==1){
                fixed.drawString(str, 95, 1010);
            }else if(i==2){
                fixed.drawString(str, 20, 1055);
            }else if(i ==3){
                fixed.drawString(str, 20, 1095);
            }
            i++;
        }


        //固定文字 现价
        Graphics2D fixNowPrice = bufferedImage.createGraphics();
        fixNowPrice.setColor(new Color(51, 51, 51));
        Font fixNowPriceFont = new Font("黑体", Font.PLAIN, 28);
        fixNowPrice.setFont(fixNowPriceFont);
        //失真处理
        fixNowPrice.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        fixNowPrice.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);
        String newPrice =  "现价:¥"+originPrice;
        fixNowPrice.drawString(newPrice, 25, 1166);


        Graphics2D quanJx = bufferedImage.createGraphics();
        quanJx.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        quanJx.setColor(new Color(218, 83, 80));
        quanJx.fillRect(25,1190,30,30);


        //固定文字 券
        Graphics2D fixquanWenzi = bufferedImage.createGraphics();
        fixquanWenzi.setColor(new Color(252, 250, 253));
        Font fixQuanHouwenziFont = new Font("黑体", Font.PLAIN, 26);
        fixquanWenzi.setFont(fixQuanHouwenziFont);
        //失真处理
        fixquanWenzi.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        fixquanWenzi.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);
        String quanwezi =  "券";
        fixquanWenzi.drawString(quanwezi, 25, 1215);



        Graphics2D yuanJx = bufferedImage.createGraphics();
        yuanJx.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        yuanJx.setColor(new Color(218, 83, 80));
        yuanJx.drawRect(55,1190,60,30);


        //固定文字 券
        Graphics2D fixyuanWenzi = bufferedImage.createGraphics();
        fixyuanWenzi.setColor(new Color(218, 83, 80));
        Font fixyuanWenziFont = new Font("黑体", Font.PLAIN, 26);
        fixyuanWenzi.setFont(fixyuanWenziFont);
        //失真处理
        fixyuanWenzi.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        fixyuanWenzi.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);
        String yuan =  couponPrice+"";
        fixyuanWenzi.drawString(yuan, 55, 1215);




        //固定文字 券以及券后价
        Graphics2D fixQuanHou = bufferedImage.createGraphics();
        fixQuanHou.setColor(new Color(51, 51, 51));
        Font fixQuanHouFont = new Font("黑体", Font.PLAIN, 26);
        fixQuanHou.setFont(fixQuanHouFont);
        //失真处理
        fixQuanHou.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        fixQuanHou.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);
        String quanhoujia =  "券后价:";
        fixQuanHou.drawString(quanhoujia, 131, 1215);




        //固定文字¥
        Graphics2D meiyuan = bufferedImage.createGraphics();
        meiyuan.setColor(new Color(218, 83, 80));
        Font qhjPriceMeiyuanFont = new Font("黑体", Font.PLAIN, 30);
        meiyuan.setFont(qhjPriceMeiyuanFont);
        //失真处理
        meiyuan.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        meiyuan.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);
        String meiyuanWenZi =  "¥";
        meiyuan.drawString(meiyuanWenZi, 224, 1215);


        //固定文字 9.90
        Graphics2D qhjPrice = bufferedImage.createGraphics();
        qhjPrice.setColor(new Color(218, 83, 80));
        Font qhjPriceFont = new Font("黑体", Font.PLAIN, 60);
        qhjPrice.setFont(qhjPriceFont);
        //失真处理
        qhjPrice.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        qhjPrice.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);
        String QaunPrice = nowPrice+"";
        qhjPrice.drawString(QaunPrice, 245, 1215);




        Graphics2D sptjRect = bufferedImage.createGraphics();
        sptjRect.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        sptjRect.setColor(new Color(218, 83, 80));
        sptjRect.fillRect(25,1275,110,30);


        //固定文字
        Graphics2D fixsptjwenzi = bufferedImage.createGraphics();
        fixsptjwenzi.setColor(new Color(252, 250, 253));
        Font sptjFont = new Font("黑体", Font.PLAIN, 26);
        fixsptjwenzi.setFont(sptjFont);
        fixsptjwenzi.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        fixsptjwenzi.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);
        String sptjwenzi =  "商品推荐";
        fixsptjwenzi.drawString(sptjwenzi, 25, 1300);


        //商品推荐
        Graphics2D fixTuiJian = bufferedImage.createGraphics();
        fixTuiJian.setColor(new Color(51, 51, 51));
        Font fixTuiJianFont = new Font("黑体", Font.PLAIN, 30);
        fixTuiJian.setFont(fixTuiJianFont);
        //失真处理
        fixTuiJian.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        fixTuiJian.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);
        String tuijian = description;
        List<String> tuijianList = getStrList(tuijian,24);

        int m = 1 ;
        for(String str:tuijianList){
            if(m ==1){
                fixTuiJian.drawString(str, 150, 1300);
            }else if(m ==2){
                fixTuiJian.drawString(str, 20, 1345);
            }else if(m  ==3){
                fixTuiJian.drawString(str, 20, 1390);
            }
            m++;
        }

        return bufferedImage;
    }

}

普通java绘图

https://blog.csdn.net/xietansheng/article/details/55669157

https://www.jb51.net/article/73136.htm

ContactAuthor