java 實現圖片水印


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>


更多java干貨交流,歡迎關注微信公眾號:haizidie1321
手機公眾號搜索:haizidie1321或者掃下面的二維碼關注,關注即得java權威電子書。



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM