在本地启动没有中文乱码在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;
}
}