java后台生成微信中用的分享图片

案例:

java后台生成微信中用的分享图片_第1张图片      java后台生成微信中用的分享图片_第2张图片

底图:

java后台生成微信中用的分享图片_第3张图片          java后台生成微信中用的分享图片_第4张图片

java后台生成微信中用的分享图片_第5张图片        java后台生成微信中用的分享图片_第6张图片

色值转换工具:http://www.atool.org/colorpicker.php

代码:

public interface ActivityShareImageServise {

    /**生成活动分享图*/
    String generateActivityShareImage(ActivityShareImageType activityType,Integer itemId) throws Exception;

    /**
     *  生成分享图片组件
     * @param activityType
     * @param itemId    商品id
     * @return  有序组件(ImageParam、TextParam),绘图时有序添加组件
     * @throws IOException
     */
    LinkedList generateimgComponent(ActivityShareImageType activityType,Integer itemId) throws Exception;
}



/**
 * 活动分享图类型
 */
public enum ActivityShareImageType {
    TEJIA_ACTIVITY("特价活动分享图","images/tejia/tejia-background.jpg"),
    CUTPRICE_ACTIVITY_POOL_COLOR("砍价活动分享图策略池-色彩","images/cutpricepool/color.png"),;

    ActivityShareImageType(String type,String imgPath){
        this.type = type;
        this.imgPath = imgPath;
    }

    public String type;
    public String imgPath;
} 
  

 

 @Override
    public String generateActivityShareImage(ActivityShareImageType activityType, Integer itemId) throws Exception{
        try {
            BufferedImage backImage = loadClassPathImage(activityType.imgPath);
            LinkedList list = generateimgComponent(activityType,itemId);
            return graphics2DImg(activityType,backImage,list);
        }catch (Exception e){   //避免创建分享图
            logger.error("生成活动分析卡片图异常:{}",e.getMessage(),e);
            throw new BizException(0,"创建活动分享卡片图异常");
        }
    }  




//加载底图
    private BufferedImage loadClassPathImage(String classPath) {
        BufferedImage bufferedImage = null;
        try {
            InputStream resourceAsStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(classPath);
            bufferedImage = ImageIO.read(resourceAsStream);
        } catch (IOException e) {
            //e.printStackTrace();
        	logger.error(e.getMessage(),e);;
        }
        return bufferedImage;
    }

 @Override
