JAVA生成椭圆形签章

话不多说,直接贴代码吧。

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.font.FontRenderContext;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Calendar;
import java.util.UUID;

import javax.imageio.ImageIO;

import org.apache.commons.lang.StringUtils;


/**
 * 勾画圆形公司章
 * 
 * @author ldd
 */
public class DrawSeal {
    //生成文件路径
    public static final String FILE_PATH = "d:/";
    
    private final static int WIDTH = 160;
    
    private final static int HEIGHT = 110;
    
    /**
     * 画圆形章
     * @param name1 章的名字
     * @param name2 公司的名字
     * @param numCode 公司的数字编码
     * @param width 
     * @param height
     * @return
     */
    public static String drawCircularChapter(String name1, String name2, String numCode){
        OutputStream out = null;
        InputStream in = null;
        //创建缓存
        BufferedImage bufImg = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
        //获得画布
        Graphics2D gs = bufImg.createGraphics();
        //设置颜色
        gs.setColor(Color.WHITE);
        //填充区域
        gs.fillRect(0, 0, WIDTH, HEIGHT);
        //设置画笔颜色
        gs.setColor(new Color(204,41,41));
        //画五角星
        drawFiveStar(gs, WIDTH/2, (HEIGHT-10)/2, (HEIGHT-10)/6-3);
        //设置画笔宽度
        gs.setStroke(new BasicStroke(3));
        //画圆形边框
        gs.drawOval(2, 2, WIDTH-4, HEIGHT-10);
        //设置字体
        gs.setFont(new Font("宋体", Font.BOLD, 21));
//        画数据(合同专用章)
        drawCenterMessage(gs, name1, WIDTH/2+2, (HEIGHT-10) * 4 / 5);
        if (StringUtils.isNotEmpty(name2) && name2.length()>11) {
            int len = name2.length();
            int fontSize = 18;
            switch (len) {
            case 12:
                fontSize = 20;
                break;
            case 13:
                fontSize = 19;
                break;
            case 14:
                fontSize = 19;
                break;
            case 15:
                fontSize = 18;
                break;
            case 16:
                fontSize = 17;
                break;
            case 17:
                fontSize = 16;
                break;
            case 18:
                fontSize = 15;
                break;
            case 19:
                fontSize = 14;
                break;
            case 20:
                fontSize = 14;
                break;
            case 21:
                fontSize = 12;
                break;
            case 22:
                fontSize = 12;
                break;
            case 23:
                fontSize = 10;
                break;
            case 24:
                fontSize = 10;
                break;
            case 25:
                fontSize = 9;
                break;
            default :
                fontSize = 18;
                break;
            }
            //设置字体
            gs.setFont(new Font("宋体", Font.PLAIN, fontSize));
        }
        //画上方的环形字
        drawUpperMessage(gs, name2, WIDTH/2, (HEIGHT-10)/2, WIDTH/2-8, (HEIGHT-10)/2-8);
        //设置字体
        gs.setFont(new Font("宋体", Font.BOLD, 9));
        //画下方的环形数字
        drawBelowNumber(gs, numCode, WIDTH/2, (HEIGHT-10)/2, WIDTH/2-8, (HEIGHT-10)/2+8);
        //释放此图形的上下文以及它使用的所有系统资源
        gs.dispose();
        //输出图片
        try {
            StringBuffer fileDir = new StringBuffer();
            fileDir.append(Calendar.getInstance().get(Calendar.YEAR)).append(File.separator).append(Calendar.getInstance().get(Calendar.MONTH)+1).append(File.separator).append(Calendar.getInstance().get(Calendar.DAY_OF_MONTH)).append(File.separator);
            File ff = new File(FILE_PATH + fileDir.toString());
            if (!ff.exists()) {
                ff.mkdirs();
            }
            String imgFile = FILE_PATH + fileDir.toString() + UUID.randomUUID() + ".png";
            out = new FileOutputStream(imgFile);
            ImageIO.write(bufImg, "png", out);
            
            bufImg.flush();
            out.flush();
            
            /*in = new FileInputStream(imgFile);
            data = new byte[in.available()];
            in.read(data);*/
            
            //对字节数组Base64编码
            /*sun.misc.BASE64Encoder encoder = new sun.misc.BASE64Encoder();
            //返回Base64编码过的字节数组字符串
            String encodeStr = encoder.encode(data);
            //将图片文件删除
            File file = new File(imgFile);
            if (file.isFile()) {
                file.delete();
            }*/
            return imgFile;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (null != out) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != in) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }
    
