java 画印章_java 2d生成指定文字的电子印章图片

该博客介绍了一个用Java实现的工具类`SealUtils`,能够生成包含指定公司名称的电子印章图片。代码通过2D图形API绘制圆形边框、五角星、底部文字和弧形顶部文字,提供了自定义参数如印章大小、字体等。
摘要由CSDN通过智能技术生成

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);

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值