证书图片本地启动没事,Linux服务器启动中文乱码解决

在本地启动没有中文乱码在Linux上发布服务出现中文乱码,中文乱码是因为Linux系统上没有安装响应的字体可以下载字体和Java文件一起打包上传

在resuorces下放置你需要的中文字体

在这里插入图片描述

下面是读取字体的工具类

package com.yszs.saxt.service.utils;
import java.awt.Font;
import java.awt.FontFormatException;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * @author 克里斯·加德纳
 * @ClassName CyFont
 * @date 2020/12/22/022 14:47
 */
public class CyFont {
    private Font definedFont = null;

    public Font getDefinedFont(int ft,float fs) {
        String fontUrl="";
        InputStream inputStream =null;
        switch (ft) {
            case 1:
                inputStream = CyFont.class.getClassLoader().getResourceAsStream("msyh.ttf");//微软雅黑 读取resource下的字体文件
                break;
            case 2:
                inputStream = CyFont.class.getClassLoader().getResourceAsStream("simsun.ttf");//宋体
                break;
         
        }
        if (definedFont == null) {
            InputStream is = null;
            BufferedInputStream bis = null;
            try {
                is =inputStream;
                bis = new BufferedInputStream(is);
                definedFont = Font.createFont(Font.TRUETYPE_FONT, is);
                //设置字体大小,float型
                definedFont = definedFont.deriveFont(fs);
            } catch (FontFormatException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (null != bis) {
                        bis.close();
                    }
                    if (null != is) {
                        is.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return definedFont;
    }


    public static void main(String[] args) {
        // TODO Auto-generated method stub
        CyFont cf=new CyFont();
        cf.getDefinedFont(1, 50);

    }

}

下面是生成证书图片的代码

package com.yszs.saxt.service.utils;

import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.font.FontRenderContext;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

public class PictureSynthesisUtils {

	private Graphics2D graphics2 = null;
	private static final int width = 414;
	private static final int height = 583;

	/**
	 * 导入本地图片到缓冲区
	 */
	public BufferedImage loadImageLocal(String imgName) {
		try {
			return ImageIO.read(new File(imgName));
		} catch (IOException e) {
			System.out.println(e.getMessage());
		}
		return null;
	}

	/**
	 * 
	 * @param qrcode     二维码图�?
	 * @param background 模板背景�?
	 * @param title      标题
	 * @param content    信息
	 * @param color      字体颜色
	 * @return
	 */
	public BufferedImage modifyImagetogeter(BufferedImage qrcode, BufferedImage background, String title,
			String content, Color color) {

		try {
			int qrcodeWidth = qrcode.getWidth();
			int qrcodeHeight = qrcode.getHeight();
			graphics2 = background.createGraphics();
			graphics2.drawImage(qrcode, 106, 192, qrcodeWidth, qrcodeHeight, null);
			CyFont cyFont = new CyFont();
			Font font = cyFont.getDefinedFont(1, 18);
			BufferedImage bufferedImage = new BufferedImage(21, 24, BufferedImage.TYPE_INT_RGB);
			graphics2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
			graphics2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
			// 设置背影为白�?
			graphics2.setColor(Color.WHITE);
			graphics2.fillRect(1, 1, bufferedImage.getWidth(), bufferedImage.getHeight());
			graphics2.setFont(font);
			graphics2.setColor(Color.BLACK);
			// 字体颜色
			graphics2.setPaint(color);
			graphics2.drawString(title, count(title, 18), 83);// 图片上写文字
			//Font font2 = new Font("微软雅黑", Font.BOLD, 16);
			Font font2 = cyFont.getDefinedFont(1, 16);
			graphics2.setFont(font2);
			graphics2.drawString(content, count(content, 16), 171);// 图片上写文字
			graphics2.setColor(new Color(255, 255, 255, 0));// 透明
			graphics2.dispose();
		} catch (Exception e) {
			System.out.println(e.getMessage());
		}

		return background;
	}

	/**
	 * 剧中计算
	 * 
	 * @param msg
	 * @return
	 */

	public int count(String msg, int fonsize) {
		char[] chararray = msg.toCharArray();
		int max = chararray.length * (fonsize);
		int x;
		if (max > width) {
			x = 0;
			return x;
		}
		x = (width / 2) - (max / 2);
		return x;

	}

	/**
	 * 生成新图片到本地
	 */
	public void writeImageLocal(String newImage, BufferedImage img) {
		if (newImage != null && img != null) {
			try {
				File outputfile = new File(newImage);
				ImageIO.write(img, "png", outputfile);
			} catch (IOException e) {
				System.out.println(e.getMessage());
			}
		}
	}

	private int getFontSizeByFontNum1(int fontNum) {
		int fontSize = 20;
		if (fontNum > 85) {
			fontSize = 55;
		} else if (fontNum > 60) {
			fontSize = 45;
		} else if (fontNum > 40) {
			fontSize = 35;
		} else if (fontNum > 18) {
			fontSize = 25;
		} else {
			fontSize = 25;
		}
		return fontSize;
	}

//	public BufferedImage generateCertificatePhoto(BufferedImage cirle, BufferedImage zhang, String title,
//			String content, String credentialCode, String certifying, String userLife) {
	/**
	 * 生成证书
	 * 
	 * @param cirle     二维码图�?
	 * @param zhang 模板背景�?
	 * @param title      标题
	 * @param content    信息
	 * @param title      字体颜色
	 * @return
	 */
	public BufferedImage generateCertificatePhoto(BufferedImage cirle, BufferedImage zhang, String title,
			String content, String credentialCode, String certifying, String userName, String dateStr) {
		try {

			/*
			 * int cirleWidth = cirle.getWidth()*4; int cirleHeight = cirle.getHeight()*4;
			 * if(cirleWidth>436) { cirleWidth=436; } if(cirleHeight>436) { cirleHeight=436;
			 * }
			 */
			int zhangWidth = zhang.getWidth();
			int zhangHeight = zhang.getHeight();

			graphics2 = zhang.createGraphics();
			// graphics2.drawImage(cirle,
			// zhangWidth-cirleWidth-400,zhangHeight-cirleHeight-300, cirleWidth,
			// cirleHeight, null);

			graphics2.setPaint(Color.BLACK);

			// 字体大小
			int planNum = title.length();
			System.out.println(planNum);
			int fontSize_1 = getFontSizeByFontNum1(planNum);
			CyFont cyFont = new CyFont();
			Font font1 = cyFont.getDefinedFont(1, fontSize_1);

			//Font font1 = new Font("微软雅黑", Font.BOLD, fontSize_1);
			// 获取截断的字数
			// 左右两边的间距
			int beginwidth = 40;
			int beginHeight = zhangHeight / 4;
			// 每次截取长度
			int subNum = sublitContent(zhangWidth, fontSize_1, beginwidth);
			int m = title.toCharArray().length / subNum;
			// content=begin+content;
			// 开始截取字数
			int subBegin = 0;
			String b = "";
			graphics2.setFont(font1);
			for (int j = 0; j <= m; j++) {
				if (title.length() < subBegin) {
					break;
				} else if (title.length() > subBegin + subNum) {
					b = title.substring(subBegin, subBegin + subNum);
				} else {
					b = title.substring(subBegin);
				}
				subBegin = subBegin + subNum;
				graphics2.drawString(b, zhangWidth / 2 - b.toCharArray().length * fontSize_1 / 2, beginHeight);// 图片上写文字
				beginHeight = beginHeight + fontSize_1 + 10;
			}

			//CyFont cyFont = new CyFont();
			Font font2 = cyFont.getDefinedFont(1, fontSize_1-5);
			//Font font2 = new Font("微软雅黑", Font.BOLD, fontSize_1 - 5);
			// String begin=" 张贺然 于 2019 年 02 月 02 日";

			// 获取截断的字数
			int i = sublitContent(zhangWidth, fontSize_1 - 5, 30);
			int n = content.toCharArray().length / i;
			// content=begin+content;
			int begin1 = 0;
			String c = "";
			int chight = 200;
			graphics2.setFont(font2);
			int start = 0;// 截取的结束位置
			int beginPoint = 90;// 开始位置
			for (int j = 0; j <= n; j++) {
				if (content.length() < begin1) {
					break;
				}
				start = begin1 + i;
				if (j == 0) {
//					start = start - 2;
				} else {
					beginPoint = 50;
				}
				int end = getSubInt(content, begin1, start);
				if (content.length() > end) {
					c = content.substring(begin1, end - 4);
					if (j > 0) {
						c = content.substring(begin1, end - 2);
					}
				} else {
					c = content.substring(begin1);
				}
				if (j == 0) {
					begin1 = end - 4;
				} else {

					begin1 = end - 2;
				}
				graphics2.drawString(c, beginPoint, chight);// 图片上写文字
				chight = chight + 30;

			}

			// 设置用户姓名
			//Font font3 = new Font("微软雅黑", Font.BOLD, fontSize_1 - 5);
			//CyFont cyFont = new CyFont();
			Font font3 = cyFont.getDefinedFont(1, fontSize_1-5);
			credentialCode = userName;
			graphics2.setFont(font3);
			graphics2.setPaint(Color.BLACK);
			graphics2.drawString(credentialCode, zhangWidth / 2 - 30, zhangHeight / 3 + 15);

			// 设置日期
			//Font font4 = new Font("微软雅黑", Font.BOLD, fontSize_1);
			String createDate = "日期:" + dateStr;
			graphics2.setFont(font3);
			graphics2.setPaint(Color.BLACK);
			graphics2.drawString(createDate, zhangWidth - 300, zhangHeight - 100);

			// 画合格章
			startGraphics2D(graphics2, certifying, zhangWidth - 150, zhangHeight - 130);
			/*
			 * Font font4 = new Font("微软雅黑", Font.BOLD, 40); certifying="郑州市食品药品网络宣";
			 * graphics2.setFont(font4); graphics2.drawString(certifying,
			 * zhangWidth-600-center(certifying, 40), zhangHeight-600); Font font5 = new
			 * Font("微软雅黑", Font.BOLD, 45); userLife="有效期: "+userLife;
			 * graphics2.setFont(font5); graphics2.drawString(userLife,
			 * zhangWidth-400-cirleWidth/2-300, zhangHeight-400);
			 */

			// graphics2.setColor(new Color(255, 255, 255,0));//透明
			graphics2.dispose();
		} catch (Exception e) {
			System.out.println(e.getMessage());
		}

		return zhang;
	}

	// 判断截取的字符串中数字和空格和字母的个数。以确定截取的位置
	private int getSubInt(String str, int beginSubInt, int endSubInt) {
		int i = 0;
		if (str.length() >= endSubInt) {
			char[] c = str.substring(beginSubInt, endSubInt).toCharArray();
			for (int d : c) {
				if ((d >= 65 && d <= 90) || (d >= 97 && d <= 122) || (d >= 48 && d <= 57) || d == 32) {
					i++;
				}
			}
			if (i < 2) {
				return endSubInt;
			} else {
				int a = i / 2 + endSubInt;
				int d = getSubInt(str, endSubInt, a);
				return d;
			}
		} else {
			return endSubInt;
		}
	}

	public static void startGraphics2D(Graphics2D g, String message, int zhangWidth, int zhangHight) {

		g.setColor(Color.RED);
		// 设置锯齿圆滑
		g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

		// 绘制圆
		int radius = 80;// 周半径
		int CENTERX = zhangWidth;// 画图所出位置
		int CENTERY = zhangHight;// 画图所处位置

		Ellipse2D circle = new Ellipse2D.Float();
		circle.setFrameFromCenter(CENTERX, CENTERY, CENTERX + radius, CENTERY + radius);
		// circle.set
		Graphics2D g2d = (Graphics2D) g;
		g2d.setStroke(new BasicStroke(5));
		g2d.draw(circle);
         //new Font("宋体", Font.BOLD, 30)
		// 绘制中间的五角星
		CyFont cyFont = new CyFont();
		g.setFont(cyFont.getDefinedFont(2,30));
		g.drawString("合  格", CENTERX - 50, CENTERY + 60);
		// 设置字体属性
		int fontsize = 25;
		//"宋体", Font.BOLD, fontsize
		//Font f = new Font();
		Font f = cyFont.getDefinedFont(2, fontsize);

		// 根据输入字符串得到字符数组
		if (message.length() > 20) {
			message = message.substring(0, 20);
		}
		FontRenderContext context = g.getFontRenderContext();
		Rectangle2D bounds = f.getStringBounds(message, context);
		String[] messages = message.split("", 0);
		// 输入的字数
		int ilength = messages.length;
		// 字符宽度=字符串长度/字符数
		double char_interval = (bounds.getWidth() / ilength);
		// 上坡度
		double ascent = -bounds.getY() + 5;

		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 radius2 = radius - ascent;
		double x0 = CENTERX;
		double y0 = CENTERY - radius + ascent;
		// 旋转角度
		double a = 2 * Math.asin(char_interval / (2 * radius2));

		if (odd) {
			// 单数
			g.setFont(f);
			g.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 = radius2 * Math.sin(aa);
				double ay = radius2 - radius2 * Math.cos(aa);
				AffineTransform transform = AffineTransform.getRotateInstance(aa);// ,x0 + ax, y0 + ay);
				Font f2 = f.deriveFont(transform);
				g.setFont(f2);
				g.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 = radius2 * Math.sin(aa);
				double ay = radius2 - radius2 * Math.cos(aa);
				AffineTransform transform = AffineTransform.getRotateInstance(-aa);// ,x0 + ax, y0 + ay);
				Font f2 = f.deriveFont(transform);
				g.setFont(f2);
				g.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.5) * a;
				double ax = radius2 * Math.sin(aa);
				double ay = radius2 - radius2 * Math.cos(aa);
				AffineTransform transform = AffineTransform.getRotateInstance(aa);// ,x0 + ax, y0 + ay);
				Font f2 = f.deriveFont(transform);
				g.setFont(f2);
				g.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.5) * a;
				double ax = radius2 * Math.sin(aa);
				double ay = radius2 - radius2 * Math.cos(aa);
				AffineTransform transform = AffineTransform.getRotateInstance(-aa);// ,x0 + ax, y0 + ay);
				Font f2 = f.deriveFont(transform);
				g.setFont(f2);
				g.drawString(messages[i], (float) (x0 - ax - char_interval / 2 * Math.cos(aa)),
						(float) (y0 + ay + char_interval / 2 * Math.sin(aa)));
			}
		}

	}