public LinkedList generateimgComponent(ActivityShareImageType activityType, 
  Integer itemId) throws Exception{
        LinkedList list = new LinkedList<>();
        switch (activityType){
case TEJIA_ACTIVITY:{
                BufferedImage backImage = loadClassPathImage(activityType.imgPath);
                //白色底图
                BufferedImage whiteImage = new BufferedImage(backImage.getWidth()-20*2, backImage.getHeight()-20,BufferedImage.TYPE_INT_BGR);
                Graphics2D graphics = whiteImage.createGraphics();
                graphics.setBackground(Color.white);
                graphics.clearRect(0, 0, backImage.getWidth()-20*2, backImage.getHeight()-20);
                graphics.dispose();
                whiteImage = roundImage(whiteImage,whiteImage.getWidth(),30);
                ImageParam whiteParam = new ImageParam(whiteImage, 20, 30);
                list.add(whiteParam);


                AssertUtil.notEmpty(itemId,"商品id不能为空");
                Product product = productMapper.selectByPrimaryKey(itemId);
                AssertUtil.notEmpty(product,"商品不存在");
                //商品图组件
                String url = product.getItemImgurl();
                url = url.contains("http") ? url : "http://image.baidu.com".concat(url);
                BufferedImage productImage = resize(loadWebUrlImage(convert2HttpUrl(url)));
                productImage = roundImage(productImage,productImage.getWidth(),30);
                ImageParam productImageParam = new ImageParam(productImage, 50, 50);
                list.add(productImageParam);

                //商品名称
                Font productFont = new Font("思源黑体 CN Normal", Font.PLAIN, 40);
                Color productFontColor = new Color(32, 32, 32);
                String prodcutName = product.getItemName();
                String temp1 = null;
                String temp2 = null;
                String temp3 = null;
                if(StringHelper.getChineseStrLen(prodcutName)>8){
                    temp1 = StringHelper.substringChineseStr(prodcutName,8);
                    prodcutName = prodcutName.substring(prodcutName.indexOf(temp1)+temp1.length());
                    if(StringHelper.getChineseStrLen(prodcutName)>8){
                        temp2 = StringHelper.substringChineseStr(prodcutName,8);
                        prodcutName = prodcutName.substring(prodcutName.indexOf(temp2)+temp2.length());
                        if(StringHelper.getChineseStrLen(prodcutName)>8){
                            temp3 = StringHelper.substringChineseStr(prodcutName,8)+"...";
                        }else{
                            temp3 = prodcutName;
                        }
                    }else{
                        temp2 = prodcutName;
                    }
                }else {
                    temp1 = prodcutName;
                }
                TextParam first = new TextParam(temp1,new Font("思源黑体 CN Normal", Font.PLAIN, 40),productFontColor,productImageParam.getX()+productImage.getWidth()+20, 60+6+20);
                first.setAlpha(0.8f);
                list.add(first);
                if(temp2!=null && temp2.length() > 0){
                    TextParam t2 = new TextParam(temp2,new Font("思源黑体 CN Normal", Font.PLAIN, 40),productFontColor,productImageParam.getX()+productImage.getWidth()+20, 60+6+20+50);
                    t2.setAlpha(0.8f);
                    list.add(t2);
                }
                if(temp3!=null && temp3.length() > 0){
                    TextParam t3 = new TextParam(temp3,new Font("思源黑体 CN Normal", Font.PLAIN, 40),productFontColor,productImageParam.getX()+productImage.getWidth()+20, 60+6+20+100);
                    t3.setAlpha(0.8f);
                    list.add(t3);
                }
                //logger.info("分享卡片,t1:{},t2:{},t3:{}",temp1,temp2,temp3);

                //商品价格组件
                String priceText = "¥0";
                String priceText2 = "¥";
                Integer itemPrice = cutpriceActivityMapper.getMinSkuPrice(product.getId());
                AssertUtil.notEmpty(itemPrice,"商品无有效sku");
                AssertUtil.isTrue(itemPrice>0,"无效商品价格");
                double t = PayUtils.fen2RMByuanDouble((long) itemPrice);
//                if((double)((int)t) == t){
//                    priceText2 += (int)t;   //整数
//                }else{
//                    priceText2 += t;
//                }
                DecimalFormat df = new DecimalFormat("######0.00");//精确小数点两位,分
                priceText2 += df.format(t);

                Font priceFont = new Font("思源黑体 CN Normal", Font.BOLD, 88);
                Color priceColor = new Color(222, 48, 70);
                TextParam priceTextParam = new TextParam(priceText, priceFont, priceColor, productImageParam.getX()+productImage.getWidth()+30, 304);
                list.add(priceTextParam);

                //价格组件
                Font priceFont2 = new Font("思源黑体 CN Normal", Font.PLAIN, 40);
                Color priceColor2 = new Color(32, 32, 32);
                int priceStringWidth = getStrWidth(priceFont, priceText);
                TextParam priceTextParam2 = new TextParam(priceText2,priceFont2, priceColor2, priceTextParam.getX()+priceStringWidth+30, 304);
                priceTextParam2.setStrikethrough(true);//划线
                priceTextParam2.setAlpha(0.4f);
                list.add(priceTextParam2);
                //logger.info("分享卡片,priceText2:{}",priceText2);

                // 点击组件

                String btnImg = "images/tejia/tejia-btn.jpg";
                BufferedImage participationImage = loadClassPathImage(btnImg);
                ImageParam participationIconImgParam = new ImageParam(participationImage, 0, backImage.getHeight()*2-100-participationImage.getHeight());
                list.add(participationIconImgParam);
                break;
            }
    
 case CUTPRICE_ACTIVITY_POOL_WOMAN:{
                BufferedImage backImage = loadClassPathImage(activityType.imgPath);

                AssertUtil.notEmpty(itemId,"商品id不能为空");
                Product product = productMapper.selectByPrimaryKey(itemId);
                AssertUtil.notEmpty(product,"商品不存在");
                //商品图组件
                String url = product.getItemImgurl();
                url = url.contains("http") ? url : "http://image.baidu.com".concat(url);
                BufferedImage productImage = resizePool(loadWebUrlImage(convert2HttpUrl(url)));
                productImage = roundImage(productImage,productImage.getWidth(),0);
                ImageParam productImageParam = new ImageParam(productImage, 110, 84);
                list.add(productImageParam);

                //商品名称
                Font productFont = new Font("思源黑体 CN Normal", Font.PLAIN, 40);
                Color productFontColor = new Color(255, 112, 117);
                String prodcutName = product.getItemName();
                String temp1 = null;
                String temp2 = null;
                if(StringHelper.getChineseStrLen(prodcutName)>7){
                    temp1 = StringHelper.substringChineseStr(prodcutName,7);
                    prodcutName = prodcutName.substring(prodcutName.indexOf(temp1)+temp1.length());
                    if(StringHelper.getChineseStrLen(prodcutName)>7){
                        temp2 = StringHelper.substringChineseStr(prodcutName,7)+"...";
                    }else{
                        temp2 = prodcutName;
                    }
                }else {
                    temp1 = prodcutName;
                }
                TextParam first = new TextParam(temp1,new Font("思源黑体 CN Normal", Font.BOLD, 39),productFontColor,100, 420);
                first.setAlpha(0.8f);
                list.add(first);

                if(temp2!=null && temp2.length() > 0){
                    TextParam t2 = new TextParam(temp2,new Font("思源黑体 CN Normal", Font.BOLD, 39),productFontColor,100, 475);
                    t2.setAlpha(0.8f);
                    list.add(t2);
                }
                //logger.info("分享卡片,t1:{},t2:{},t3:{}",temp1,temp2,temp3);

                //商品价格组件
                String priceText = "0元得";
                String priceText2 = "¥";
                Integer itemPrice = cutpriceActivityMapper.getMinSkuPrice(product.getId());
                AssertUtil.notEmpty(itemPrice,"商品无有效sku");
                AssertUtil.isTrue(itemPrice>0,"无效商品价格");
                double t = PayUtils.fen2RMByuanDouble((long) itemPrice);
//                if((double)((int)t) == t){
//                    priceText2 += (int)t;   //整数
//                }else{
//                    priceText2 += t;
//                }
                DecimalFormat df = new DecimalFormat("######0.00");//精确小数点两位,分
                priceText2 += df.format(t);

                Font priceFont = new Font("思源黑体 CN Normal", Font.BOLD, 75);
                Color priceColor = new Color(255, 112, 117);
                TextParam priceTextParam = new TextParam(priceText, priceFont, priceColor, 440, 160);
                list.add(priceTextParam);

                //价格组件
                Font priceFont2 = new Font("思源黑体 CN Normal", Font.PLAIN, 65);
                Color priceColor2 = new Color(255, 112, 117);
                int priceStringWidth = getStrWidth(priceFont, priceText);
                TextParam priceTextParam2 = new TextParam(priceText2,priceFont2, priceColor2, 440, 235);
                priceTextParam2.setStrikethrough(true);//划线
                priceTextParam2.setAlpha(0.4f);
                list.add(priceTextParam2);
                //logger.info("分享卡片,priceText2:{}",priceText2);

                // 点击组件
                BufferedImage participationImage = loadClassPathImage("images/cutpricepool/woman-button.png");
                ImageParam participationIconImgParam = new ImageParam(participationImage, 414, 242);
                list.add(participationIconImgParam);
                break;
            }

            // todo 其它分享图组件配置  case
        }
        return list;
 } 
  
  static BufferedImage roundImage(BufferedImage image, int targetSize, int cornerRadius) throws Exception {
        BufferedImage outputImage = new BufferedImage(targetSize, targetSize, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2 = outputImage.createGraphics();
        g2.setComposite(AlphaComposite.Src);
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setColor(Color.WHITE);
        g2.fill(new RoundRectangle2D.Float(0, 0, targetSize, targetSize, cornerRadius, cornerRadius));
        g2.setComposite(AlphaComposite.SrcAtop);
        g2.drawImage(image, 0, 0, null);
        g2.dispose();
        return outputImage;
    }


/**https替换http*/
    private static String convert2HttpUrl(String url){
        url = url.contains("https") ? url.replace("https", "http") : url;
        return url;
    }


 /**读取web图片*/
    private static BufferedImage loadWebUrlImage(String url) throws IOException {
        ByteArrayInputStream in = new ByteArrayInputStream(HttpUtil.getBytes(url));
        BufferedImage bufferedImage = ImageIO.read(in);
        return bufferedImage;
    }

 /**调整图片大小 204*204*/
    private static BufferedImage resize(BufferedImage bufferedImage){
        BufferedImage result = new BufferedImage(284, 284,BufferedImage.TYPE_INT_RGB);
        Graphics graphics = result.getGraphics();
        graphics.drawImage(bufferedImage.getScaledInstance(284, 284,Image.SCALE_SMOOTH), 0, 0, null);
        graphics.dispose();
        return result;
    }

public static Double fen2RMByuanDouble(Long fen) {
		if (fen == null) {
			return 0D;
		} else {
			BigDecimal amount = new BigDecimal(fen);
			amount = amount.divide(new BigDecimal(100));
			return amount.doubleValue();
		}
	}

 private static int getStrWidth(Font font, String text) {
        FontMetrics fontMetrics = FontDesignMetrics.getMetrics(font);
        return fontMetrics.stringWidth(text);
    }

 

 

 /**
     *  2D绘图
     * @param backImage 背景图
     * @param list  有序图片组件(ImageParam、TextParam),组件图层从低到高
     * @return  图片的web地址
     * @throws IOException
     */
    private static String graphics2DImg(ActivityShareImageType activityType,BufferedImage backImage, LinkedList list ) throws IOException{
        // 图片的高/宽度
        int bwidth = backImage.getWidth();
        int bheight = backImage.getHeight();
        if ("特价活动分享图".equals(activityType.type)){
             bheight = bheight*2-100;
        }
        int alphaType = BufferedImage.TYPE_INT_RGB;
        // 画板图片
        BufferedImage backgroundImage = new BufferedImage(bwidth, bheight, alphaType);
        Graphics2D graphics2D = backgroundImage.createGraphics();
        graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        graphics2D.drawImage(backImage.getScaledInstance(bwidth, bheight, Image.SCALE_SMOOTH), 0, 0, null);
        graphics2D.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 1));

        if(list!=null){
            for(Object obj:list){
                if( obj instanceof ImageParam){
                    drawImageParam((ImageParam)obj,graphics2D);
                }else if(obj instanceof TextParam){
                    drawTextParam((TextParam) obj,graphics2D);
                }else{
                    throw new BizException(-1,"生成图片参数异常");
                }
            }
        }
        String imgUrl = writeFileAndUpload(backgroundImage);
        graphics2D.dispose();
        return imgUrl;
    }


  private static void drawImageParam(ImageParam param,Graphics2D graphics2D){
        int triangleWidth = param.getBufferedImage().getWidth();
        int triangleHeight = param.getBufferedImage().getHeight();
        graphics2D.drawImage(param.getBufferedImage().getScaledInstance(triangleWidth, triangleHeight, Image.SCALE_SMOOTH), param.getX(), param.getY(), triangleWidth, triangleHeight, null);
    }


  private static String writeFileAndUpload(BufferedImage backgroundImage) throws IOException {
        String folder = System.getProperty("java.io.tmpdir");
        String filePath = folder + UUID.randomUUID().toString() + ".png";
        ImageIO.write(backgroundImage, "png", new File(filePath));
        return "/" + QiNiuCdnUtil.uploadToQiNiu(filePath, "s/p/product_v2/");
    }