    public static void drawCenterMessage(Graphics2D gs, String message, int CENTERX, int CENTERY){
        if (message != null) {
            // 根据输入字符串得到字符数组
            String[] messages2 = message.split("", 0);
            String[] messages = new String[messages2.length];
            System.arraycopy(messages2, 0, messages, 0, messages2.length);
            // 输入的字数
            int ilength = messages.length;
            Font f = gs.getFont();
            FontRenderContext context = gs.getFontRenderContext();
            Rectangle2D bounds = f.getStringBounds(message, context);
            // 字符宽度=字符串长度/字符数
            double char_interval = (bounds.getWidth() / ilength) - 1;
            
            int first = 0, second = 0;
            boolean odd = false;
            if (ilength % 2 == 1) {
                first = (ilength - 1) / 2;
                odd = true;
            } else {
                first = (ilength) / 2 - 1;
                second = (ilength) / 2;
                odd = false;
            }
            if (odd) {
                gs.drawString(messages[first],
                        (float)(CENTERX - char_interval / 2 - char_interval / 10), 
                        (float) CENTERY);
                // 中心点的右边
                for (int i = first + 1; i < ilength; i++) {
                    double x = CENTERX + (i - first - 0.6) * char_interval;
                    gs.drawString(messages[i],(float) x,
                            (float) CENTERY);
                }
                // 中心点的左边
                for (int i = first - 1; i > -1; i--) {
                    double x = CENTERX - (first - i + 0.6) * char_interval;
                    gs.drawString(messages[i],(float) x,
                            (float) CENTERY);
                }
            } else {
                // 中心点的右边
                for (int i = second; i < ilength; i++) {
                    double x = CENTERX + (i - second - 0.1) * char_interval;
                    gs.drawString(messages[i],(float) x,
                            (float) CENTERY);
                }
                // 中心点的左边
                for (int i = first; i > -1; i--) {
                    double x = CENTERX - (first + 1 - i + 0.1) * char_interval;
                    gs.drawString(messages[i],(float) x,
                            (float) CENTERY);
                }
    
            }
        }
    }
    
    /**
     * 画上方圆弧的汉字
     * 
     * @param gs
     * @param message
     * @param CENTERX
     * @param CENTERY
     * @param r
     */
    public static void drawUpperMessage(Graphics2D gs, String message, int CENTERX, int CENTERY, int wr, int hr) {
        if (message != null) {
            // 根据输入字符串得到字符数组
            String[] messages = message.split("", 0);
//            String[] messages = new String[messages2.length];
//            System.arraycopy(messages2, 0, messages, 0, messages2.length);
            // 输入的字数
            int ilength = messages.length;
            Font f = gs.getFont();
            FontRenderContext context = gs.getFontRenderContext();
            Rectangle2D bounds = f.getStringBounds(message, context);
            // 字符宽度=字符串长度/字符数
            double char_interval = (bounds.getWidth() / ilength) - 1;
            // 上坡度
            double ascentY = - bounds.getY()-2;
            
            double ascentX = - bounds.getX()-2;
            int first = 0, second = 0;
            boolean odd = false;
            if (ilength % 2 == 1) {
                first = (ilength - 1) / 2;
                odd = true;
            } else {
                first = (ilength) / 2 - 1;
                second = (ilength) / 2;
                odd = false;
            }
            double r2 = wr - ascentX;
            double x0 = CENTERX;
            double y0 = CENTERY - hr + ascentY;
            // 旋转角度
            double a = 2 * Math.asin(char_interval / (2 * r2));
    
            if (odd) {
                gs.drawString(messages[first],(float)(x0 - char_interval / 2), (float) y0);
                // 中心点的右边
                for (int i = first + 1; i < ilength; i++) {
                    double aa = (i - first) * a;
                    double ax = r2 * Math.sin(aa);
                    double ay = r2 - r2 * Math.cos(aa);
                    AffineTransform transform = AffineTransform.getRotateInstance(aa);
                    Font f2 = f.deriveFont(transform);
                    gs.setFont(f2);
                    gs.drawString(messages[i],(float) (x0 + ax - char_interval / 2 * Math.cos(aa)),
                            (float) (y0 + ay - char_interval / 2 * Math.sin(aa)));
                }
                // 中心点的左边
                for (int i = first - 1; i > -1; i--) {
                    double aa = (first - i) * a;
                    double ax = r2 * Math.sin(aa);
                    double ay = r2 - r2 * Math.cos(aa);
                    AffineTransform transform = AffineTransform.getRotateInstance(-aa);
                    Font f2 = f.deriveFont(transform);
                    gs.setFont(f2);
                    gs.drawString(messages[i],
                    (float) (x0 - ax - char_interval / 2 * Math.cos(aa)),
                    (float) (y0 + ay + char_interval / 2 * Math.sin(aa)));
                }
            } else {
                // 中心点的右边
                for (int i = second; i < ilength; i++) {
                    double aa = (i - second + 0.3) * a;
                    double ax = r2 * Math.sin(aa);
                    double ay = r2 - r2 * Math.cos(aa);
                    AffineTransform transform = AffineTransform.getRotateInstance(aa);
                    Font f2 = f.deriveFont(transform);
                    gs.setFont(f2);
                    gs.drawString(messages[i],
                        (float) (x0 + ax - char_interval / 2 * Math.cos(aa)),
                        (float) (y0 + ay - char_interval / 2 * Math.sin(aa)));
                }
                // 中心点的左边
                for (int i = first; i > -1; i--) {
                    double aa = (first - i + 0.7) * a;
                    double ax = r2 * Math.sin(aa);
                    double ay = r2 - r2 * Math.cos(aa);
                    AffineTransform transform = AffineTransform.getRotateInstance(-aa);
                    Font f2 = f.deriveFont(transform);
                    gs.setFont(f2);
                    gs.drawString(messages[i],
                        (float) (x0 - ax - char_interval / 2 * Math.cos(aa)),
                        (float) (y0 + ay + char_interval / 2* Math.sin(aa)));
                }
            }
        }
    }
    
