import com.alibaba.citrus.service.requestcontext.parser.ParameterParser;
import com.alibaba.citrus.turbine.Context;
import com.alibaba.citrus.turbine.Navigator;
import com.hikvision.hikshop.biz.ElectronicCardService;
import com.hikvision.hikshop.domain.pojo.ElectronicCard;
import com.hikvision.hikshop.web.common.ThreadLocalUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.stream.FileImageOutputStream;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.swing.*;
import java.awt.*;
import java.awt.font.TextAttribute;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.text.AttributedCharacterIterator;
import java.text.AttributedString;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.List;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.net.URL;
public class ElectronicCards {
private static final Logger logger = LoggerFactory.getLogger(ElectronicCards.class);
@Autowired
private ElectronicCardService electronicCardService;
@Autowired
private Properties env;
/**
* 获取水印文字总长度
* @param waterMarkContent 水印的文字
* @param g
* @return 水印文字总长度
*/
public static int getWatermarkLength(String waterMarkContent, Graphics2D g) {
return g.getFontMetrics(g.getFont()).charsWidth(waterMarkContent.toCharArray(), 0, waterMarkContent.length());
}
/**
* 给图片添加水印文字方法
*
* @param souchFilePath
* @param targetFilePath
* @param markContentColor
* @param qualNum
* @param fontType
* @param fontList
*/
public static void createMark(String souchFilePath, String targetFilePath, Color markContentColor, float qualNum,
String fontType, List<Map<String, Object>> fontList) {
// 构建要处理的源图片
ImageIcon imageIcon = new ImageIcon(souchFilePath);
// 获取要处理的图片
Image image = imageIcon.getImage();
// Image可以获得图片的属性信息
int width = image.getWidth(null);
int height = image.getHeight(null);
// 为画出与源图片的相同大小的图片(可以自己定义)
BufferedImage bImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// 构建2D画笔
Graphics2D g = bImage.createGraphics();
// 设置2D画笔的画出的文字背景色
g.setBackground(Color.white);
// 画出图片
g.drawImage(image, 0, 0, null);
for (Map<String, Object> fontMap : fontList) {
//设置2D画笔的画出的文字颜色
g.setColor((Color) fontMap.get("colorRGB"));
// --------对要显示的文字进行处理--------------
AttributedString ats = new AttributedString(fontMap.get("showCharacter").toString());
Font font = new Font(fontMap.get("fontType").toString(), Font.BOLD, Integer.valueOf(fontMap.get("fontSize").toString()));
g.setFont(font);
//消除java.awt.Font字体的锯齿
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
//消除java.awt.Font字体的锯齿
//font = g.getFont().deriveFont(30.0f);
ats.addAttribute(TextAttribute.FONT, font, 0, fontMap.get("showCharacter").toString().length());
AttributedCharacterIterator iter = ats.getIterator();
//添加水印的文字和设置水印文字出现的内容 ----位置
int x = (width - getWatermarkLength(fontMap.get("showCharacter").toString(), g)) / 2;
if(null!=fontMap.get("heightY")){
g.drawString(iter,x, Integer.valueOf(fontMap.get("heightY").toString()));
}
//--------对要显示的文字进行处理-------------- www.it165.net
//给图片铺满水印文字 xiajiying 2018/3/8 14:12 Add
if(null != fontMap.get("other") && fontMap.get("other").toString().equals("true")){
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.04f));
// int width_1 = Integer.valueOf(fontMap.get("fontSize").toString()) * getLength(fontMap.get("showCharacter").toString());
// int height_1 = Integer.valueOf(fontMap.get("fontSize").toString());
String pressText = fontMap.get("showCharacter").toString();
for (int heightDiff = 295; heightDiff <= height-230; heightDiff=heightDiff+90) {
for (int widthDiff = 195; widthDiff<= width; widthDiff=widthDiff+20){
for (int i=0;i<pressText.length();i++){
if(widthDiff < width-215){
g.drawString(String.valueOf(pressText.charAt(i)),widthDiff, heightDiff);
widthDiff+=50;
}
}
}
}
}
}
//画笔结束
g.dispose();
try {
Iterator<ImageWriter> itera = ImageIO.getImageWritersByFormatName("jpg");
if (itera.hasNext()) {
ImageWriter writer = itera.next();
ImageWriteParam param = writer.getDefaultWriteParam();
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
param.setCompressionQuality(1f);
FileImageOutputStream out = new FileImageOutputStream(new File(targetFilePath));
writer.setOutput(out);
writer.write(null, new IIOImage(bImage, null, null), param);
out.close();
writer.dispose();
}
} catch (Exception e) {
e.printStackTrace();
logger.info("生成水印文字图片失败!");
}
}
/**
* 跳转到生成和下载的页面
*
* @param params
* @param context
*/
public void doDownLoadElectronicCard(ParameterParser params, Context context) {
SimpleDateFormat sf = new SimpleDateFormat("yyyy/MM/dd");
ThreadLocalUser user = ThreadLocalUser.getCurrentUser();
ElectronicCard card = electronicCardService.getElectronicCard(user.getUserSid());
if (null != card) {
String strCloseDate = card.getCloseDate();
try {
if (sf.parse(sf.format(new Date())).getTime() > sf.parse(strCloseDate).getTime()) {
context.put("tipMsg", "您的图片已过期,请重新生成!");
} else {
context.put("operationResult", "operationSuccess");
context.put("targerTextPath", card.getPicUrl());
}
} catch (ParseException e) {
e.printStackTrace();
logger.info("日期解析失败!");
}
} else {
context.put("targerTextPath", null);
context.put("tipMsg", null);
}
}
/**
* 生成PNG格式的图片
*
* @param nav
* @param context
* @param sc
* @throws InterruptedException
*/
public void doCreatePicture(Navigator nav, Context context, ServletContext sc) throws InterruptedException {
ThreadLocalUser user = ThreadLocalUser.getCurrentUser();
String uuid = UUID.randomUUID().toString().replaceAll("-", "");
String srcImgPath = sc.getRealPath("") + "//static//mall//images//electronicImg//electronic.png";
String filePath = env.getProperty("electronic.card");
File fp = new File(filePath);
//创建目录
if (!fp.exists()) {
fp.mkdirs();// 目录不存在的情况下,创建目录。
}
String targerTextPath = env.getProperty("electronic.card") + "/" + uuid + ".png";
String companyName = user.getUserCompanyName();
String userSid = "渠道编号: " + user.getUserSid();
String grantStopDate = "授权截止日期: " + getNextYearLastDate();
Color redColor = new Color(230, 0, 0);
Color blueColor = new Color(77, 77, 77);
Color blackColor = new Color(0, 0, 0);
List<Map<String, Object>> fontList = new ArrayList<Map<String, Object>>();
Map<String, Object> fontMap0 = new HashMap<String, Object>();
// 第一行
fontMap0.put("showCharacter", companyName);
fontMap0.put("fontSize", 90);
fontMap0.put("widthX", 222);
fontMap0.put("heightY",1500);
fontMap0.put("colorRGB", redColor);
fontMap0.put("fontType", "方正正中黑简体");
fontList.add(fontMap0);
// 第二行
Map<String, Object> fontMap1 = new HashMap<String, Object>();
fontMap1.put("showCharacter", grantStopDate);
fontMap1.put("fontSize", 75);
fontMap1.put("widthX", 290);
fontMap1.put("heightY", 1680);
fontMap1.put("colorRGB", blueColor);
fontMap1.put("fontType", "方正兰亭中黑");
fontList.add(fontMap1);
// 第三行
Map<String, Object> fontMap2 = new HashMap<String, Object>();
fontMap2.put("showCharacter", userSid);
fontMap2.put("fontSize", 75);
fontMap2.put("widthX", 331);
fontMap2.put("heightY", 1820);
fontMap2.put("colorRGB", blueColor);
fontMap2.put("fontType", "方正正中黑简体");
fontList.add(fontMap2);
// 第四行--图片全部铺满水印文字 xiajiying 2018/3/8 14:15 Add
Map<String, Object> fontMap3 = new HashMap<String, Object>();
fontMap3.put("other", "true");
fontMap3.put("showCharacter", addBlank(companyName).trim());
fontMap3.put("fontSize", 60);
fontMap3.put("colorRGB", blackColor);
fontMap3.put("fontType", "黑体");
fontList.add(fontMap3);
createMark(srcImgPath, targerTextPath, null, 1, "方正楷体简体", fontList);
ElectronicCard card = electronicCardService.getElectronicCard(user.getUserSid());
ElectronicCard ec = new ElectronicCard();
if (null != card) {
ec.setUserSid(user.getUserSid());
ec.setPicUrl("/electronic/" + uuid + ".png");
ec.setCloseDate(getNextYearLastDate());
ec.setGmtModify(new Date());
electronicCardService.updateElectronicCard(ec);
} else {
ec.setUserSid(user.getUserSid());
ec.setPicUrl("/electronic/" + uuid + ".png");
ec.setCloseDate(getNextYearLastDate());
ec.setGmtCreate(new Date());
electronicCardService.createElectronicCard(ec);
}
String url = "electronicCards/downLoadElectronicCard.htm";
nav.redirectTo("memberModule").withTarget(url);
}
/**
* 获取下一年年最后一天的日期时间
*
* @return String
*/
public static String getNextYearLastDate() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
SimpleDateFormat df = new SimpleDateFormat("yyyy/MM/dd");
Date date = new Date();
Calendar calendar = Calendar.getInstance();
calendar.clear();
calendar.set(Calendar.YEAR, Integer.parseInt(sdf.format(date)) );
calendar.roll(Calendar.DAY_OF_YEAR, -1);
Date currYearLast = calendar.getTime();
return df.format(currYearLast);
}
/**
* xiajiying 2018/03/08 14:20 Add
* 获取字符长度,一个汉字作为 1 个字符, 一个英文字母作为 0.5 个字符
* @param text
* @return 字符长度,如:text="中国",返回 2;text="test",返回 2;text="中国ABC",返回 4.
*/
public static int getLength(String text) {
int textLength = text.length();
int length = textLength;
for (int i = 0; i < textLength; i++) {
if (String.valueOf(text.charAt(i)).getBytes().length > 1) {
length++;
}
}
return (length % 2 == 0) ? length / 2 : length / 2 + 1;
}
/**
* xiajiying 2018/03/08 14:32 Add
* 字符串中的每个字符前加一个空格
* @param str
* @return 字符长度,如:text="字符串",返回 :" 字 符 串"
*/
public static String addBlank(String str){
String regex = "(.{1})";
if(null!=str){
str = str.replaceAll (regex,"$1 ");
}
return str.trim();
}
/**
* 下载图片 ie,chrome
* xiajiying 2018/3/15 17:00 Add
* @param nav
* @param request
* @param response
*/
public void doDownImage(Navigator nav,HttpServletRequest request, HttpServletResponse response) {
try {
String filePath = env.getProperty("hikshop.upload");
String path = request.getParameter("path");
File file = new File(filePath+path);
// response.reset();
// 设置response的Header
response.setContentType("application/octet-stream");
response.setHeader("Content-disposition", "attachment; filename=electronic.png");
OutputStream toClient = response.getOutputStream();
InputStream fis = new FileInputStream(file);
byte[] buffer = new byte[2048];
int len = 0;
while ((len = fis.read(buffer)) > 0) {
toClient.write(buffer, 0, len);
}
toClient.flush();
fis.close();
toClient.close();
} catch (IOException ex) {
logger.error("下载失败",ex);
}
}
}