	/**
	 * 生成成绩单
	 * 
	 * @param beijing     二维码图�?
	 * @param  �?
	 * @param name      标题
	 * @param
	 * @param   socre   字体颜色
	 * @return
	 */

	public BufferedImage generateChengJiDanPhoto(BufferedImage beijing, String name, String socre, String planName,
			String time, String signOrganizationName) {
		try {
			int zhangWidth = beijing.getWidth();
			int zhangHeight = beijing.getHeight();
			graphics2 = beijing.createGraphics();

			graphics2.setColor(Color.BLACK);

			// 字体大小
			planName = "您参与的由 " + signOrganizationName + " (部门或居委会)发起的" + planName + "培训学习计划,于" + time + "进行正式考试,成绩如下:";
			int planNum = planName.length();
			int fontSize_1 = getFontSizeByFontNum(planNum);
			CyFont cyFont = new CyFont();
			Font font1 = cyFont.getDefinedFont(1, 18);

			// 获取截断的字数
			// 左右两边的间距
			int beginwidth = zhangWidth / 2 - 300;
			int beginHeight = zhangHeight / 3 + 100;

			// 获取截断的字数
//			int i = sublitContent(zhangWidth, 60, 300);
			int i = sublitContent(zhangWidth, fontSize_1, zhangWidth / 10);
			int n = planName.toCharArray().length / i;
			// content=begin+content;
			int begin1 = 0;
			String c = "";
			int chight = zhangHeight / 2;
			graphics2.setFont(font1);
			int start = 0;// 截取的结束位置
			int beginPoint = 100;// 开始位置
			for (int j = 0; j <= n; j++) {
				if (planName.length() < begin1) {
					break;
				}
				start = begin1 + i;
				if (j == 0) {
//					start = start - 2;
				} else {
					beginPoint = 60;
				}
				int end = getSubInt(planName, begin1, start);
				if (planName.length() > end) {
					c = planName.substring(begin1, end);
				} else {
					c = planName.substring(begin1);
				}
				begin1 = end;
				graphics2.drawString(c, beginPoint, chight - 170);// 图片上写文字
				chight = chight + 50;

			}

			int fontSize_2 = fontSize_1;
			//Font font = new Font("微软雅黑", Font.BOLD, fontSize_2);
			Font font = cyFont.getDefinedFont(1, fontSize_2);
			graphics2.setFont(font);
			beginHeight = zhangHeight / 2;
			graphics2.drawString(name, zhangWidth / 2 - name.toCharArray().length * fontSize_2 / 2, 1000);
			beginHeight = beginHeight + fontSize_2 * 3;

			String a = "得分 : " + socre + "分";
			graphics2.drawString(a, zhangWidth / 2 - 80, zhangHeight / 2 + 80);

			//Font font5 = new Font("微软雅黑", Font.BOLD, fontSize_1);
			Font font5 = cyFont.getDefinedFont(1, fontSize_1);

			time = "考试日期:" + time;
			graphics2.setFont(font5);
			graphics2.drawString(time, zhangWidth - 450, zhangHeight - 210);

			graphics2.dispose();
		} catch (Exception e) {
			System.out.println(e.getMessage());
		}

		return beijing;
	}

	private int getFontSizeByFontNum(int fontNum) {
		int fontSize = 40;
		if (fontNum > 75) {
			fontSize = 40;
		} else if (fontNum > 59) {
			fontSize = 30;
		} else if (fontNum > 44) {
			fontSize = 20;
		} else if (fontNum > 35) {
			fontSize = 10;
		} else if (fontNum > 24) {
			fontSize = 15;
		} else {
			fontSize = 40;
		}
		return fontSize;
	}

	/**
	 * 剧中计算
	 * 
	 * @param msg
	 * @return
	 */

	public int center(String msg, int fonsize) {
		char[] chararray = msg.toCharArray();
		int max = chararray.length * (fonsize);

		return max / 2;

	}

	/**
	 * 
	 * @param width    北京宽度
	 * @param fontsize 文字大小
	 * @param offect   一边的间距
	 * @return 一行显示的文字数目
	 */
	public int sublitContent(int width, int fontsize, int offect) {
		return (width - offect * 2) / fontsize;
	}

}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值