实践简单的动态水印的总结

参照java程序员之旅<JSP开发技术详解>  卢汉鹏等编著  化学工业出版社出版  的讲解,做的。

在入题前,我先表达一下自己对这本书的,憎恶骂人岂一个烂字了得得到的,错误一大片,代码也有问题。今天做的这个动态水印就是原书上代码出现Fatal ERROR!!!

好,不吐不快;说出来,我感觉好多了。但我更多的是希望,那些同志们,一定要谨慎对待这本书

现在正是bla  bla  bla:

原理部分

      添加水印的话,就是对图片进行操作,将水印对应的像素覆盖原始图片的特定区域。这里,我们使用JSP中的filter来进行处理。因为当一个文件被request 的时候,WEB容器(我的就是tomcat)会根据application的web.xml中的配置信息进行处理。我们配置了过滤器,过滤器就会首先对request和response进行处理。然后,把request,response交付给对应的controller去进一步处理。

具体内容

        首先,编写对两个Image对象进行合并的类:ImageUtil.java

就是首先获取两个Image对象,然后开辟一个图片缓存区,先将原始图片写入缓存,然后将水印图片写入缓存的对应位置。最后返回这个缓存对象。

package test.watermarker;

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;

/**
 * Created with IntelliJ IDEA.
 * Date: 13-7-10
 * Time: 上午9:16
 * To change this template use File | Settings | File Templates.
 */
public class ImageUtil {
    /*
    * @param imageData JPG file
    * @param waterMarkFile waterMark file
    * @return marked file
    * @throws IOException
    * */
    public static byte[] waterMark (byte[] imageData, String waterMarkFile) throws IOException {
        int paddingRight = 10;
        int paddingBottom = 10;

        Image image = new ImageIcon(imageData).getImage();
        int imageWidth = image.getWidth(null);
        int imageHeight = image.getHeight(null);

        Image waterMark = ImageIO.read(new File(waterMarkFile));
        int waterMarkWidth = waterMark.getWidth(null);
        int waterMarkHeight = waterMark.getHeight(null);

        if (imageWidth < waterMarkWidth + 2 * paddingRight
                || imageHeight < waterMarkHeight + 2 * paddingBottom) {
            return imageData;
        }

        BufferedImage bufferedImage = new BufferedImage(imageWidth,imageHeight,BufferedImage.TYPE_INT_RGB);
        Graphics g = bufferedImage.createGraphics();

        g.drawImage(image,0,0,imageWidth,imageHeight,null);
        g.drawImage(waterMark,imageWidth - waterMarkWidth - paddingRight,imageHeight - waterMarkHeight - paddingBottom,waterMarkWidth,waterMarkHeight,null);
        g.dispose();

        ByteArrayOutputStream out = new ByteArrayOutputStream();
        JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
        encoder.encode(bufferedImage);
        byte[] data = out.toByteArray();
        out.close();
        return data;
    }
}
做动态水印的话,就是修改了response,这里我们单独做一个wrapper:Response_WaterMark.java

package test.watermarker;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;

/**
 * Created with IntelliJ IDEA.
 * Date: 13-7-10
 * Time: 上午9:39
 * To change this template use File | Settings | File Templates.
 */
public class Response_WaterMark extends HttpServletResponseWrapper {
    private String waterMarkFile;
    private String originalImageFile;
    private HttpServletResponse response;

    private WaterMark_Output waterMarkOutputStream;

    public Response_WaterMark(HttpServletResponse response, String waterMarkFile, String imageOriginal) throws IOException {
        super(response);
        this.response = response;
        this.waterMarkFile = waterMarkFile;
        this.originalImageFile = imageOriginal;
        waterMarkOutputStream = new WaterMark_Output();
    }
    @Override
    public ServletOutputStream getOutputStream() throws IOException {
        return waterMarkOutputStream;
    }

