Spring Boot + hutool 创建海报图片

Spring Boot + hutool 创建海报图片

复制代码
/**
     * 分享,生成图片
     * @param id
     * @return
     */
    @GetMapping("/getShareImg")
    public void getShareImg(String id,HttpServletResponse response) throws IOException {
        CouponConsignSaleClassify byId = couponConsignSaleClassifyService.getById(id);
        if(byId == null){
            throw new GlobalException("查询 id 为空 ");
        }

        CouponConsignSaleGoods one = couponConsignSaleGoodsService.lambdaQuery().eq(CouponConsignSaleGoods::getClassifyId, id).ge(CouponConsignSaleGoods::getStock, 1)
                .orderByAsc(CouponConsignSaleGoods::getPurchasePrice).last(" limit 0,1").one();

        /*final int w = 270 * 2;
        final int h = 340 * 2;*/

        final int w = 405;
        final int h = 550;

        BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_BGR);
        Graphics2D graphics2D = bi.createGraphics();
        //绘制白色背景
        graphics2D.setColor(Color.white);
        graphics2D.fillRect(0, 0, w, h);

        //释放资源
        graphics2D.dispose();

        String tempPath = System.getProperty("java.io.tmpdir");

        //System.out.println(tempPath);

        File outputfile = new File(tempPath+"poster.jpg");
        ImageIO.write(bi, "jpg", outputfile);

        //分类图片
        Image image = ImgUtil.getImage(new URL(transformStyle(byId.getImg())));

        File scaleImg = new File(tempPath+"imgScale.jpg");
        ImgUtil.scale(image,scaleImg,1.2f);
        BufferedImage read = ImageIO.read(scaleImg);
        //画图片
        ImgUtil.pressImage(outputfile,outputfile,read,0,-140,1f);

        //商品名称
        String name = byId.getName();
        ImgUtil.pressText(outputfile,outputfile,name,Color.black,new Font("黑体", Font.PLAIN, 20),-170+(name.length() * 10),0,0.8f);

        String lowestPrice=byId.getMaxPrice()==null?"":byId.getMaxPrice().toPlainString();
        if(one != null){
            lowestPrice = one.getPrice().toPlainString();
        }

        //最低价格
        String p="最低价格:"+lowestPrice;
        ImgUtil.pressText(outputfile,outputfile,p,Color.red,new Font("黑体", Font.PLAIN, 22),-200 + (p.length() * 11),35,0.8f);

        //原价
        ImgUtil.pressText(outputfile,outputfile,"原价:"+(byId.getMaxPrice()==null?"-":byId.getMaxPrice()),Color.black,new Font("黑体", Font.PLAIN, 15),50,30,0.8f);

        String url="http://qy.gsjf.cc/h5/#/pages/buy/consignBuy/consignBuy?id="+byId.getId();
        String qrFile=tempPath+"qrFile.jpg";
        File file = FileUtil.file(qrFile);

        //生成二维码
        QrCodeUtil.generate(url, 180, 180,
                file);
        BufferedImage qrFile0 = ImageIO.read(file);
        //显示二维码
        ImgUtil.pressImage(outputfile,outputfile,qrFile0,0,130,1f);

        //显示文字
        ImgUtil.pressText(outputfile,outputfile,"识别二维码查看详情",Color.black,new Font("黑体", Font.PLAIN, 16),-07,250,0.6f);

       /* ByteArrayOutputStream os = new ByteArrayOutputStream();
        ImageIO.write(bi, "jpg", os);*/


        byte[] bFile = Files.readAllBytes(outputfile.toPath());

        response.setContentType("image/jpg"); //设置返回的文件类型
        OutputStream respOut = response.getOutputStream();
        respOut.write(bFile);
        respOut.flush();
        respOut.close();
    }

    /**
     * 对中文字符进行UTF-8编码
     * @param source 要转义的字符串
     * @return
     * @throws UnsupportedEncodingException
     */
    public static String transformStyle(String source) throws UnsupportedEncodingException
    {
        char[] arr = source.toCharArray();
        StringBuilder sb = new StringBuilder();
        for(int i = 0; i < arr.length; i++)
        {
            char temp = arr[i];
            if(isChinese(temp))
            {
                sb.append(URLEncoder.encode("" + temp, "UTF-8"));
                continue;
            }
            sb.append(arr[i]);
        }
        return sb.toString();
    }
    /**
     * 判断是不是中文字符
     * @param c
     * @return
     */
    public static boolean isChinese(char c)
    {

        Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);

        if(ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS

                || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS

                || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A

                || ub == Character.UnicodeBlock.GENERAL_PUNCTUATION

                || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION

                || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS)
        {

            return true;

        }

        return false;

    }

效果

相关推荐
-Xie-1 小时前
Redis(八)——多线程与单线程
java·数据库·redis
Kuo-Teng1 小时前
LeetCode 279: Perfect Squares
java·数据结构·算法·leetcode·职场和发展
Filotimo_1 小时前
SpringBoot3整合Druid数据源
java·spring boot
G探险者1 小时前
为什么 VARCHAR(1000) 存不了 1000 个汉字? —— 详解主流数据库“字段长度”的底层差异
数据库·后端·mysql
百锦再1 小时前
第18章 高级特征
android·java·开发语言·后端·python·rust·django
Tony Bai2 小时前
Go 在 Web3 的统治力:2025 年架构与生态综述
开发语言·后端·架构·golang·web3
乄bluefox2 小时前
Reactor 中的 doOnError 与 doOnCancel
java·reactor·rea
CoderYanger2 小时前
B.双指针——3194. 最小元素和最大元素的最小平均值
java·开发语言·数据结构·算法·leetcode·职场和发展·1024程序员节
程序猿20232 小时前
项目结构深度解析:理解Spring Boot项目的标准布局和约定
java·spring boot·后端
RainbowSea2 小时前
内网穿透配置和使用
java·后端