2016-09-09 22:58:24
前言
聽到水印這個詞,會想到各大狗仔扒的圖片上的小圖標,於是腦海開始想它的實現。。。
應該是把圖片打散,然后再重組。。。?
框架
這個是基於struts2實現的,當然不僅僅是這個框架,這個功能可以脫離框架,也可以用springmvc實現。
雖然是學的一個小應用,但還是想把eclipse下搭建struts2.0的過程記錄下來。
struts2.0框架搭建
jdk 1.8 + eclipse + tomcat 6.0
1.創建Dynamic Web Project
2.導入相應的jar
3.在src下新建struts.xml,進行基本配置
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd"> <struts> <constant name="struts.devMode" value="true"></constant> <constant name="struts.i18n.encoding" value="UTF-8"></constant> <constant name="struts.action.extension" value="action"></constant> <!-- 限制文件上傳的大小 單位為字節 --> <constant name="struts.multipart.maxSize" value="1073741824"></constant> <package name="struts" extends="struts-default" namespace="/"> </struts>
4.配置web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>watermark</display-name> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <filter> <filter-name>struts2</filter-name> <filter-class> org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter </filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <jsp-config> <taglib> <taglib-uri>http://java.sun.com/jstl/core</taglib-uri> <taglib-location>/WEB-INF/c.tld</taglib-location> </taglib> </jsp-config> </web-app>
至此,框架搭建完畢。(用於eclipse下搭建struts2查閱使用)
-------------------------------------------------------------------------------------------------------------------------------------------------------------
Java圖片水印實現思路
1.創建緩存圖片對象--BufferedImage
2.創建Java繪圖工具對象--Graphics2D
3.使用繪圖工具對象將原圖片繪制到緩存圖片對象中
4.使用繪圖工具對象將水印(文字/圖片)繪制到緩存圖片對象中
5.創建圖像編碼工具類對象--JPEGImageEncoder
6.使用圖像編碼工具類對象,輸出緩存對象到目標圖片文件
代碼實現:
用於接收上傳圖片的action WaterMarkAction

/** *用於接收上傳圖片的action */ public class WaterMarkAction extends ActionSupport { /** * */ private static final long serialVersionUID = 1L; private File[] image; private String[] imageFileName; private String uploadPath; private List<PicInfo> pic = new ArrayList<PicInfo>(); public List<PicInfo> getPic() { return pic; } public void setPic(List<PicInfo> pic) { this.pic = pic; } public String waterMark() throws Exception { MarkService markService = new MoreImageWaterMarkImpl(); // MarkService markService = new MoreTextWaterMarkImpl(); // MarkService markService = new ImageWaterMarkImpl(); // MarkService markService = new TextWaterMarkImpl(); String realPath = ServletActionContext.getServletContext().getRealPath(uploadPath); UploadService service = new UploadService(); if(null != image && image.length > 0) { for (int i = 0; i < image.length; i++) { PicInfo info = new PicInfo(); //多文件上傳時,封裝原圖的顯示路徑 info.setImageURL(service.uploadImage(image[i], imageFileName[i], uploadPath, realPath)); //多文件上傳時,封裝水印圖的顯示路徑 info.setLogoImageURL(markService.waterMark(image[i], imageFileName[i], uploadPath, realPath)); pic.add(info); } } return SUCCESS; } public File[] getImage() { return image; } public void setImage(File[] image) { this.image = image; } public String[] getImageFileName() { return imageFileName; } public void setImageFileName(String[] imageFileName) { this.imageFileName = imageFileName; } public String getUploadPath() { return uploadPath; } public void setUploadPath(String uploadPath) { this.uploadPath = uploadPath; } }
圖片上傳方法實現類 UploadService

public class UploadService { public String uploadImage(File image, String fileName, String uploadPath, String realPath) { InputStream is = null; OutputStream os = null; try { is = new FileInputStream(image); os = new FileOutputStream(realPath + "/" + fileName); byte[] buffer = new byte[1024]; int len = 0; while ((len = is.read(buffer)) != -1) { os.write(buffer); } } catch (Exception e) { e.printStackTrace(); }finally { if(null != is) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } if(null != os) { try { os.close(); } catch (IOException e) { e.printStackTrace(); } } } return uploadPath + "/" + fileName; } }
打水印的接口 MarkService

/** * 水印接口 * * @author Administrator * */ public interface MarkService { //文字樣式 String MARK_TEXT = "孩子爹"; String FONT_NAME = "微軟雅黑"; int FONT_STYLE = Font.BOLD; int FONT_SIZE = 120; Color FONT_COLOR = Color.green; //文字位置 int X = 10; int Y = 10; //透明度 float ALPHA = 0.3f; String LOGO = "logo.png"; //打水印 String waterMark(File image, String fileName, String uploadPath, String realPath); }
實現類:多個圖片水印(將圖片打在上傳圖片上) MoreImageWaterMarkImpl

public class MoreImageWaterMarkImpl implements MarkService { @Override public String waterMark(File image, String fileName, String uploadPath, String realPath) { String logoFileName = "logo_" + fileName; OutputStream os = null; try { Image image2 = ImageIO.read(image); int width = image2.getWidth(null); int heigth = image2.getHeight(null); BufferedImage bufferImage = new BufferedImage(width, heigth, BufferedImage.TYPE_INT_RGB); Graphics2D g = bufferImage.createGraphics(); g.drawImage(image2, 0, 0, width, heigth, null); String logoPath = realPath + "/" + LOGO; File logoFile = new File(logoPath); Image logo = ImageIO.read(logoFile); int widthReal = logo.getWidth(null); int heigthReal = logo.getHeight(null); g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, ALPHA)); // 因為水印已經傾斜,所以不做畫布傾斜 // g.rotate(Math.toRadians(30), bufferImage.getWidth() / 2, // bufferImage.getHeight() / 2); int x = -width / 2; int y = -heigth / 2; while (x < width * 1.5) { y = -heigth / 2; while (y < heigth * 1.5) { g.drawImage(logo, x, y, null); y += heigthReal + 200; } x += widthReal + 200; } g.dispose(); os = new FileOutputStream(realPath + "/" + logoFileName); JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(os); encoder.encode(bufferImage); } catch (Exception e) { e.printStackTrace(); } finally { if (null != os) { try { os.close(); } catch (IOException e) { e.printStackTrace(); } } } return uploadPath + "/" + logoFileName; } }
傳輸類 PicInfo

public class PicInfo { private String imageURL; private String logoImageURL; public String getImageURL() { return imageURL; } public void setImageURL(String imageURL) { this.imageURL = imageURL; } public String getLogoImageURL() { return logoImageURL; } public void setLogoImageURL(String logoImageURL) { this.logoImageURL = logoImageURL; } }
效果圖
原圖:
加水印后:
總結:
1.在學習過程中,發現struts 標簽和EL還是不太一樣,下圖中的pic是通過struts2轉發回前台的一個list集合,而imageURL和logoImageURL分別是上面傳輸類的成員
<table width="99%" align="center"> <s:iterator value="pic"> <tr> <td><img width="555" src='<%=basePath %><s:property value="imageURL"/>' /></td> <td><img width="555" src='<%=basePath %><s:property value="logoImageURL"/>' /></td> </tr> </s:iterator> </table>
更多java干貨交流,歡迎關注微信公眾號:haizidie1321
手機公眾號搜索:haizidie1321或者掃下面的二維碼關注,關注即得java權威電子書。

