印章生成工具类开发

2023-11-02

  1. Java代码见我的资源  免费使用印章生成工具类,Java开发-Java文档类资源-CSDN下载印章生成工具类,Java开发更多下载资源、学习资料请访问CSDN下载频道.https://download.csdn.net/download/jlonghou/85218149
  2. 代码:
    1. pom
      <?xml version="1.0" encoding="UTF-8"?>
      <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
          <modelVersion>4.0.0</modelVersion>
          <parent>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-starter-parent</artifactId>
              <version>2.6.7</version>
              <relativePath/> <!-- lookup parent from repository -->
          </parent>
          <groupId>com</groupId>
          <artifactId>seal</artifactId>
          <version>0.0.1-SNAPSHOT</version>
          <name>seal</name>
          <description>Demo project for Spring Boot</description>
          <properties>
              <java.version>1.8</java.version>
              <maven.compiler.encoding>UTF-8</maven.compiler.encoding>
              <maven.compiler.source>1.8</maven.compiler.source>
              <maven.compiler.target>1.8</maven.compiler.target>
          </properties>
          <repositories>
              <repository>
                  <id>aliyun</id>
                  <name>aliyun</name>
                  <url>http://maven.aliyun.com/nexus/content/groups/public</url>
                  <releases>
                      <enabled>true</enabled>
                  </releases>
                  <snapshots>
                      <enabled>false</enabled>
                  </snapshots>
              </repository>
          </repositories>
      
          <dependencies>
              <dependency>
                  <groupId>org.projectlombok</groupId>
                  <artifactId>lombok</artifactId>
                  <version>RELEASE</version>
                  <scope>provided</scope>
              </dependency>
              <dependency>
                  <groupId>junit</groupId>
                  <artifactId>junit</artifactId>
                  <version>RELEASE</version>
                  <scope>test</scope>
              </dependency>
              <dependency>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-test</artifactId>
                  <version>2.6.7</version>
                  <scope>test</scope>
              </dependency>
              <dependency>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-starter</artifactId>
              </dependency>
              <dependency>
                  <groupId>org.projectlombok</groupId>
                  <artifactId>lombok</artifactId>
                  <optional>true</optional>
              </dependency>
              <dependency>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-starter-test</artifactId>
                  <scope>test</scope>
              </dependency>
          </dependencies>
      
          <profiles>
              <profile>
                  <id>jdk-1.8</id>
                  <activation>
                      <jdk>1.8</jdk>
                  </activation>
              </profile>
          </profiles>
      
      </project>
      

      2.测试代码

      package com.seal;
      
      import org.junit.Before;
      import org.junit.jupiter.api.Test;
      import org.springframework.boot.test.context.SpringBootTest;
      
      import java.io.File;
      
      @SpringBootTest
      class SealApplicationTests {
          @Before
          public void mkdir() {
              File dir = new File("src/main/resources/mg");
              if (!dir.exists()) {
                  dir.mkdirs();
              }
          }
      
          @Test
          public void SealTest_1() throws Exception {
              Seal.builder()
                      .size(200)
                      .borderCircle(SealCircle.builder().line(4).width(95).height(95).build())
                      .mainFont(SealFont.builder().text("中国公章开发有限公司").size(22).space(22.0).margin(4).build())
                      .centerFont(SealFont.builder().text("★").size(60).build())
                      .titleFont(SealFont.builder().text("电子签章").size(16).space(8.0).margin(54).build())
                      .build()
                      .draw("src/main/resources/img/中国公章开发有限公司1.png");
          }
      
          @Test
          public void SealTest_2() throws Exception {
              Seal.builder()
                      .size(300)
                      .borderCircle(SealCircle.builder().line(5).width(140).height(140).build())
                      .mainFont(SealFont.builder().text("中国公章开发有限公司").size(35).space(35.0).margin(10).build())
                      .centerFont(SealFont.builder().text("★").size(100).build())
                      .titleFont(SealFont.builder().text("电子签章").size(22).space(10.0).margin(68).build())
                      .build()
                      .draw("src/main/resources/img/中国公章开发有限公司2.png");
          }
      
          @Test
          public void SealTest_3() throws Exception {
              Seal.builder()
                      .size(300)
                      .borderCircle(SealCircle.builder().line(3).width(144).height(100).build())
                      .borderInnerCircle(SealCircle.builder().line(1).width(140).height(96).build())
                      .mainFont(SealFont.builder().text("中国公章开发有限公司").size(25).space(12.0).margin(10).build())
                      .centerFont(SealFont.builder().text("NO.5201314").size(20).build())
                      .titleFont(SealFont.builder().text("电子合同专用章").size(20).space(9.0).margin(64).build())
                      .build()
                      .draw("src/main/resources/img/中国公章开发有限公司3.png");
          }
      
          @Test
          public void SealTest_4() throws Exception {
              Seal.builder()
                      .size(300)
                      .borderSquare(16)
                      .mainFont(SealFont.builder().text("马卡").size(120).build())
                      .build()
                      .draw("src/main/resources/img/马卡.png");
          }
      
          @Test
          public void SealTest_5() throws Exception {
              Seal.builder()
                      .size(300)
                      .borderSquare(16)
                      .mainFont(SealFont.builder().text("卡罗印").size(120).build())
                      .build()
                      .draw("src/main/resources/img/卡罗.png");
          }
      }
      

      3.SealFont

      package com.seal;
      
      import lombok.Builder;
      import lombok.Getter;
      
      /**
       * @Author HOUJL
       * @Date 2022/4/25
       * @Description:
       */
      @Getter
      @Builder
      public class SealFont {
          private String text;
          private String family;
          private Integer size;
          private Boolean bold;
          private Double space;
          private Integer margin;
      
          public String getFamily() {
              return family == null ? "宋体" : family;
          }
      
          public boolean getBold() {
              return bold == null ? true : bold;
          }
      
          public SealFont append(String text) {
              this.text += text;
              return this;
          }
      
      
      }
      

      4.SealCircle

      package com.seal;
      
      import lombok.Builder;
      import lombok.Getter;
      
      /**
       * @Author HOUJL
       * @Date 2022/4/25
       * @Description:
       */
      @Getter
      @Builder
      public class SealCircle {
          private Integer line;
          private Integer width;
          private Integer height;
      }

      5.核心代码

      package com.seal;
      
      import lombok.Builder;
      import lombok.Getter;
      
      import javax.imageio.ImageIO;
      import java.awt.*;
      import java.awt.font.FontRenderContext;
      import java.awt.geom.AffineTransform;
      import java.awt.geom.Rectangle2D;
      import java.awt.image.BufferedImage;
      import java.io.File;
      
      /**
       * @Author HOUJL
       * @Date 2022/4/25
       * @Description:
       */
      @Builder
      @Getter
      public class Seal {
      
          // 起始位置
          private static final int INIT_BEGIN = 5;
      
          // 尺寸
          private Integer size;
          // 颜色
          private Color color;
          // 主字
          private SealFont mainFont;
          // 副字
          private SealFont viceFont;
          // 抬头
          private SealFont titleFont;
          // 中心字
          private SealFont centerFont;
          // 边线圆
          private SealCircle borderCircle;
          // 内边线圆
          private SealCircle borderInnerCircle;
          // 内线圆
          private SealCircle innerCircle;
          // 边线框
          private Integer borderSquare;
          // 加字
          private String stamp;
      
          /**
           * 画公章
           */
          public boolean draw(String pngPath) throws Exception {
              if (borderSquare != null) {
                  return draw2(pngPath); // 画私章
              }
      
              //1.画布
              BufferedImage bi = new BufferedImage(size, size, BufferedImage.TYPE_4BYTE_ABGR);
      
              //2.画笔
              Graphics2D g2d = bi.createGraphics();
      
              //2.1抗锯齿设置
              //文本不抗锯齿,否则圆中心的文字会被拉长
              RenderingHints hints = new RenderingHints(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
              //其他图形抗锯齿
              hints.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
              g2d.setRenderingHints(hints);
      
              //2.2设置背景透明度
              g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC, 0));
      
              //2.3填充矩形
              g2d.fillRect(0, 0, size, size);
      
              //2.4重设透明度,开始画图
              g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC, 1));
      
              //2.5设置画笔颜色
              g2d.setPaint(color == null ? Color.RED : color);
      
              //3.画边线圆
              if (borderCircle != null) {
                  drawCircle(g2d, borderCircle, INIT_BEGIN, INIT_BEGIN);
              } else {
                  throw new Exception("BorderCircle can not null!");
              }
      
              int borderCircleWidth = borderCircle.getWidth();
              int borderCircleHeight = borderCircle.getHeight();
      
              //4.画内边线圆
              if (borderInnerCircle != null) {
                  int x = INIT_BEGIN + borderCircleWidth - borderInnerCircle.getWidth();
                  int y = INIT_BEGIN + borderCircleHeight - borderInnerCircle.getHeight();
                  drawCircle(g2d, borderInnerCircle, x, y);
              }
      
              //5.画内环线圆
              if (innerCircle != null) {
                  int x = INIT_BEGIN + borderCircleWidth - innerCircle.getWidth();
                  int y = INIT_BEGIN + borderCircleHeight - innerCircle.getHeight();
                  drawCircle(g2d, innerCircle, x, y);
              }
      
              //6.画弧形主文字
              if (borderCircleHeight != borderCircleWidth) {
                  drawArcFont4Oval(g2d, borderCircle, mainFont, true);
              } else {
                  drawArcFont4Circle(g2d, borderCircleHeight, mainFont, true);
              }
      
              //7.画弧形副文字
              if (borderCircleHeight != borderCircleWidth) {
                  drawArcFont4Oval(g2d, borderCircle, viceFont, false);
              } else {
                  drawArcFont4Circle(g2d, borderCircleHeight, viceFont, false);
              }
      
              //8.画中心字
              drawFont(g2d, (borderCircleWidth + INIT_BEGIN) * 2, (borderCircleHeight + INIT_BEGIN) * 2, centerFont);
      
              //9.画抬头文字
              drawFont(g2d, (borderCircleWidth + INIT_BEGIN) * 2, (borderCircleHeight + INIT_BEGIN) * 2, titleFont);
      
              g2d.dispose();
      
              return ImageIO.write(bi, "PNG", new File(pngPath));
          }
      
          /**
           * 绘制圆弧形文字
           */
          private static void drawArcFont4Circle(Graphics2D g2d, int circleRadius, SealFont font, boolean isTop) {
              if (font == null) {
                  return;
              }
      
              //1.字体长度
              int textLen = font.getText().length();
      
              //2.字体大小,默认根据字体长度动态设定
              int size = font.getSize() == null ? (55 - textLen * 2) : font.getSize();
      
              //3.字体样式
              int style = font.getBold() ? Font.BOLD : Font.PLAIN;
      
              //4.构造字体
              Font f = new Font(font.getFamily(), style, size);
      
              FontRenderContext context = g2d.getFontRenderContext();
              Rectangle2D rectangle = f.getStringBounds(font.getText(), context);
      
              //5.文字之间间距,默认动态调整
              double space;
              if (font.getSpace() != null) {
                  space = font.getSpace();
              } else {
                  if (textLen == 1) {
                      space = 0;
                  } else {
                      space = rectangle.getWidth() / (textLen - 1) * 0.9;
                  }
              }
      
              //6.距离外圈距离
              int margin = font.getMargin() == null ? INIT_BEGIN : font.getMargin();
      
              //7.写字
              double newRadius = circleRadius + rectangle.getY() - margin;
              double radianPerInterval = 2 * Math.asin(space / (2 * newRadius));
      
              double fix = 0.04;
              if (isTop) {
                  fix = 0.18;
              }
              double firstAngle;
              if (!isTop) {
                  if (textLen % 2 == 1) {
                      firstAngle = Math.PI + Math.PI / 2 - (textLen - 1) * radianPerInterval / 2.0 - fix;
                  } else {
                      firstAngle = Math.PI + Math.PI / 2 - ((textLen / 2.0 - 0.5) * radianPerInterval) - fix;
                  }
              } else {
                  if (textLen % 2 == 1) {
                      firstAngle = (textLen - 1) * radianPerInterval / 2.0 + Math.PI / 2 + fix;
                  } else {
                      firstAngle = (textLen / 2.0 - 0.5) * radianPerInterval + Math.PI / 2 + fix;
                  }
              }
      
              for (int i = 0; i < textLen; i++) {
                  double theta;
                  double thetaX;
                  double thetaY;
      
                  if (!isTop) {
                      theta = firstAngle + i * radianPerInterval;
                      thetaX = newRadius * Math.sin(Math.PI / 2 - theta);
                      thetaY = newRadius * Math.cos(theta - Math.PI / 2);
                  } else {
                      theta = firstAngle - i * radianPerInterval;
                      thetaX = newRadius * Math.sin(Math.PI / 2 - theta);
                      thetaY = newRadius * Math.cos(theta - Math.PI / 2);
                  }
      
                  AffineTransform transform;
                  if (!isTop) {
                      transform = AffineTransform.getRotateInstance(Math.PI + Math.PI / 2 - theta);
                  } else {
                      transform = AffineTransform.getRotateInstance(Math.PI / 2 - theta + Math.toRadians(8));
                  }
                  Font f2 = f.deriveFont(transform);
                  g2d.setFont(f2);
                  g2d.drawString(font.getText().substring(i, i + 1), (float) (circleRadius + thetaX + INIT_BEGIN),
                          (float) (circleRadius - thetaY + INIT_BEGIN));
              }
          }
      
          /**
           * 绘制椭圆弧形文字
           */
          private static void drawArcFont4Oval(Graphics2D g2d, SealCircle sealCircle, SealFont font, boolean isTop) {
              if (font == null) {
                  return;
              }
              float radiusX = sealCircle.getWidth();
              float radiusY = sealCircle.getHeight();
              float radiusWidth = radiusX + sealCircle.getLine();
              float radiusHeight = radiusY + sealCircle.getLine();
      
              //1.字体长度
              int textLen = font.getText().length();
      
              //2.字体大小,默认根据字体长度动态设定
              int size = font.getSize() == null ? 25 + (10 - textLen) / 2 : font.getSize();
      
              //3.字体样式
              int style = font.getBold() ? Font.BOLD : Font.PLAIN;
      
              //4.构造字体
              Font f = new Font(font.getFamily(), style, size);
      
              //5.总的角跨度
              double totalArcAng = font.getSpace() * textLen;
      
              //6.从边线向中心的移动因子
              float minRat = 0.90f;
      
              double startAngle = isTop ? -90f - totalArcAng / 2f : 90f - totalArcAng / 2f;
              double step = 0.5;
              int alCount = (int) Math.ceil(totalArcAng / step) + 1;
              double[] angleArr = new double[alCount];
              double[] arcLenArr = new double[alCount];
              int num = 0;
              double accArcLen = 0.0;
              angleArr[num] = startAngle;
              arcLenArr[num] = accArcLen;
              num++;
              double angR = startAngle * Math.PI / 180.0;
              double lastX = radiusX * Math.cos(angR) + radiusWidth;
              double lastY = radiusY * Math.sin(angR) + radiusHeight;
              for (double i = startAngle + step; num < alCount; i += step) {
                  angR = i * Math.PI / 180.0;
                  double x = radiusX * Math.cos(angR) + radiusWidth, y = radiusY * Math.sin(angR) + radiusHeight;
                  accArcLen += Math.sqrt((lastX - x) * (lastX - x) + (lastY - y) * (lastY - y));
                  angleArr[num] = i;
                  arcLenArr[num] = accArcLen;
                  lastX = x;
                  lastY = y;
                  num++;
              }
              double arcPer = accArcLen / textLen;
              for (int i = 0; i < textLen; i++) {
                  double arcL = i * arcPer + arcPer / 2.0;
                  double ang = 0.0;
                  for (int p = 0; p < arcLenArr.length - 1; p++) {
                      if (arcLenArr[p] <= arcL && arcL <= arcLenArr[p + 1]) {
                          ang = (arcL >= ((arcLenArr[p] + arcLenArr[p + 1]) / 2.0)) ? angleArr[p + 1] : angleArr[p];
                          break;
                      }
                  }
                  angR = (ang * Math.PI / 180f);
                  Float x = radiusX * (float) Math.cos(angR) + radiusWidth;
                  Float y = radiusY * (float) Math.sin(angR) + radiusHeight;
                  double qxang = Math.atan2(radiusY * Math.cos(angR), -radiusX * Math.sin(angR));
                  double fxang = qxang + Math.PI / 2.0;
      
                  int subIndex = isTop ? i : textLen - 1 - i;
                  String c = font.getText().substring(subIndex, subIndex + 1);
      
                  //获取文字高宽
                  FontMetrics fm = sun.font.FontDesignMetrics.getMetrics(f);
                  int w = fm.stringWidth(c), h = fm.getHeight();
      
                  if (isTop) {
                      x += h * minRat * (float) Math.cos(fxang);
                      y += h * minRat * (float) Math.sin(fxang);
                      x += -w / 2f * (float) Math.cos(qxang);
                      y += -w / 2f * (float) Math.sin(qxang);
                  } else {
                      x += (h * minRat) * (float) Math.cos(fxang);
                      y += (h * minRat) * (float) Math.sin(fxang);
                      x += w / 2f * (float) Math.cos(qxang);
                      y += w / 2f * (float) Math.sin(qxang);
                  }
      
                  // 旋转
                  AffineTransform affineTransform = new AffineTransform();
                  affineTransform.scale(0.8, 1);
                  if (isTop) {
                      affineTransform.rotate(Math.toRadians((fxang * 180.0 / Math.PI - 90)), 0, 0);
                  } else {
                      affineTransform.rotate(Math.toRadians((fxang * 180.0 / Math.PI + 180 - 90)), 0, 0);
                  }
                  Font f2 = f.deriveFont(affineTransform);
                  g2d.setFont(f2);
                  g2d.drawString(c, x.intValue() + INIT_BEGIN, y.intValue() + INIT_BEGIN);
              }
          }
      
          /**
           * 画文字
           */
          private static void drawFont(Graphics2D g2d, int circleWidth, int circleHeight, SealFont font) {
              if (font == null) {
                  return;
              }
      
              //1.字体长度
              int textLen = font.getText().length();
      
              //2.字体大小,默认根据字体长度动态设定
              int size = font.getSize() == null ? (55 - textLen * 2) : font.getSize();
      
              //3.字体样式
              int style = font.getBold() ? Font.BOLD : Font.PLAIN;
      
              //4.构造字体
              Font f = new Font(font.getFamily(), style, size);
              g2d.setFont(f);
      
              FontRenderContext context = g2d.getFontRenderContext();
              String[] fontTexts = font.getText().split("\n");
              if (fontTexts.length > 1) {
                  int y = 0;
                  for (String fontText : fontTexts) {
                      y += Math.abs(f.getStringBounds(fontText, context).getHeight());
                  }
                  //5.设置上边距
                  float margin = INIT_BEGIN + (float) (circleHeight / 2 - y / 2);
                  for (String fontText : fontTexts) {
                      Rectangle2D rectangle2D = f.getStringBounds(fontText, context);
                      g2d.drawString(fontText, (float) (circleWidth / 2 - rectangle2D.getCenterX()), margin);
                      margin += Math.abs(rectangle2D.getHeight());
                  }
              } else {
                  Rectangle2D rectangle2D = f.getStringBounds(font.getText(), context);
                  //5.设置上边距,默认在中心
                  float margin = font.getMargin() == null ?
                          (float) (circleHeight / 2 - rectangle2D.getCenterY()) :
                          (float) (circleHeight / 2 - rectangle2D.getCenterY()) + (float) font.getMargin();
                  g2d.drawString(font.getText(), (float) (circleWidth / 2 - rectangle2D.getCenterX()), margin);
              }
          }
      
          /**
           * 画圆
           */
          private static void drawCircle(Graphics2D g2d, SealCircle circle, int x, int y) {
              if (circle == null) {
                  return;
              }
      
              //1.圆线条粗细默认是圆直径的1/35
              int lineSize = circle.getLine() == null ? circle.getHeight() * 2 / (35) : circle.getLine();
      
              //2.画圆
              g2d.setStroke(new BasicStroke(lineSize));
              g2d.drawOval(x, y, circle.getWidth() * 2, circle.getHeight() * 2);
          }
      
          /**
           * 画私章
           */
          public boolean draw2(String pngPath) throws Exception {
              if (mainFont == null || mainFont.getText().length() < 2 || mainFont.getText().length() > 4) {
                  throw new IllegalArgumentException("请输入2-4个字");
              }
      
              int fixH = 18;
              int fixW = 2;
      
              //1.画布
              BufferedImage bi = new BufferedImage(size, size / 2, BufferedImage.TYPE_4BYTE_ABGR);
      
              //2.画笔
              Graphics2D g2d = bi.createGraphics();
      
              //2.1设置画笔颜色
              g2d.setPaint(Color.RED);
      
              //2.2抗锯齿设置
              g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
      
              //3.写签名
              int marginW = fixW + borderSquare;
              float marginH;
              FontRenderContext context = g2d.getFontRenderContext();
              Rectangle2D rectangle;
              Font f;
      
              if (mainFont.getText().length() == 2) {
                  if (stamp != null && stamp.trim().length() > 0) {
                      bi = drawThreeFont(bi, g2d, mainFont.append(stamp), borderSquare, size, fixH, fixW, true);
                  } else {
                      f = new Font(mainFont.getFamily(), Font.BOLD, mainFont.getSize());
                      g2d.setFont(f);
                      rectangle = f.getStringBounds(mainFont.getText().substring(0, 1), context);
                      marginH = (float) (Math.abs(rectangle.getCenterY()) * 2 + marginW) + fixH - 4;
                      g2d.drawString(mainFont.getText().substring(0, 1), marginW, marginH);
                      marginW += Math.abs(rectangle.getCenterX()) * 2 + (mainFont.getSpace() == null ? INIT_BEGIN : mainFont.getSpace());
                      g2d.drawString(mainFont.getText().substring(1), marginW, marginH);
      
                      //拉伸
                      BufferedImage nbi = new BufferedImage(size, size, bi.getType());
                      Graphics2D ng2d = nbi.createGraphics();
                      ng2d.setPaint(Color.RED);
                      ng2d.drawImage(bi, 0, 0, size, size, null);
      
                      //画正方形
                      ng2d.setStroke(new BasicStroke(borderSquare));
                      ng2d.drawRect(0, 0, size, size);
                      ng2d.dispose();
                      bi = nbi;
                  }
              } else if (mainFont.getText().length() == 3) {
                  if (stamp != null && stamp.trim().length() > 0) {
                      bi = drawFourFont(bi, mainFont.append(stamp), borderSquare, size, fixH, fixW);
                  } else {
                      bi = drawThreeFont(bi, g2d, mainFont, borderSquare, size, fixH, fixW, false);
                  }
              } else {
                  bi = drawFourFont(bi, mainFont, borderSquare, size, fixH, fixW);
              }
      
              g2d.dispose();
      
              return ImageIO.write(bi, "PNG", new File(pngPath));
          }
      
          /**
           * 画三字
           */
          private static BufferedImage drawThreeFont(BufferedImage bi, Graphics2D g2d, SealFont font, int lineSize, int imageSize, int fixH,
                                                     int fixW, boolean isWithYin) {
              fixH -= 9;
              int marginW = fixW + lineSize;
              //设置字体
              Font f = new Font(font.getFamily(), Font.BOLD, font.getSize());
              g2d.setFont(f);
              FontRenderContext context = g2d.getFontRenderContext();
              Rectangle2D rectangle = f.getStringBounds(font.getText().substring(0, 1), context);
              float marginH = (float) (Math.abs(rectangle.getCenterY()) * 2 + marginW) + fixH;
              int oldW = marginW;
      
              if (isWithYin) {
                  g2d.drawString(font.getText().substring(2, 3), marginW, marginH);
                  marginW += rectangle.getCenterX() * 2 + (font.getSpace() == null ? INIT_BEGIN : font.getSpace());
              } else {
                  marginW += rectangle.getCenterX() * 2 + (font.getSpace() == null ? INIT_BEGIN : font.getSpace());
                  g2d.drawString(font.getText().substring(0, 1), marginW, marginH);
              }
      
              //拉伸
              BufferedImage nbi = new BufferedImage(imageSize, imageSize, bi.getType());
              Graphics2D ng2d = nbi.createGraphics();
              ng2d.setPaint(Color.RED);
              ng2d.drawImage(bi, 0, 0, imageSize, imageSize, null);
      
              //画正方形
              ng2d.setStroke(new BasicStroke(lineSize));
              ng2d.drawRect(0, 0, imageSize, imageSize);
              ng2d.dispose();
              bi = nbi;
      
              g2d = bi.createGraphics();
              g2d.setPaint(Color.RED);
              g2d.setFont(f);
              g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
      
              if (isWithYin) {
                  g2d.drawString(font.getText().substring(0, 1), marginW, marginH += fixH);
                  rectangle = f.getStringBounds(font.getText(), context);
                  marginH += Math.abs(rectangle.getHeight());
                  g2d.drawString(font.getText().substring(1), marginW, marginH);
              } else {
                  g2d.drawString(font.getText().substring(1, 2), oldW, marginH += fixH);
                  rectangle = f.getStringBounds(font.getText(), context);
                  marginH += Math.abs(rectangle.getHeight());
                  g2d.drawString(font.getText().substring(2, 3), oldW, marginH);
              }
              return bi;
          }
      
          /**
           * 画四字
           */
          private static BufferedImage drawFourFont(BufferedImage bi, SealFont font, int lineSize, int imageSize, int fixH, int fixW) {
              int marginW = fixW + lineSize;
              //拉伸
              BufferedImage nbi = new BufferedImage(imageSize, imageSize, bi.getType());
              Graphics2D ng2d = nbi.createGraphics();
              ng2d.setPaint(Color.RED);
              ng2d.drawImage(bi, 0, 0, imageSize, imageSize, null);
      
              //画正方形
              ng2d.setStroke(new BasicStroke(lineSize));
              ng2d.drawRect(0, 0, imageSize, imageSize);
              ng2d.dispose();
              bi = nbi;
      
              Graphics2D g2d = bi.createGraphics();
              g2d.setPaint(Color.RED);
              g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
              FontRenderContext context = g2d.getFontRenderContext();
      
              Font f = new Font(font.getFamily(), Font.BOLD, font.getSize());
              g2d.setFont(f);
              Rectangle2D rectangle = f.getStringBounds(font.getText().substring(0, 1), context);
              float marginH = (float) (Math.abs(rectangle.getCenterY()) * 2 + marginW) + fixH;
      
              g2d.drawString(font.getText().substring(2, 3), marginW, marginH);
              int oldW = marginW;
              marginW += Math.abs(rectangle.getCenterX()) * 2 + (font.getSpace() == null ? INIT_BEGIN : font.getSpace());
      
              g2d.drawString(font.getText().substring(0, 1), marginW, marginH);
              marginH += Math.abs(rectangle.getHeight());
      
              g2d.drawString(font.getText().substring(3, 4), oldW, marginH);
      
              g2d.drawString(font.getText().substring(1, 2), marginW, marginH);
      
              return bi;
          }
      }
      

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