    /**
     * 画下方圆弧数字编码
     * 
     * @param gs
     * @param message
     * @param CENTERX
     * @param CENTERY
     * @param r
     */
    public static void drawBelowNumber(Graphics2D gs, String message, int CENTERX, int CENTERY, int wr, int hr) {
        if (message != null) {
            // 根据输入字符串得到字符数组
            String[] messages = message.split("", 0);
//            String[] messages = new String[messages2.length];
//            System.arraycopy(messages2, 0, messages, 0, messages2.length);
            // 输入的字数
            int ilength = messages.length;
            Font f = gs.getFont();
            FontRenderContext context = gs.getFontRenderContext();
            Rectangle2D bounds = f.getStringBounds(message, context);
            // 字符宽度=字符串长度/字符数
            double char_interval = (bounds.getWidth() / ilength) + 4;
            // 上坡度
            double ascentY = -bounds.getY();
            
            double ascentX = -bounds.getY();
            
            int first = 0, second = 0;
            boolean odd = false;
            if (ilength % 2 == 1) {
                first = (ilength - 1) / 2;
                odd = true;
            } else {
                first = (ilength) / 2 - 1;
                second = (ilength) / 2;
                odd = false;
            }
            double r2 = wr - ascentX;
            double x0 = CENTERX;
            double y0 = CENTERY - hr + ascentY;
            // 旋转角度
            double a = 2 * Math.asin(char_interval / (2 * r2));
            if (odd) {
                // 中心点的右边
                for (int i = first + 1; i < ilength; i++) {
                    double aa = (i - first + 0.5) * a;
                    double ax = r2 * Math.sin(aa);
                    double ay = r2 - r2 * Math.cos(aa);
                    AffineTransform transform = AffineTransform.getRotateInstance(2*Math.PI - aa);
                    Font f2 = f.deriveFont(transform);
                    gs.setFont(f2);
                    gs.drawString(messages[i],
                        (float) (x0 + ax - char_interval / 2 * Math.cos(aa)),
                        2*CENTERY - (float) (y0 + ay - char_interval / 2 * Math.sin(aa)));
                }
                // 中心点的左边
                for (int i = first; i > -1; i--) {
                    double aa = (first - i - 0.5) * a;
                    double ax = r2 * Math.sin(aa);
                    double ay = r2 - r2 * Math.cos(aa);
                    AffineTransform transform = AffineTransform.getRotateInstance(2*Math.PI + aa);
                    Font f2 = f.deriveFont(transform);
                    gs.setFont(f2);
                    gs.drawString(messages[i],
                        (float) (x0 - ax - char_interval / 2 * Math.cos(aa)),
                        2*CENTERY - (float) (y0 + ay + char_interval / 2 * Math.sin(aa)));
                }
            } else {
                // 中心点的右边
                for (int i = second; i < ilength; i++) {
                    double aa = (i - second + 1) * a;
                    double ax = r2 * Math.sin(aa);
                    double ay = r2 - r2 * Math.cos(aa);
                    AffineTransform transform = AffineTransform.getRotateInstance(2*Math.PI - aa);
                    Font f2 = f.deriveFont(transform);
                    gs.setFont(f2);
                    gs.drawString(messages[i],
                        (float) (x0 + ax - char_interval / 2 * Math.cos(aa)),
                        2*CENTERY - (float) (y0 + ay - char_interval / 2 * Math.sin(aa)));
                }
                // 中心点的左边
                for (int i = first; i > -1; i--) {
                    double aa = (first - i) * a;
                    double ax = r2 * Math.sin(aa);
                    double ay = r2 - r2 * Math.cos(aa);
                    AffineTransform transform = AffineTransform.getRotateInstance(2*Math.PI + aa);
                    Font f2 = f.deriveFont(transform);
                    gs.setFont(f2);
                    gs.drawString(messages[i],
                        (float) (x0 - ax - char_interval / 2 * Math.cos(aa)),
                        2*CENTERY - (float) (y0 + ay + char_interval / 2* Math.sin(aa)));
                }
            }
        }
    }
    
