我们有的时候营销的时候,需要把给每一位用户生成单独的海报。比如微信营销的时候,需要给每一个用户单独生成。这个时候,需要把用户昵称和头像放到海报里。这个如何开发呢?下面我们介绍下。
先给背景图片中添加头像,并且根据位置和长宽等。确定位置。
接着把文字添加进去,核心代码如下:
/**
* 把两张图片合并
*/
public class QrPicUtil {
private static Logger logger = LoggerFactory.getLogger(QrPicUtil.class);
private Font font = new Font("宋体", Font.PLAIN, 12); // 添加字体的属性设置
private static Graphics2D g = null;
private int fontsize = 0;
private int x = 0;
private int y = 0;
/**
* 导入本地图片到缓冲区
*/
public BufferedImage loadImageLocal(String imgName) {
try {
return ImageIO.read(new File(imgName));
} catch (IOException e) {
System.out.println(e.getMessage());
}
return null;
}
/**
* 导入网络图片到缓冲区
*/
public static BufferedImage loadImageUrl(String imgName) {
try {
URL url = new URL(imgName);
return ImageIO.read(url);
} catch (IOException e) {
System.out.println(e.getMessage());
}
return null;
}
/**
* 生成新图片到本地
*/
public static void writeImageLocal(String newImage, BufferedImage img) {
if (newImage != null && img != null) {
try {
File outputfile = new File(newImage);
ImageIO.write(img, "jpg", outputfile);
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}
/**
* 设定文字的字体等
*/
public void setFont(String fontStyle, int fontSize) {
this.fontsize = fontSize;
this.font = new Font(fontStyle, Font.PLAIN, fontSize);
}
/**
* 修改图片,返回修改后的图片缓冲区(只输出一行文本)
*/
public BufferedImage modifyImage(BufferedImage img, Object content, int x, int y) {
try {
int w = img.getWidth();
int h = img.getHeight();
g = img.createGraphics();
g.setBackground(Color.WHITE);
g.setColor(Color.orange);//设置字体颜色
if (this.font != null){
g.setFont(this.font);
}
// 验证输出位置的纵坐标和横坐标
if (x >= h || y >= w) {
this.x = h - this.fontsize + 2;
this.y = w;
} else {
this.x = x;
this.y = y;
}
if (content != null) {
g.drawString(content.toString(), this.x, this.y);
}
g.dispose();
} catch (Exception e) {
System.out.println(e.getMessage());
}
return img;
}
/**
* 修改图片,返回修改后的图片缓冲区(输出多个文本段) xory:true表示将内容在一行中输出;false表示将内容多行输出
*/
public BufferedImage modifyImage(BufferedImage img, Object[] contentArr, int x, int y,
boolean xory) {
try {
int w = img.getWidth();
int h = img.getHeight();
g = img.createGraphics();
g.setBackground(Color.WHITE);
g.setColor(Color.RED);
if (this.font != null){
g.setFont(this.font);
}
// 验证输出位置的纵坐标和横坐标
if (x >= h || y >= w) {
this.x = h - this.fontsize + 2;
this.y = w;
} else {
this.x = x;
this.y = y;
}
if (contentArr != null) {
int arrlen = contentArr.length;
if (xory) {
for (int i = 0; i < arrlen; i++) {
g.drawString(contentArr[i].toString(), this.x, this.y);
this.x += contentArr[i].toString().length() * this.fontsize / 2 + 5;// 重新计算文本输出位置
}
} else {
for (int i = 0; i < arrlen; i++) {
g.drawString(contentArr[i].toString(), this.x, this.y);
this.y += this.fontsize + 2;// 重新计算文本输出位置
}
}
}
g.dispose();
} catch (Exception e) {
System.out.println(e.getMessage());
}
return img;
}
/**
* 修改图片,返回修改后的图片缓冲区(只输出一行文本)
* <p>
* 时间:2007-10-8
*
* @param img
* @return
*/
public BufferedImage modifyImageYe(BufferedImage img) {
try {
int w = img.getWidth();
int h = img.getHeight();
g = img.createGraphics();
g.setBackground(Color.WHITE);
//设置字体颜色
g.setColor(Color.blue);
if (this.font != null){
g.setFont(this.font);
}
g.drawString("www.hi.baidu.com?xia_mingjian", w - 85, h - 5);
g.dispose();
} catch (Exception e) {
System.out.println(e.getMessage());
}
return img;
}
/**
*
* @param b head
* @param d bg
* @param banner
* @return
*/
public static BufferedImage modifyImagetogeter(BufferedImage b, BufferedImage d, ActivityBanner banner) {
try {
g = d.createGraphics();
Integer length = banner.getAvetarLength()*banner.getPicRate();
if (length == null) {
length = 300;
}
Integer width = banner.getAvetarWidth()*banner.getPicRate();
if (width == null) {
width = 455;
}
Integer x = banner.getAvetarX()*banner.getPicRate();
if (x == null) {
x = 300;
}
Integer y = banner.getAvetarY()*banner.getPicRate();
if (y == null) {
y = 455;
}
if (banner.getAvetarType() != null && banner.getAvetarType() == 0) {
Ellipse2D.Double shape = new Ellipse2D.Double(x,y,width, length);
g.setClip(shape);
}
g.drawImage(b, x, y, width, length, null);
g.dispose();
} catch (Exception e) {
logger.error(e.getMessage());
}
return d;
}
/**
*
* @param b head
* @param d bg
* @param tempUrl
* @param nickName
* @param banner
* @return
* @throws Exception
*/
public static BufferedImage addWater(BufferedImage b, BufferedImage d, String tempUrl, String nickName, ActivityBanner banner) throws Exception {
BufferedImage image = null;
//用户头像启用。1启用,0是禁用
if (banner.getAvatarStatus() != null && banner.getAvatarStatus() == 1) {
image = modifyImagetogeter(b, d, banner);
// return image;
} else {
image = d;
}
Graphics2D gd = image.createGraphics();
// 3、设置对线段的锯齿状边缘处理
gd.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
//用户昵称状态 1启用 0禁用
if (banner.getBannerNicknameStatus() != null && banner.getBannerNicknameStatus() == 1) {
logger.info("昵称:"+nickName);
// nickName="会吃人的蘑菇:mushroom: ₆₆₆⁶⁶⁶";
// nickName="大锤锤";
nickName=EmojiParser.parseToUnicode(nickName);
if(containsEmoji(nickName)){
logger.info("包含emoji");
}
logger.info("nickName:"+nickName);
// 5、设置水印文字颜色
if(banner.getBannerNicknameColor()==null){
gd.setColor(Color.WHITE);
}else{
try {
String color=banner.getBannerNicknameColor();
color=color.replace("#","");
if(color.length()!=6){
gd.setColor(Color.WHITE);
}else{
String s1=color.substring(0,2);
String s2=color.substring(2,4);
String s3=color.substring(4,6);
gd.setColor(new Color((int)Long.parseLong(s1, 16), (int)Long.parseLong(s2, 16), (int)Long.parseLong(s3, 16)));
}
}catch (Exception e){
logger.error("字体颜色转换异常,{}",e);
gd.setColor(Color.WHITE);
}
}
// 6、设置水印文字Font
String font = banner.getBannerNicknameFont();
Integer size=0;
if (font == null) {
size=35;
}else{
size=Integer.parseInt(font)+18;
}
gd.setFont(new Font("微软雅黑", Font.BOLD, size));
// 8、第一参数->设置的内容,后面两个参数->文字在图片上的坐标位置(x,y)
Integer x = banner.getBannerNicknameX()*banner.getPicRate();
if (x == null) {
x = 340;
}
Integer y = banner.getBannerNicknameY()*banner.getPicRate()+22;
if (y == null) {
y = 660;
}
gd.drawString(nickName, x, y);
}
//使用工具类生成二维码
Integer length = banner.getBannerScanLength()*banner.getPicRate();
if (length == null) {
length = 400;
}
Integer width = banner.getBannerScanWidth()*banner.getPicRate();
if (width == null) {
width = 320;
}
Image scImage = createQrCode(tempUrl, length, width);
//将小图片绘到大图片上,500,300 .表示你的小图片在大图片上的位置。
Integer bx = banner.getBannerScanX()*banner.getPicRate();
if (bx == null) {
bx = 175;
}
Integer by = banner.getBannerScanY()*banner.getPicRate();
if (by == null) {
by = 1020;
}
gd.drawImage(scImage, bx, by, null);
gd.dispose();
return image;
}
/**
* 将链接生成二维码的Image
*
* @param content
* @param width
* @param height
* @return
* @throws Exception
*/
private static BufferedImage createQrCode(String content, int width, int height) throws Exception {
QrConfig config = new QrConfig(width, height);
// Image image = ImageIO.read(getUrl(headImg));
// config.setImg(image);
// config.setErrorCorrection(ErrorCorrectionLevel.H);
return QrCodeUtil.generate(
content,
config);
}
/**
* 生成海报方法
*
* @param exitUrl 生成海报存储的位置
* @param bgPic 背景图片
* @param headUrl 用户头像
* @param nickName 用户昵称
* @param tempUrl 用户二维码
* @param banner 海报生成规则
* @throws Exception
*/
public static void addPic(String exitUrl, String bgPic, String headUrl, String nickName, String tempUrl, ActivityBanner banner) throws Exception {
logger.info("生成在图片上的昵称:" + nickName + ",banner的JSON::::" + JSON.toJSONString(banner));
BufferedImage bg = loadImageUrl(bgPic);
BufferedImage head = loadImageUrl(headUrl);
//往图片上写文件
writeImageLocal(exitUrl, addWater(head, bg, tempUrl, nickName, banner));
//将多张图片合在一起
logger.info("生成海报成功");
}
/**
* 检测是否有emoji字符
* @param source
* @return 一旦含有就抛出
*/
public static boolean containsEmoji(String source) {
if (StringUtils.isBlank(source)) {
return false;
}
int len = source.length();
for (int i = 0; i < len; i++) {
char codePoint = source.charAt(i);
// 文字
if (!isEmojiCharacter(codePoint)) {
return true;
}
}
return false;
}
public static boolean isEmojiCharacter(char codePoint) {
return (codePoint == 0x0) ||
(codePoint == 0x9) ||
(codePoint == 0xA) ||
(codePoint == 0xD) ||
((codePoint >= 0x20) && (codePoint <= 0xD7FF)) ||
((codePoint >= 0xE000) && (codePoint <= 0xFFFD)) ||
((codePoint >= 0x10000) && (codePoint <= 0x10FFFF));
}
public static void main(String[] args) throws Exception {
ActivityBanner banner = new ActivityBanner();
banner.setAvatarStatus(1);
banner.setBannerNicknameStatus(1);
banner.setAvetarType(0);
banner.setBannerNicknameFont("18");
QrPicUtil.addPic("D:\\pic\\a.jpg", "http://wedo918map.oss-cn-shenzhen.aliyuncs.com/images/CBIvZAmVaZi5bQjh3cScnmoblWgGzNYxI0OGfZYX.jpeg", "http://thirdwx.qlogo.cn/mmopen/Q3auHgzwzM7Vvr3wBsvm8TkUW4LplsJxEuqJLTDwjXylYqxB174ITaxSGhyicaLNKhmQLjbqaaTSz55uibdyA3LLAB8vwiaWnREcM0ojayE3Qs/132", "测试", "http://weixin.qq.com/q/02DFd6hnQOdDC1JRz0xwcE", banner);
}
}
特别说明:因为我们这边默认的是微软雅黑,所以如果你在本地部署启动一切正常,但是如果你要是部署到linux服务器上,生成的海报中中文名字可能不显示。这是因为linux中是没有微软雅黑字体,所以需要我们把微软雅黑的字体(msyhbd.ttf 和msyh.ttf 在C:/windows/fonts/里有)放到部署的jre中。记得要放到jre/lib/fonts下。然后重启你的项目就可以了。