首页>代码>java 2d生成指定文字的电子印章图片>/生成电子签章/src/SealUtils.java
import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.font.FontRenderContext;
import java.awt.geom.AffineTransform;
import java.awt.geom.Arc2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

import javax.imageio.ImageIO;


public class SealUtils {
	private static final int CANVAS_SIZE = 300; // 画布宽

	private static final String FONT_FAMILY = "宋体"; // 字体
	//private static final String FOOT_TXT = "电子签约专用章";// 底部文字
	private static final String FOOT_TXT = "我家特有章";// 底部文字
	private static final String STAR = "★";


	private static int STAR_SIZE = (int) (CANVAS_SIZE / 3.2); // 五角星大小
	private static int FOOT_FONT_SIZE = CANVAS_SIZE / 12; // 底部文字大小
/**
 * 根据companyName获得合同专用章 
 * @param companyName
 * @return
*/
	public static BufferedImage genSealImage(String companyName) {
		 BufferedImage bi = new BufferedImage(CANVAS_SIZE, CANVAS_SIZE, BufferedImage.TYPE_4BYTE_ABGR);
		 Graphics2D g2d = bi.createGraphics();
		 g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC, 0));
		 g2d.fillRect(0, 0, CANVAS_SIZE, CANVAS_SIZE);
		
		
		 g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC, 1));
		 int circleRadius = CANVAS_SIZE / 2 - 10;
		 drawCicle(g2d, circleRadius);
		 drawStar(g2d, circleRadius);
		 drawFootText(g2d, circleRadius);
		 drwaHeadText(companyName, g2d, circleRadius);


          g2d.dispose();
          return bi;
          }

 public static void main(String[] args) {
    try {
		String name="我的印章";
			byte[] img= SealUtils.genSealData(name);
			byte2File(img,"E:\\生成电子章\\",name+".png");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

/**
     * 辅助方法,byte数组保存为本地文件
     * @param buf
     * @param filePath
     * @param fileName
     */
 private static void byte2File(byte[] buf, String filePath, String fileName)
{
 BufferedOutputStream bos = null;
 FileOutputStream fos = null;
 File file = null;
try
{
 File dir = new File(filePath);
 if (!dir.exists())
  {
   dir.mkdirs();
		}
			file = new File(filePath + File.separator + fileName);
			 fos = new FileOutputStream(file);
			 bos = new BufferedOutputStream(fos);
			 bos.write(buf);
			 }
		catch (Exception e)
		{
			e.printStackTrace();
}
	finally
	   {
		if (bos != null)
			{
		try
			{
			bos.close();
	}
		catch (IOException e)
		{
			 e.printStackTrace();
			}
		}
		 if (fos != null)
	{
		try
			{
			 fos.close();
	}
		catch (IOException e)
			 {
			     e.printStackTrace();
             }
		}
	  }
  }


/**
     * 根据companyName获得合同专用章
     * 
     * @param companyName
     * @return
     * @throws IOException
     */
 public static byte[] genSealData(String companyName) throws IOException {
		 BufferedImage image = genSealImage(companyName);
		 ByteArrayOutputStream outStream = new ByteArrayOutputStream();
 		try {
 				ImageIO.write(image, "png", outStream);
 }
 		catch (IOException e) {
 			throw e;
 			}
 		finally {
 			try {
 				outStream.close();
 				}
 			catch (IOException e) {
}
}
 		byte[] imageData = outStream.toByteArray();
 		return imageData;
 }

/**
     * 弧形绘制顶部名称
     * 
     * @param companyName
     * @param g2d
     * @param circleRadius
     */
 private static void drwaHeadText(String companyName, Graphics2D g2d, int circleRadius) {
		 int companyNameLen = companyName.length();
		 int headFontSize;
	 if (companyNameLen < 8) { // 字体根据画布大小微调出来的
		 headFontSize = 47;
	}
	else {
		 headFontSize = 43 - (companyNameLen - 8) * 2;
	}

		
		 Font f;
		 FontRenderContext context;
		 Rectangle2D rectangle;
		 f = new Font(FONT_FAMILY, Font.PLAIN, headFontSize);
		 context = g2d.getFontRenderContext();
		 rectangle = f.getStringBounds(companyName, context);


		 	double interval; // 文字之间间距
	if (companyNameLen == 1) {
		interval = 0;
 }
	else {
		interval = rectangle.getWidth() / (companyNameLen - 1) * 0.9;
}


	 double newRadius = circleRadius + rectangle.getY() - 10; // bounds.getY()是负数,这样可以将弧形文字固定在圆内了。-10目的是离圆环稍远一点
	 double radianPerInterval = 2 * Math.asin(interval / (2 * newRadius)); // 每个间距对应的角度


// 第一个元素的角度
 double firstAngle;
 if (companyNameLen % 2 == 1) {
 firstAngle = (companyNameLen - 1) * radianPerInterval / 2.0 + Math.PI / 2 + 0.18; // 0.18是浮点计算误差,如果文字不对称,可以微调
 }
else {
 firstAngle = (companyNameLen / 2.0 - 1) * radianPerInterval + radianPerInterval / 2.0 + Math.PI / 2 + 0.18;
 }


 for (int i = 0; i < companyNameLen; i++) {
		 double theta = firstAngle - i * radianPerInterval;
		 double thetaX = newRadius * Math.sin(Math.PI / 2 - theta); // 小小的trick,将【0,pi】区间变换到[pi/2,-pi/2]区间
		 double thetaY = newRadius * Math.cos(theta - Math.PI / 2); // 同上类似,这样处理就不必再考虑正负的问题了
		 AffineTransform transform = AffineTransform.getRotateInstance(Math.PI / 2 - theta);
		 Font f2 = f.deriveFont(transform);
		 g2d.setFont(f2);
		 g2d.drawString(companyName.substring(i, i + 1), (float) (circleRadius + thetaX + 10), (float) (circleRadius - thetaY + 10));
		 }
 }


 /**
     * 画底部文字
     * 
     * @param g2d
     * @param circleRadius
     */
 private static void drawFootText(Graphics2D g2d, int circleRadius) {
 Font f;
 FontRenderContext context;
 Rectangle2D rectangle;
 f = new Font(FONT_FAMILY, Font.BOLD, FOOT_FONT_SIZE);
 context = g2d.getFontRenderContext();
 rectangle = f.getStringBounds(FOOT_TXT, context);
int a = 10 * CANVAS_SIZE / 350; // 底部文字距中心的距离,这是调出来的
 g2d.setFont(f);
 g2d.drawString(FOOT_TXT, (float) (circleRadius + a - rectangle.getCenterX()), (float) (circleRadius * 1.5 + a - rectangle.getCenterY()));
}


 /**
     * 画中心的 ★
     * 
     * @param g2d
     * @param circleRadius
     */
private static void drawStar(Graphics2D g2d, int circleRadius) {
 Font f = new Font(FONT_FAMILY, Font.PLAIN, STAR_SIZE);
 FontRenderContext context = g2d.getFontRenderContext();
 Rectangle2D rectangle = f.getStringBounds(STAR, context);
 g2d.setFont(f);
 g2d.drawString(STAR, (float) (circleRadius + 10 - rectangle.getCenterX()), (float) (circleRadius + 10 - rectangle.getCenterY()));
 }
/**
     * 画外圈圆
     * 
     * @param g2d
     * @param circleRadius
     */
 private static void drawCicle(Graphics2D g2d, int circleRadius) {
       g2d.setPaint(Color.red);
       int lineSize = circleRadius * 2 / (35); // 圆线条粗细是圆直径的1/35
       g2d.setStroke(new BasicStroke(lineSize));
       Shape circle = new Arc2D.Double(10, 10, circleRadius * 2, circleRadius * 2, 0, 360, Arc2D.OPEN);
       		g2d.draw(circle);
       }
}
最近下载更多
binggo  LV12 8月26日
wwb521  LV7 2023年8月17日
983776210  LV1 2023年3月23日
1719863922  LV11 2022年6月13日
kele_lele  LV1 2022年3月5日
阳明娱乐  LV1 2022年2月24日
hamofeng  LV1 2022年2月21日
看天有云  LV1 2021年12月1日
lyzuidaima  LV7 2021年10月11日
我不是张三  LV1 2021年7月21日
最近浏览更多
binggo  LV12 8月26日
372001826 6月26日
暂无贡献等级
akittyboy  LV9 4月16日
Dominick  LV14 2023年11月29日
woldxy  LV12 2023年9月27日
121514713  LV2 2023年5月26日
983776210  LV1 2023年3月23日
whfuai  LV14 2023年1月31日
微信网友_6040315240812544  LV8 2022年10月14日
1719863922  LV11 2022年6月13日
顶部 客服 微信二维码 底部
>扫描二维码关注最代码为好友扫描二维码关注最代码为好友