    /**
     * 画章中间的五角星
     * 
     * @param g
     * @param x
     * @param y
     * @param r
     */
    public static void drawFiveStar(Graphics g, int x, int y, int r) {
        double ch=72*Math.PI/180;
        int x1=x,
            x2=(int)(x-Math.sin(ch)*r),
            x3=(int)(x+Math.sin(ch)*r),
            x4=(int)(x-Math.sin(ch/2)*r),
            x5=(int)(x+Math.sin(ch/2)*r);
        int y1=y-r,
            y2=(int)(y-Math.cos(ch)*r),
            y3=y2,
            y4=(int)(y+Math.cos(ch/2)*r),
            y5=y4;
        int bx=(int)(x+Math.cos(ch)*Math.tan(ch/2)*r);
        int by=y2; 

        Polygon a=new Polygon();
        Polygon b=new Polygon();
        a.addPoint(x2,y2);
        a.addPoint(x5,y5);
        a.addPoint(bx,by);
        b.addPoint(x1,y1);
        b.addPoint(bx,by);
        b.addPoint(x3,y3);
        b.addPoint(x4,y4);

        g.fillPolygon(a);
        g.fillPolygon(b);
    }
    
    public static void main(String[] args) {
    	drawCircularChapter("国税局", "陕西XX有限公司", "A1002");
	}
}

===========================================================

  /**
     * 写入到pdf 公章处
     */
    private void drawSeal(){
        //pdf模板所在路径 (通过类名获取文件路径)
        String templateFileName = DrawSeal2.class.getClassLoader().getResource("sb_loan_contract_borrow.pdf").getFile();
        //使用itext的包读取pdf模板
        PdfReader pdfReader = new PdfReader(templateFileName);
        // 提取pdf中的表单输入域字段
        AcroFields form = pdfStamper.getAcroFields();
        // 通过域名获取所在页(页数)和坐标,左下角为起点
        int pageNo = form.getFieldPositions("Chapter").get(0).page;
        Rectangle signRect = form.getFieldPositions("Chapter").get(0).position;
        //获取x y 坐标 
        float x = signRect.getLeft();
        float y = signRect.getBottom();
        //生成一个签章(用java.awt 画一个章)  章:上需要几个常量值Constants.CHAPTER_NAME, Constants.CHAPTER_COMPANY_NAME, Constants.CHAPTER_SOCIAL_NUMBER
        String imgPath = DrawSeal.drawCircularChapter(Constants.CHAPTER_NAME, Constants.CHAPTER_COMPANY_NAME, Constants.CHAPTER_SOCIAL_NUMBER);
        // 读图片
        Image image = Image.getInstance(imgPath);
        // 获取操作的页面
        PdfContentByte under = pdfStamper.getOverContent(pageNo);
        // 根据域的大小缩放图片
        image.scaleToFit(signRect.getWidth(), signRect.getHeight());
        // 添加图片
        image.setAbsolutePosition(x, y);
        under.addImage(image);
        pdfStamper.flush();
        pdfStamper.close();
        pdfReader.close();
    }

你可能感兴趣的:(java)