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权威电子书。

