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); } } }