印章生成工具类开发 的相关文章

  • 使用 objectGUID 进行查询 - Spring LDAP 模板

    我正在尝试获取 存储并依次使用 objectGUID 来查询 Active Directory 为了获取用户属性我正在使用以下 public static class MyDnKeyValueAttMapper implements Att
  • 哪个类调用了我的静态方法?

    假设我有一个带有静态方法的 Java 类 如下所示 class A static void foo Which class invoked me 进一步假设 A 类有任意数量的子类 class B extends A class C ext
  • 不同的 JDK 更新会产生不同的 Java 字节码吗?

    假设场景 我有一个项目 其源合规性级别指定为 1 5 现在 我使用两种不同的 JDK 编译此项目 首先使用 JDK 6 Update 7 然后使用 JDK 6 Update 20 这两个不同的 JDK 是否会生成不同的 Java 字节代码
  • 在 MongoDB Java 驱动程序中如何使用 $filter

    我有一个适用于 MQL 的查询 我需要将其翻译成Java MQL 中的查询如下所示 db
  • 使用 Spring MVC 返回 PDF 文件

    实际上 我有这个功能 我有一个框架 可以在其中设置 URL ip port birt preview report report rptdesign format pdf parameters 并且该框架呈现 PDF 文件 但我想隐藏该网址
  • 从 Bitmap 类创建 .bmp 图像文件

    我创建了一个使用套接字的应用程序 客户端在其中接收图像并将图像数据存储在 Bitmap 类中 谁能告诉我如何创建一个名为我的图像 png or 我的图像 bmp来自此 Bitmap 对象 String base64Code dataInpu
  • 将 JSON Map 传递到 Spring MVC 控制器

    我正在尝试将 Map 的 JSON 表示形式作为 POST 参数发送到我的控制器中 RequestMapping value search do method RequestMethod GET consumes application j
  • 隐藏类的 System.out.print 调用

    我正在使用 java 库 jar 文件 该文件的作者放入了一堆System out print and System out printlns 有没有办法隐藏特定对象的这些消息 编辑 看起来jar文件似乎正在创建一堆线程 并且每个线程都有它
  • 适用于 Solaris 的 Java 8 中缺少 javaws

    看起来 Oracle 从 Java 8 for Solaris 中删除了 Java Web Start javaws 在 Java 8u51 中不再可用 来自兼容性指南 http www oracle com technetwork jav
  • 我需要显式关闭连接吗?

    我持有一个实例MongoClient and DB在我的应用程序中 每次我想执行某些操作时 我都会调用getCollection 我想知道是否需要显式关闭连接 就像connection close 在 JDBC 中 强调一下 我只有一个Mo
  • Java 反射:如何检索匿名内部类?

    我在另一个类中有一个匿名内部类 SomeClass Both SomeClass class getClasses and SomeClass class getDeclaredClasses 返回空数组 我在中找不到一些关于此的提示Cla
  • 将多个视频文件合并到一个文件中

    我有多个以相同帧速率和分辨率录制的视频 我想将两个视频合并为一个视频 因此结果文件将是大视频 我正在使用 MP4 解析器 api 并使用下面的代码 Movie countVideo new MovieCreator build Channe
  • perl 和 java 正则表达式功能之间有什么区别?

    perl 和 java 在支持哪些正则表达式术语方面有什么区别 这个问题仅涉及正则表达式 并且特别排除了how可以使用正则表达式 即使用正则表达式的可用函数 方法 以及语言之间的语法差异 例如java要求转义反斜杠等 特别令人感兴趣的是 j
  • 我们必须将 .class 文件放在 Tomcat 目录中的位置

    我必须把我的 class文件在 Tomcat 目录中 在我的 Java Complete Reference 书中 他们告诉将其放入C Program Files Apache Tomcat 4 0 webapps examples WEB
  • 设置 JAVA_HOME 变量时出现问题

    所以我刚刚下载了 Android Studio 并尝试设置 JAVA HOME 变量以便我可以运行它 我使用的是 Windows 8 并按照我找到的所有说明进行操作 但无济于事 转到高级系统设置 gt 环境变量 然后使用包含我的 jre7
  • 计算移动的球与移动的线/多边形碰撞的时间(2D)

    我有一个多边形 里面有一个移动的球 如果球撞到边界 它应该反弹回来 My current solution I split the polygon in lines and calculate when the ball hits the
  • 如何配置嵌入式 MongoDB 以在 Spring Boot 应用程序中进行集成测试?

    我有一个相当简单的 Spring Boot 应用程序 它公开一个小型 REST API 并从 MongoDB 实例检索数据 对 MongoDB 实例的查询通过基于 Spring Data 的存储库 下面的一些关键代码 Main applic
  • 如何修改生成的SOAP请求?

    我正处于创建输出拦截器并从 SOAP 消息中获取 OuputStream 的阶段 但是 如何在将 SOAP 信封发送到端点之前对其进行修改呢 我想删除一些 xml 元素 一种方法是获取文档并通过 XSLT 转换运行它 您可以通过调用来获取拦
  • 如何隐藏或删除 Android HoneyComb 中的状态栏?

    如何隐藏或删除 Android HoneyComb 中的状态栏 每次运行应用程序时 我都会发现某些内容必须被状态栏覆盖 我尝试改变AndroidManifest xml 但没有任何改变 你不知道 它被认为是永久的屏幕装饰 就像电容式主页 菜
  • Java,如何管理线程读取socket(websocket)?

    我有一个 WebSocket 服务器 我的服务器创建一个新线程来处理新连接 该线程一直处于活动状态 直到 websocket 中断 我的问题 对于 1 000 000 个连接 我需要 1 000 000 个线程 我如何通过一个线程处理多个