    @Override
    public void flushBuffer() throws IOException {
        waterMarkOutputStream.flush();
    }
    public void finishResponse() throws IOException{
        //the original image data
        File file = new File(originalImageFile);
        if(file.exists() && file.canRead()){
            System.out.println("all files can be read!!!bla bla bla");
            BufferedImage imageaa = ImageIO.read(file);
            ByteArrayOutputStream tmp = new ByteArrayOutputStream();
            ImageIO.write(imageaa,"jpg",tmp);
            byte[] imageData = tmp.toByteArray();

            //the data after water marked
            byte[] image = ImageUtil.waterMark(imageData,waterMarkFile);

            response.setContentLength(image.length);
            response.getOutputStream().write(image);


        } else {
            System.out.println("the original image file can NOT be read!!!bla bla bla");
            BufferedImage waterMark = ImageIO.read(new File(waterMarkFile));
            ByteArrayOutputStream tmp = new ByteArrayOutputStream();
            ImageIO.write(waterMark,"jpg",tmp);
            byte[] tmpImage = tmp.toByteArray();
            response.setContentLength(tmpImage.length);
            response.getOutputStream().write(tmpImage);
        }
        waterMarkOutputStream.close();
    }
}

而这个response依赖于ServletOutputStream。因此,要单独编写一个继承了ServletOutputStream的类:WaterMark_Output.java

package test.watermarker;

import javax.servlet.ServletOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

/**
 * Created with IntelliJ IDEA.
 * Date: 13-7-10
 * Time: 上午9:32
 * To change this template use File | Settings | File Templates.
 */
public class WaterMark_Output extends ServletOutputStream {
    private ByteArrayOutputStream byteArrayOutputStream;

    public WaterMark_Output() throws IOException {
        byteArrayOutputStream = new ByteArrayOutputStream();
    }

    @Override
    public void write(int b) throws IOException {
        //To change body of implemented methods use File | Settings | File Templates.
        byteArrayOutputStream.write(b);
    }

    @Override
    public void close() throws IOException {
        byteArrayOutputStream.close();
    }

    @Override
    public void flush() throws IOException {
        byteArrayOutputStream.flush();
    }

    @Override
    public void write(byte[] b, int off, int len) throws IOException {
        byteArrayOutputStream.write(b, off, len);
    }

    @Override
    public void write(byte[] b) throws IOException {
        byteArrayOutputStream.write(b);
    }

    public ByteArrayOutputStream getByteArrayOutputStream(){
        return byteArrayOutputStream;
    }
}
最后,就是我们的filter了:Filter_Water.java

package test.watermarker;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * Created with IntelliJ IDEA.
 * Date: 13-7-10
 * Time: 上午9:49
 * To change this template use File | Settings | File Templates.
 */
public class Filter_Water implements Filter {
    private String waterMarkFile;

    @Override
    public void init(FilterConfig config) throws ServletException {
        String file = config.getInitParameter("waterMarkFile");
        waterMarkFile = config.getServletContext().getRealPath(file);
        System.out.println("the water MARK file is located in "+waterMarkFile);
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        String imageOriginal = request.getRequestURI();
        System.out.println("the original file is located in "+imageOriginal);
        Response_WaterMark responseWaterMark = new Response_WaterMark(response,waterMarkFile,imageOriginal);


        System.out.println("next will deal with image showed");
        responseWaterMark.finishResponse();
        chain.doFilter(request,responseWaterMark);
    }

    @Override
    public void destroy() {
        //To change body of implemented methods use File | Settings | File Templates.
    }
}

这些编写好之后呢,需要配置web.xml文件:添加的内容如下

<!--Water Marker for image formated by JPEG-->
    <filter>
        <filter-name>waterMarker</filter-name>
        <filter-class>test.watermarker.Filter_Water</filter-class>
        <init-param>
            <param-name>waterMarkFile</param-name>
            <param-value>/waterMark.jpg</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>waterMarker</filter-name>
        <url-pattern>*.jpg</url-pattern>
    </filter-mapping>
其中, waterMark.jpg是放在了webapp\ROOT\;这一点切记!!!ROOT是我的项目目录

即将被访问的图片test.jpg也是放在了我tomcat所在盘符的根目录下;这一点切记!!!

访问结果如下:



       



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值