Java圖片水印

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);
		}
	}
}
相關文章
相關標籤/搜索