/**
     * 上传文件到七牛cdn
     *
     * @param tempImagePath
     * @param qiNiuWxacodeImagePath
     * @return
     */
    public static String uploadToQiNiu(String tempImagePath, String qiNiuWxacodeImagePath) {
        if(StringHelper.isEmpty(tempImagePath)){
            return null;
        }
        try {
            Auth auth = Auth.create(ACCESS_KEY, SECRET_KEY);
            String upToken = auth.uploadToken(BUCKET);
            //这里的key参数就是文件的路径
            String qiNiuImagePath = getQiNiuImagePath(tempImagePath,qiNiuWxacodeImagePath);
            Response response = QINIU_UPLOAD_MANAGER.put(tempImagePath, qiNiuImagePath, upToken);
            //解析上传成功的结果
            DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
            //返回文件路径,并记录
            LOGGER.info("上传图片成功,图片路径{}","http://image.baidu.com/" + putRet.key);
            return putRet.key;
        } catch (QiniuException ex) {
            Response r = ex.response;
            LOGGER.error("上传图片到七牛云失败", ex);
            try {
                LOGGER.error(r.bodyString());
                return null;
            } catch (QiniuException ex2) {
                LOGGER.error("上传图片到七牛云失败", ex2);
                return null;
            }
        }
        finally {
        	try {
			//上传完成后删除
        	  new File(tempImagePath).delete();
        	}
        	catch (Exception e) {
        		LOGGER.error(e.getMessage(),e);
			}
		}
    } 
  

 

 

 

你可能感兴趣的:(java后台生成微信中用的分享图片)