美文网首页技术干货
小程序码生成及分享图绘制

小程序码生成及分享图绘制

作者: Joryun | 来源:发表于2018-01-13 16:15 被阅读0次

    场景

    项目需求为用户创建活动,且生成了小程序码,进而再生成小程序码分享图,即在原小程序码的基础上绘制一张完整的分享图,并展示给用户进行分享。个中过程均交由后台生成并绘制(原因:用户在小程序直接点击某选项,直接转至分享图页面,而图片存储七牛云之上,若由前端生成再交由后台处理并返回,便影响响应速度)

    说明

    开发环境:JDK1.8
    开发语言:Java

    正题

    生成小程序码

    调用微信SDK,最好的文档便是官网文档了,虽然坑是真的多...
    进入正题!!!

    参考文档:https://mp.weixin.qq.com/debug/wxadoc/dev/api/qrcode.html

    根据业务需求选择调用的相应接口,博主所做的小程序业务需求是用于临时场景,且需要多次分享、频繁分享,因此选了接口B类型。

    步骤

    • 看文档

    坑点:
    1、注意场景值scene的说明,这个也很重要
    2、注意page参数的说明,“必须是已经发布的小程序页面”(之前做的小程序由于前期未通过审核没发布,很同意略过关键字眼。经验:未发布的小程序,无需传该参数,可正常获取小程序码,与scene不一样,scene会涉及后续的业务需求,里面的值会有具体的业务操作

    • 编码

    说明:
    1、获取小程序码需要获取access_token。
    2、scene值需跟前端进行规约,具体的传值格式(以下代码scene值以加密形式传入,可自定义加密规则)
    3、以下 七牛上传 功能使用的便是博主介绍到的七牛云模块化,想了解的见上篇 《七牛云模块化文档》

    public String getminiqrQr(String sceneStr, String accessToken) {
            RestTemplate rest = new RestTemplate();
            InputStream inputStream = null;
            String path = null;
            try {
                String url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + accessToken;
                Map<String, Object> param = new HashMap<>();
                param.put("scene", "activity_" + sceneStr);
    //            param.put("page", "pages/Activity/Situation/Situation");
                param.put("width", 200);
                logger.info("调用生成微信URL接口传参:" + param);
    
                MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
                org.springframework.http.HttpEntity requestEntity = new org.springframework.http.HttpEntity(param, headers);
                ResponseEntity<byte[]> entity = rest.exchange(url, HttpMethod.POST, requestEntity, byte[].class);
                logger.info("调用小程序生成微信小程序码URL接口返回结果:" + entity.getBody());
    
                byte[] result = entity.getBody();
                logger.info(Base64.encodeBase64String(result));
                inputStream = new ByteArrayInputStream(result);
    
                //七牛上传
                path = qiniuService.uploadByStream(inputStream);
                logger.info("----------------path:{}", path);
    
            } catch (Exception e) {
                logger.error("调用小程序生成微信小程序码URL接口异常", e);
    
            } finally {
                if (inputStream != null) {
                    try {
                        inputStream.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            return path;
        }
    

    以上最终便会返回小程序码的url,算挺简单的吧!

    绘制小程序码分享图

    效果如下:

    • 说明
      1、使用awt在画布上一层层画上去,文字、图片均可以
      2、画上去的文字及图片有坐标的概念,需要底图和上层图片素材,以及坐标(用方形框住图片或文字,左上角即为原点,团队上的协作可交由设计人员给出即可)

    • 编码

    以下代码已附上注释,够详细了!

    public byte[] drawPicture(String backImg, String qrCodeImg, String kaiImg, String avatarImg,String activityText, String text1) throws IOException {
    
            //底图
            ClassPathResource redResource = new ClassPathResource(backImg);
            BufferedImage red = ImageIO.read(redResource.getInputStream());
    
            //头像
            URL avatarUrl = new URL(avatarImg);
            BufferedImage avatar = ImageIO.read(avatarUrl);
    
            //小程序码
            URL qrCodeUrl = new URL(qrCodeImg);
            BufferedImage qrCode = ImageIO.read(qrCodeUrl);
    
            //开
            ClassPathResource kaiResource = new ClassPathResource(kaiImg);
            BufferedImage kai = ImageIO.read(kaiResource.getInputStream());
    
            //白底
            ClassPathResource whiteResource = new ClassPathResource("white.jpeg");
            BufferedImage white = ImageIO.read(whiteResource.getInputStream());
    
            // --- 画图 ---
    
            //底层空白 bufferedImage
            BufferedImage imgB = new BufferedImage(red.getWidth(), red.getHeight(), BufferedImage.TYPE_4BYTE_ABGR);
    
            //画上头像
            drawImgInImg(imgB, avatar, 277, 90, 145, 145);
    
            //白底
            drawImgInImg(imgB, white, 200, 400, 250, 250);
    
            //画上小程序码
            drawImgInImg(imgB, qrCode, 255, 434, 190, 190);
    
            //画上图片
            drawImgInImg(imgB, red, 0, 0, red.getWidth(), red.getHeight());
    
            //画上开
            drawImgInImg(imgB, kai, 309, 488, 83, 83);
    
            //写上文字,上
            drawTextInImg(imgB, text1, 350, 315);
    
            //写上文字,活动
            drawTextInImg(imgB, activityText, 350, 395);
    
            //转jpg
            BufferedImage result = new BufferedImage(imgB.getWidth(), imgB
                    .getHeight(), BufferedImage.TYPE_3BYTE_BGR);
            result.getGraphics().drawImage(imgB, 0, 0, null);
            ByteArrayOutputStream bs = new ByteArrayOutputStream();
            ImageIO.write(result, "jpg", bs);
    
            //最终byte数组
            return bs.toByteArray();
        }
    
    private static BufferedImage drawImgInImg(BufferedImage bimageB, BufferedImage bimageT, int x, int y, int w, int h) {
            Graphics2D g = bimageB.createGraphics();
            g.drawImage(bimageT, x, y, w, h, null);
            g.dispose();
            return bimageB;
    }
    
    private static BufferedImage drawTextInImg(BufferedImage bimage, String text, int left, int top) {
            Graphics2D g = bimage.createGraphics();
            g.setColor(Color.white);
            g.setBackground(Color.white);
    
            Font font = new Font("微软雅黑", Font.PLAIN, 34);
            FontMetrics metrics = new FontMetrics(font) {
            };
            Rectangle2D bounds = metrics.getStringBounds(text, null);
            int textHeight = (int) bounds.getHeight();
            int textWidth = (int) bounds.getWidth();
            g.setFont(font);
            g.drawString(text, left - textWidth / 2, top - textHeight / 2);
            g.dispose();
            return bimage;
    }
    

    总结

    以上即为小程序码生成及绘制分享图的常见场景,在此基础上拓展出业务所需的功能,基本足够了!!!共勉~~~

    相关文章

      网友评论

        本文标题:小程序码生成及分享图绘制

        本文链接:https://www.haomeiwen.com/subject/qcicoxtx.html