java生成企业公章图片源代码

发布时间 2024-01-08 16:38:04作者: 想做技术的销售

企业公章图片在电子签章业务中应用广泛,在电子签章应用过程中首先需要生成公章图片,然后再使用公章图片结合数字签名技术完成电子签,这样就实现了从可视化到不可篡改的数字化电子签章功能,以下是企业公章图片生成源代码。
`​
import com.resrun.utils.Base64;
import org.apache.pdfbox.io.IOUtils;
import org.springframework.stereotype.Service;

import javax.imageio.ImageIO;
import java.awt.;
import java.awt.image.BufferedImage;
import java.io.
;

/**

  • @Description: 企业签章业务

  • @Package: com.resrun.service.image

  • @ClassName: EntSealGenerateService

  • @copyright 北京资源律动科技有限公司
    */
    @Service
    public class EntSealGenerateService {

    /**

    • @Description #生成企业签章

    • @Param [topText, middleText]

    • @return byte[]
      **/
      public byte[] generateEntSeal(String topText,String middleText){

      byte[] bytes = export2pic("png", middleText,topText);
      return bytes;
      }

    /**

    • 印章名称距中心点偏移量,按照y轴方向
      /
      private int nameOffset = 50;
      /
      *
    • 印章宽度
      /
      private int width = 200;
      /
      *
    • 印章高度
      /
      private int height = 200;
      /
      *
    • 印章中心标志(默认为五角星)外接圆半径
      /
      private float radius = 30;
      /
      *
    • 印章名称颜色
      /
      private Color nameColor = Color.RED;
      /
      *
    • 印章所属单位
      /
      // private String firm;
      /
      *
    • 印章所属单位颜色
      /
      private Color firmColor = Color.RED;
      private float firmScale = 0.7F;
      /
      *
    • 边框线宽
      /
      private float borderWidth = 5F;
      /
      *
    • 边框颜色
      /
      private Color borderColor = Color.RED;
      /
      *
    • 印章标记(默认为五角星)线宽
      /
      private float signBorderWidth = 3F;
      /
      *
    • 印章标记颜色
      /
      private Color signBorderColor = Color.RED;
      /
      *
    • 印章标记填充颜色
      */
      private Color signFillColor = Color.RED;

    public void draw(Graphics2D g2d,String middleText,String topText) {
    // 把绘制起点挪到圆中心点
    g2d.translate(width / 2, height / 2);

     Stroke stroke = g2d.getStroke();// 旧的线性
     // 填充五角星
     Polygon polygon = getPentaclePoints(radius);
     if (signFillColor != null) {
         g2d.setColor(signFillColor);
         g2d.fill(polygon);
     }
     // 绘制五角星边框
     g2d.setStroke(new BasicStroke(signBorderWidth));
     g2d.setColor(signBorderColor);
     g2d.draw(polygon);
    
     // 绘制印章边框
     g2d.setFont(nameFont);
     g2d.setColor(borderColor);
     g2d.setStroke(new BasicStroke(borderWidth));
     g2d.drawOval(-width / 2, -height / 2, width, height);
     g2d.setStroke(stroke);
    
     // 绘制印章名称
     g2d.setFont(nameFont);
     g2d.setColor(nameColor);   //g2d.setStroke(new BasicStroke(10F));
     FontMetrics fm = g2d.getFontMetrics();
     int w = fm.stringWidth(middleText);// 名称宽度
     int h = fm.getHeight();// 名称高度
     int y = fm.getAscent() - h / 2;// 求得中心线经过字体的高度的一半时的字体的起绘点
     g2d.drawString(middleText, -w / 2, y + nameOffset);
    
     // 绘制印章单位
     g2d.setFont(getFirmFont(topText));
     g2d.setColor(firmColor);
     fm = g2d.getFontMetrics();
     h = fm.getHeight();// 字高度
    
     int count = topText.length();// 字数
     int r = width / 2;// 半径,就假设此印章是个矩形,方便计算
     float angle;
     float start;
    
     if(count>1 && count <=10){
         angle = 20f;// 字间角度
         start = 90+(360 - angle*(count-1))/2;// 以x轴正向为0,顺时针旋转
     }else if(count > 10){
         angle = (360 - firmAngle) / (count-1);// 字间角度
         start = 90+(360 - angle*(count-1))/2;// 以x轴正向为0,顺时针旋转
     }else{
         angle = 0f;// 字间角度
         start = 90+(360 - angle*(2-1))/2;// 以x轴正向为0,顺时针旋转
     }
     double vr = Math.toRadians(90);// 垂直旋转弧度
     char[] chars = topText.toCharArray();
     for (int i = 0; i < count; i++) {
         char c = chars[i];// 需要绘制的字符
         int cw = fm.charWidth(c);// 此字符宽度
         float a = start + angle * i;// 现在角度
         double radians = Math.toRadians(a);
         g2d.rotate(radians);// 旋转坐标系,让要绘制的字符处于x正轴
         float x = r - h;// 绘制字符的x坐标为半径减去字高度
         g2d.translate(x, 0);// 移动到此位置,此时字和x轴垂直
         g2d.rotate(vr);// 旋转90度,让字平行于x轴
         g2d.scale(firmScale, 1);// 缩放字体宽度
         g2d.drawString(String.valueOf(c), -cw / 2, 0);// 此点为字的中心点
         // 将所有设置还原,等待绘制下一个
         g2d.scale(1 / firmScale, 1);
         g2d.rotate(-vr);
         g2d.translate(-x, 0);
         g2d.rotate(-radians);
     }
     g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    

    }

    /**

    • 获取具有指定半径外接圆的五角星顶点
    • @param radius
    •        圆半径
      

    */
    private Polygon getPentaclePoints(float radius) {
    if (radius <= 0)
    return null;
    float lradius = radius * 0.381966f;// 根据radius求内圆半径
    double halfpi = Math.PI / 180f;
    Point[] points = new Point[10];
    for (int i = 0; i < points.length; i++) {
    if (i % 2 == 1)
    points[i] = new Point(
    (int) (Math.sin(halfpi * 36 * i) * radius),
    (int) (Math.cos(halfpi * 36 * i) * radius));
    else
    points[i] = new Point(
    (int) (Math.sin(halfpi * 36 * i) * lradius),
    (int) (Math.cos(halfpi * 36 * i) * lradius));
    }
    Polygon polygon = new Polygon();
    for (Point p : points) {
    polygon.addPoint(p.x, p.y);
    }
    return polygon;
    }

    public int getWidth() {
    return width;
    }

    public int getHeight() {
    return height;
    }

    private Font nameFont = new Font("宋体", Font.PLAIN, 19);

    private Font getFirmFont(String topText){
    Font font = null;
    int len = topText.length();
    System.out.println(len);
    if(len==1){
    setFirmAngle(355);
    font = new Font("宋体", Font.PLAIN, 25);
    }else if(len>1 && len<=3){
    setFirmAngle(310);
    font = new Font("宋体", Font.PLAIN, 25);
    }else if(len>3 && len<=6){
    setFirmAngle(250);
    font = new Font("宋体", Font.PLAIN, 25);
    }else if(len>6 && len <=10){
    setFirmAngle(200);
    font = new Font("宋体", Font.PLAIN, 25);
    }else if(len>10 && len<=13){
    setFirmAngle(180);
    font = new Font("宋体", Font.PLAIN, 25);
    }
    else if(len>13 && len<=20){
    font = new Font("宋体", Font.PLAIN, 25);
    setFirmAngle(120);
    }else if(len>20 && len <= 25){
    font = new Font("宋体", Font.PLAIN, 23);

         setFirmAngle(80);
     }else if(len>25 && len < 30){
         setFirmAngle(80);
         font = new Font("宋体", Font.PLAIN, 19);
     }else if(len>=30 && len <= 40){
         setFirmAngle(80);
         font = new Font("宋体", Font.PLAIN, 19);
     }else{
         setFirmAngle(10);
         font = new Font("宋体", Font.PLAIN, 17);
     }
     return font;
    

    }

    private int firmAngle;
    public void setFirmAngle(int firmAngle){
    this.firmAngle = firmAngle;
    }

    /**

    • 导出此印章为透明背景的图片字节数组.
    • @param format
    •        图片类型,如果为null,则默认为png
      
    • @return 数组
    • @throws FileNotFoundException
    • @throws IOException
    •         写出图像数据出现问题
      

    */
    public byte[] export2pic(String format,String middleText,String topText) {
    int fix = 5;// 宽高修正,如果宽高就为图片宽高,可能边框线被切割
    BufferedImage bi = new BufferedImage(getWidth() + fix * 2, getHeight()
    + fix * 2, 3);

     Graphics2D g2d = bi.createGraphics();
     //防锯齿状毛刺算法
     g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
     g2d.translate(fix, fix);
     draw(g2d,middleText,topText);
    
     ByteArrayOutputStream baos = new ByteArrayOutputStream();
     try {
         ImageIO.write(bi, format == null ? "png" : format, baos);
         return baos.toByteArray();
     } catch (IOException e) {
         throw new RuntimeException(topText+":生成企业签章失败",e);
     }finally {
         try {
             if(baos!=null)
                 baos.close();
         } catch (IOException e) {
         }
     }
    

    }
    }

​`