随机推荐

  • 自制GUI

    包含了 sqlmap GUI Xray GUI dirmap GUI
  • selenium测试框架快速搭建(UI自动化测试)

    一 介绍 selenium目前主流的web自动化测试框架 支持多种编程语言Java pythan go js等 selenium 提供一系列的api 供我们使用 因此在web测试时我们要点页面中的某一个按钮 那么我们只需要获取页面 然后根据
  • js控制获得焦点与失去焦点样式

    function focusInput focusClass normalClass var elements document getElementsByTagName input for var i 0 i lt elements le
  • Vue项目保存代码之后页面自动更新

    Vue项目保存代码之后页面自动更新 想要在代码中保存之后 页面自动刷新 命令行敲如下代码 npm install webpack dev server 下载了这个东西就不用每次都手动刷新了 我也不知道这个是干嘛的 留在以后研究研究
  • Chromium OS autotest

    autotest三种主要测试手段 直接调用系统命令 相当于直接运行shell命令 通过dbus进行method call 通过加载插件到browser的方式 运行js代码 以js代码来调用C 方法 通过extension来运行js代码 目的
  • XSS闯关——第五关:level5

    第五关 level5 输入语句测试 gt 观察源代码发现字符被替换 把部分字符换成大写尝试 gt 一样的结果 采用html事件方法 失败 同样是字符被替换 使用伪链接方式假造一个超链接尝试 gt a href link a 点击后执行脚本
  • Laravel Collection 常用方法(1)

    我的个人博客 逐步前行STEP 1 first 返回集合第一个通过指定测试的元素 collect 1 2 3 4 gt first 1 collect 1 2 3 4 gt first function value key return v
  • 深度学习deep learning

    一 简介 深度学习是包含多个隐层的机器学习模型 核心是基于训练的方式 从海量数据中挖掘有用信息 实现分类与预测 早期的深度学习模型 编码器 循环神经网络 深度置信网络 卷积神经网络 衍生模型 堆叠降噪自编码器 稀疏自编码器 降噪自编码器 深
  • mysql 集成测试_使用Go进行集成测试的MySQL Docker容器

    使用Go进行集成测试的MySQL Docker容器 原文链接 https itnext io mysql docker container for integration testing using go f784b70a03b 作者 Mi
  • 【Linux】在Xilinx平台上实现UVC Gadget(2)- 解决dwc3驱动bug

    Linux 在Xilinx平台上实现UVC Gadget 2 解决dwc3驱动bug 一 bug描述 二 具体修改方法 1 找到内核源码位置并复制到其他目录 2 Petalinux里面设置使用自定义内核源码 1 选第2个Linux Comp
  • 数列分段

    描述 对于给定的一个长度为N的正整数数列A i 现要将其分成M M N 段 并要求每段连续 且每段和的最大值最小 关于最大值最小 例如一数列4 2 4 5 1要分成3段 将其如下分段 4 2 4 5 1 第一段和为6 第2段和为9 第3段和
  • MySQL查询语句的执行顺序

    SQL语句执行顺序 FROM ON JOIN WHERE GROUP BY AGG FUNC WITH HAVING SELECT UNION DISTINCT ORDER BY LIMIT 在实际执行过程中 每个步骤都会为下一个步骤生成一
  • [django项目] 后台菜单管理功能

    后台菜单管理功能 菜单的管理功能其实就是 对菜单的增删改查 I 业务功能分析 1 gt 业务需求分析 后台首页菜单根据用户权限动态生成 不同菜单对应不同的功能视图 菜单的增删改查 2 gt 功能分析 菜单列表 添加菜单 修改菜单 删除菜单
  • Python Tree库绘制多叉树的用法介绍

    Python Tree库绘制多叉树的用法介绍 Tree 库是一个 Python 的第三方库 这个库主要用于生成树和绘制树的图形 一 安装Tree pip install Tree 使用 Tree 库需要配合 PIL 库来实现绘图 二 官方案
  • Qt控件之QCheckBox复选框控件使用详解

    Qt控件之QCheckBox复选框控件使用详解 在Qt的控件中 QCheckBox是常用的一种复选框控件 用于用户进行多选操作 本篇文章将为大家详细介绍QCheckBox的使用方法 一 QCheckBox控件的创建 在Qt中创建QCheck
  • Windows下配置 MinGW - Gcc、G++构建C++编译环境,并在Notepad++编写C++程序

    win10 64位系统参考博文 MinGW w64安装教程 著名C C 编译器GCC的Windows版本 工具 win7 Notepad MinGW MinGW是什么 MinGW 提供了一套简单方便的Windows下的基于GCC 程序开发环
  • spark的安装与部署

    目录 前言 一 spark是什么 二 知识回顾 1 启动zookeeper 2 启动hdfs和yarn 3 通过jps查看是否启动成功 4 进入MySQL 5 进入hive之后验证 6 启动hbase 7 查看进程 8 进入hbase并测试
  • 数值的整数次方(剑指offer 16)Java快速幂

    目录 一 题目描述 二 思路讲解 三 Java代码实现 四 时空复杂度分析 五 另一种方法 一 题目描述 实现 pow x n 即计算 x 的 n 次幂函数 即 xn 不得使用库函数 同时不需要考虑大数问题 示例 1 输入 x 2 0000
  • GPIO应用编程

    开发平台 正点原子阿尔法开发板 PS 可以用cat sys kernel debug gpio命令查看引脚被占用情况 文章目录 GPIO应用编程 编程步骤 应用编程 遇到的问题 GPIO应用编程 sys class gpio export
  • 印章生成工具类开发

    Java代码见我的资源 免费使用印章生成工具类 Java开发 Java文档类资源 CSDN下载印章生成工具类 Java开发更多下载资源 学习资料请访问CSDN下载频道 https download csdn net download jlo