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;
}
}
View Code
图片上传方法实现类 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;
}
}
View Code
打水印的接口 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);
}
View Code
实现类:多个图片水印(将图片打在上传图片上) 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;
}
}
View Code
传输类 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;
}
}
View Code
效果图
原图:
加水印后:
总结:
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>