java Graphics2D 畫圖


  

  

平時出圖都是前端畫圖的,本次畫圖是對響應時間有要求,所有給后端提的需求。這里就給出一個demo 還有列出其中遇到的幾個小問題

1 首先列出結果圖

 

 

 

 

 

2   遇到的問題

  1  這是兩張圖片覆蓋的。

  coverImage 方法  

     2  覆蓋圖是圓角矩形,但是四個角的底色要和底圖保持一致

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

     3  覆蓋圖的文字顯示問題, 因為是介紹,不確定字體的多少  自動換行  多行文字 自動計算高度  我這個是標題最多2行     介紹最多3行(在方法里面都是參數)。  

 

  drawString  該方法從網上找的  自己改造了下   

     4  font 字體的問題  和 Color顏色的問題

        font字體  從C:\Windows\Fonts 中找對應的字體就行   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;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM