zoukankan      html  css  js  c++  java
  • java Graphics2D 画图

      

      

    平时出图都是前端画图的,本次画图是对响应时间有要求,所有给后端提的需求。这里就给出一个demo 还有列出其中遇到的几个小问题

    1 首先列出结果图

    2   遇到的问题

      1  这是两张图片覆盖的。

      coverImage 方法  

         2  覆盖图是圆角矩形,但是四个角的底色要和底图保持一致

      需要先fillRect 填充相应的底色。

         3  覆盖图的文字显示问题, 因为是介绍,不确定字体的多少  自动换行  多行文字 自动计算高度  我这个是标题最多2行     介绍最多3行(在方法里面都是参数)。  

      drawString  该方法从网上找的  自己改造了下   

         4  font 字体的问题  和 Color颜色的问题

            font字体  从C:WindowsFonts 中找对应的字体就行   Font font3 = new Font("苹方-简", Font.BOLD, 28);    但是记得如果是奇葩字体 比如我这个要求苹果的字体  一定要把字体上传到linux服务器  否咋 测试或生成 文字就会变成 “口口”

          Color   颜色  java api 不能识别  #CC00FF   只能识别    Color.getHSBColor(153,153,153)

    https://www.sioe.cn/yingyong/yanse-rgb-16/  这个百度颜色转化  就出来了

     5 推荐一个好使的颜色取色器

    链接:https://pan.baidu.com/s/1gxLTOIysfYQLlSWdMFmYpQ
    提取码:se9s

    3  main 代码  

    public static void main(String[] args) throws Exception {
      int picWid=660;
      int picHeight1=269;
      int picHeight2=531;
      BufferedImage BufImage = new BufferedImage(picWid, picHeight1+picHeight2, BufferedImage.TYPE_INT_RGB);// RGB形式
      Graphics2D g = BufImage.createGraphics();
      g.drawRect(0,0,picWid,picHeight1);//画线框
      g.setColor(Color.red);
      g.fillRect(0,0,picWid,picHeight1);//是用预定的颜色填充一个矩形


      g.drawRect(0,picHeight1,picWid,picHeight2);//画线框
      g.setColor(Color.white);
      g.fillRect(0,picHeight1,picWid,picHeight2);//是用预定的颜色填充一个矩形

      // 设置圆形头像
      BufferedImage headImage = ImageIO.read(new       URL("https://wx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTKu4BoQkiauW80hPgpeLZSVkHXVDVY1iaQkicNj5UjY5w1DDqZqk6GnfedKPthqxdE4qK2K2wCUTMoUw/132"));
      headImage=convertCircular(headImage);


      // 获取小程序码
      BufferedImage qrCodeImage = ImageIO.read(new URL("https://sxhw-1251808348.cos.ap-beijing.myqcloud.com/xcxqrcode/2020-  04/af12e742bcf7662706f2c0153f0e82d8.jpg"));
      // 设置各组件位置
      //设置头像
      g.drawImage(headImage, 48, 32, 80, 80, null);
      //小程序码
      g.drawImage(qrCodeImage, 30, 620, 160, 160, null);

      //写字
      g.setColor(Color.white);
      Font font2 = new Font("苹方-简", Font.BOLD, 24);
      g.setFont(font2);
      g.drawString("丁一江", 148, 53);

      //写字
      g.setColor(Color.white);
      Font font3 = new Font("苹方-简", Font.BOLD, 28);
      g.setFont(font3);
      g.drawString("我的团购活动正在火热进行~", 148, 90);

      //写字
      g.setColor(Color.black);
      Font font4 = new Font("苹方-简", Font.BOLD, 32);
      g.setFont(font4);
      g.drawString("长按识别下程序码", 210, 677);

      //写字
      g.setColor(Color.getHSBColor(153,153,153));
      Font font5 = new Font("苹方-简", Font.BOLD, 24);
      g.setFont(font5);
      g.drawString("立即抢购好物", 210, 730);

      //覆盖层数据
      BufferedImage realImg = new BufferedImage(620, 456, BufferedImage.TYPE_INT_RGB);// RGB形式
      Graphics2D real2D = realImg.createGraphics();

      // real2D.drawRect(0,0,710,100);//画线框
      //解决 圆角矩形 4个角黑色 先填充颜色 在画矩形
      real2D.setColor(Color.red);
      real2D.fillRect(0,0,620,125);//是用预定的颜色填充一个矩形


      //real2D.drawRect(0,100,710,400);//画线框
      real2D.setColor(Color.white);
      real2D.fillRect(0,125,620,331);//是用预定的颜色填充一个矩形


      real2D.setColor(Color.white);
      real2D.fillRoundRect(0, 0, 620, 456,40, 40);


      //商品介绍
      String groupName="商品标题test-商品标题test-商品标题test-商品标题test-商品标题test-商品标题test-商品标题test-商品标题test-商品标题test";
      String groupDetail="商品详情test-商品详情test-商品详情test-商品详情test-商品详情test-商品详情test-商品详情test-商品详情test-商品详情test-商品详情test-商品详情test-商品详情test-商品详情test-商品详情test-商品详情test-商品详情test-商品详情test-商品详情test-商品详情test-商品详情test";
      String price="商品团购价:¥5-¥28.8";


      //写字
      real2D.setColor(Color.black);
      Font font6 = new Font("苹方-简", Font.BOLD, 28);
      int height=drawString(real2D,font6,groupName,578,20,40,30,2);

      //写字
      real2D.setColor(Color.gray);
      Font font7 = new Font("苹方-简", Font.BOLD, 20);
      height=drawString(real2D,font7,groupDetail,578,20,height+20,30,3);

      //写字
      real2D.setColor(Color.red);
      Font font8 = new Font("苹方-简", Font.BOLD, 28);
      height=drawString(real2D,font8,price,578,20,height+40,30,1);
      // 商品图片
      List<String> imgList=new ArrayList<String>();
      imgList.add("https://sxhw-1251808348.cos.ap-beijing.myqcloud.com/prod-image/2020-04/22824b828c39aec9396fe345cc2d8cb0.jpg");
      imgList.add("https://sxhw-1251808348.cos.ap-beijing.myqcloud.com/prod-image/2020-04/3c4dbfef1fbe4c8ae092e0efc79ecb8c.jpg");
      imgList.add("https://sxhw-1251808348.cos.ap-beijing.myqcloud.com/prod-image/2020-04/0a5774763ea977d5421b08b8204a0ed7.jpg");
      for(int i=0;i<imgList.size();i++) {
        String imgUrl=imgList.get(i);
        BufferedImage posterBufImage = ImageIO.read(new URL(imgUrl));
        real2D.drawImage(posterBufImage, 180*i+(i+1)*20, height, 180, 179, null);
      }

      // 两张图片覆盖
      BufImage = coverImage(BufImage, realImg, 20, 144, 620, 456);

      // g.setColor(Color.blue);
      ImageIO.write(BufImage, "png", new File("D:\1111test\demo31.png"));
    }

       

    /**
    * 文字超出限定长度自动换行
    *
    * @param g 画布
    * @param font 字体样式
    * @param text 文字
    * @param widthLength 最大长度 (多少长度后需要换行)
    * @param x 文字位置坐标 x
    * @param y 文字位置坐标 Y
    * @param yn 每次换行偏移多少pt
    * showLine 显示行数 文字可能过多 我们只显示showLine行文字
    */
    private static int drawString(Graphics2D g, Font font, String text1, int widthLength, int x, int y, int yn,int showLine) {
      FontMetrics fg = g.getFontMetrics(font);
      List<String> ls = new ArrayList<>();
      getListText(fg, text1, widthLength, ls);
      g.setFont(font);
      for (int i = 0; i < ls.size(); i++) {
        if(i==showLine) {
          break;
        }
        if (i == 0) {
          g.drawString(ls.get(i), x, y);
        } else {
          g.drawString(ls.get(i), x, y + i*yn);
        }
      }
      int height=fg.getHeight();
      if(ls.size()<=showLine) {
        y=y+height*ls.size();
      }else {
        y=y+height*showLine;
      }
      return y;
    }

    /**
    * 递归 切割字符串
    * @param fg
    * @param text
    * @param widthLength
    * @param ls
    */
    private static void getListText(FontMetrics fg, String text, int widthLength, List<String> ls) {
      String ba = text;
      boolean b = true;
      int i = 1;
      while (b) {
        if (fg.stringWidth(text) > widthLength) {
          text = text.substring(0, text.length() - 1);
          i++;
        } else {
          b = false;
        }
      }
      if (i != 1) {
        ls.add(ba.substring(0, ba.length() - i));
        getListText(fg, ba.substring(ba.length() - i), widthLength, ls);
      } else {
        ls.add(text);
      }
    }

    //覆盖图片方法
    public static BufferedImage coverImage(BufferedImage baseBufferedImage, BufferedImage coverBufferedImage, int x, int y, int width, int height) throws Exception{
      // 创建Graphics2D对象,用在底图对象上绘图
      Graphics2D g2d = baseBufferedImage.createGraphics();
      // 绘制
      g2d.drawImage(coverBufferedImage, x, y, width, height, null);
      g2d.dispose();// 释放图形上下文使用的系统资源
      return baseBufferedImage;
    }

    /**
    * 传入的图像必须是正方形的 才会 圆形 如果是长方形的比例则会变成椭圆的
    *
    * @param url
    * 用户头像地址
    * @return
    * @throws IOException
    */
    public static BufferedImage convertCircular(BufferedImage bi1) throws IOException {

      // BufferedImage bi1 = ImageIO.read(new File(url));

      // 这种是黑色底的
      // BufferedImage bi2 = new BufferedImage(bi1.getWidth(), bi1.getHeight(), BufferedImage.TYPE_INT_RGB);

      // 透明底的图片
      BufferedImage bi2 = new BufferedImage(bi1.getWidth(), bi1.getHeight(), BufferedImage.TYPE_4BYTE_ABGR);
      Ellipse2D.Double shape = new Ellipse2D.Double(0, 0, bi1.getWidth(), bi1.getHeight());
      Graphics2D g2 = bi2.createGraphics();
      g2.setClip(shape);
      // 使用 setRenderingHint 设置抗锯齿
      g2.drawImage(bi1, 0, 0, null);
      // 设置颜色
      g2.setBackground(Color.green);
      g2.dispose();
      return bi2;
    }

  • 相关阅读:
    Java第一次作业
    第十一次作业
    第十次作业
    第九次作业
    第八次作业
    第七次作业
    第六次作业
    第五次作业
    java第三次实验
    java 第二次实验
  • 原文地址:https://www.cnblogs.com/studyitskill/p/12843386.html
Copyright © 2011-2022 走看看