JAVA原生图片处理:Graphics2D海报升级(二)

最近公司安排我写批量海报(9图合1,生成几十张海报图)、单品海报,多个商品海报(常规业务)

技巧:字体居中:背景宽/2-字体长度/2(只适合字体宽度能计算)

只说最简单的生成一张海报里面包含元素 背景图、订单主图、原价、现价、描述(中文换行)

难点1.Graphics2D资料较少;

       2.中英、半全、符号数字组合换行未解决

       3.价格背景图自动拉伸(可以绘制,但是我没绘成功)

限制:

1.api叙述资料较少,不能很好的精确绘图

2.只能绘制本地图,远程的图片必须先下载下来

3.高频io瓶颈(我现阶段不解决)

 private String posterImgOrderOne(String filePath, Long orderId) {
        Map map = new HashMap();
        map.put("orderId", orderId);
        List<OrderItem> list = orderItemService.list(map);
        String image = list.get(0).getGoodsImage();
        String newImg = new String();
        try {
            //29.8
            Font pinfang_67 = new Font("宋体", Font.BOLD, 67);
            //我买了这些省了 元
            Font pinfang_57 = new Font("宋体", Font.BOLD, 57);
            //商品标题
            Font pinfang_32 = new Font("宋体", Font.BOLD, 32);
            //现价
            Font pinfang_35 = new Font("宋体", Font.BOLD, 35);
            //原价
            Font pinfang_27 = new Font("宋体", Font.BOLD, 27);
            //背景图
            String backgroundPath = filePath + "upload/poster_good1.jpg";
            //商品图
            String frontgroudPath = filePath + image.substring(1);
            //通过缓存图片流读取图片,并裁切
            BufferedImage background = ImageIO.read(new File(backgroundPath));
            BufferedImage frontgroud = ImageReorganization.resizeImagePng(203, 175, ImageIO.read(new File(frontgroudPath)));
            //Graphics2D画板
            Graphics2D g = background.createGraphics();
            //画笔宽度
            //g.setStroke(new BasicStroke(100));
            //消除锯齿,圆润
            g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
            //透明覆盖
            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 1.0f));
            //合并图片
            g.drawImage(frontgroud, 50, 316, frontgroud.getWidth(), frontgroud.getHeight(), null);
            //第一行字:设置宣传语
            String s3 = String.valueOf(list.get(0).getGoodsPriceOriginal().subtract(list.get(0).getGoodsPrice()).setScale(2, BigDecimal.ROUND_DOWN));
            String msg1 = "我买这些省了" + s3 + "元";
            AttributedString as1 = new AttributedString(msg1);
            g.setColor(Color.WHITE);
            int i = msg1.indexOf("了");
            int length = msg1.length();
            /**设置同一行字体不同*/
            as1.addAttribute(TextAttribute.FONT, pinfang_57, 0, i + 1);
            as1.addAttribute(TextAttribute.FONT, pinfang_67, i + 1, length - 1);
            as1.addAttribute(TextAttribute.FONT, pinfang_57, length - 1, length);
            g.drawString(as1.getIterator(), 100, 190);
//            as1.addAttribute(TextAttribute.SWAP_COLORS, TextAttribute.SWAP_COLORS_ON, 0, 2);//交换背景色
            /**第二行字:标题*/
            String msg2 = list.get(0).getGoodsName();
//            getCommnityNameSize();

            //换行计算
            String msgsNewOne = new String();//第一行
            String msgsNewTwo = new String();//第二行
            //中文先转英文,全角再转半角
            String s = StringEnglishUtil.full2Half(StringEnglishUtil.cToe(msg2));
            if (s.length()>16){
                msgsNewOne = s.substring(0, 16);
                msgsNewTwo = s.substring(16);
                log.info(msgsNewTwo);
            }else {
                msgsNewOne=s;
            }

            g.setPaint(Color.BLACK);
            AttributedString as2 = new AttributedString(msgsNewOne);
            as2.addAttribute(TextAttribute.FONT, pinfang_32);
            g.drawString(as2.getIterator(), 270, 360);
            if (!StringUtils.isEmpty(msgsNewTwo)) {
                if (msgsNewTwo.length()>10){
                    msgsNewTwo = msgsNewTwo.substring(0, 10);
                    log.info(msgsNewTwo);
                    msgsNewTwo = msgsNewTwo+"...";
                    log.info(msgsNewTwo);
                }
                as2 = new AttributedString(msgsNewTwo);
                as2.addAttribute(TextAttribute.FONT, pinfang_32);
                g.drawString(as2.getIterator(), 270, 408);
            }

            String s1 = list.get(0).getGoodsPrice().setScale(2, BigDecimal.ROUND_DOWN).toString();

            /**第三排字:价格*/
            String msg3 = "¥" +StringEnglishUtil.cToe(s1);
            g.setPaint(Color.RED);
            AttributedString as3 = new AttributedString(msg3);
            as3.addAttribute(TextAttribute.FONT, pinfang_35);
            g.drawString(as3.getIterator(), 480, 470);
            /**原价:删除线*/
            String s2 = list.get(0).getGoodsPriceOriginal().setScale(2, BigDecimal.ROUND_DOWN).toString();
            String msg4 = "¥" +StringEnglishUtil.cToe(s2);
            g.setPaint(Color.GRAY);
            AttributedString as4 = new AttributedString(msg4);
            as4.addAttribute(TextAttribute.FONT, pinfang_27);
            as4.addAttribute(TextAttribute.STRIKETHROUGH, TextAttribute.STRIKETHROUGH_ON, 0, msg4.length());
            g.drawString(as4.getIterator(), 610, 470);
            g.dispose();
            //输出图片,JDK7的语法,打开流通道加快写入效率;这里这样写可以提高不少的io效率
            newImg = filePath + "upload/temp/" + UUID.randomUUID() + ".jpg";
            ImageIO.write(background, "jpg", Files.newOutputStream(Paths.get(newImg)));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return newImg.replace("/data/lrkj.com/resources","");
    }
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值