编写过滤器,完成对bmp图片的信息隐写操作和读取
来源:互联网 发布:c语言 stdio.h 编辑:程序博客网 时间:2024/06/06 00:50
编写过滤器,完成对bmp图片的信息隐写操作和读取
上上周老师布置的web作业,我才今天写完,而且写的很艰难(下面是题目信息):
写这道题的思路:
- 首先上传txt文件和bmp文件
- 从input里面获取文件名,分别处理txt文件和image文件
- txt文件就是先获取文件内容转换为byte,再将byte转换为二进制的数组
- 对image文件处理:先获取image图片rgb值,再将txt文件转换的数组的每一位赋值给rgb的red green和blue的值的最后一位,再由新的rgb组成一张新的图片,存储到webContent的image文件夹下,再由MyAPI的类调用而显示出来
- 图片的读取则和隐写相反,先获取rgb里面的每个的最后一位存到数组里面,再将数组由二进制转换为byte,再由byte直接返回到过滤器的response的值
代码块
获取input里面的文件名称:
DiskFileUpload diskFileUpload = new DiskFileUpload(); List<FileItem> list = null; try { list = diskFileUpload.parseRequest(httpServletRequest); } catch (FileUploadException e) { e.printStackTrace(); } for(FileItem file : list) { System.out.println(file..getFieldName()) }
判断为txt文件:
if(file.getFieldName().equals("docField")) { byte[] bt = file.get(); int len = (bt.length+1)*8; bit = new byte[len]; for(int i = 0 ; i < bt.length ; i++) { for(int j = 0 ; j <= 7 ; j++) { //通过右移将byte数组转换为二进制 先右移再和0x01与得到最后一位 再赋值给二进制数组 bit[ i*8 + j] = (byte)((bt[i]>>(7-j)) & 0x01); } } }
判断为image文件:
else if(file.getFieldName().equals("imageField")) { InputStream img = file.getInputStream(); BufferedImage image = ImageIO.read(img); int height = image.getHeight(); //获取图片的高度 int width = image.getWidth();//获取图片宽度 int count = 0; //定义一个数来计数 for(int imgX = 0 ; imgX < width ; imgX++ ) { for(int imgY = 0 ; imgY < height ; imgY++ ) { int rgb = image.getRGB(imgX, imgY); //获取image图片的rgb值 Color color = new Color(rgb); //通过rgb值来定义color 再通过color分别获取red,green,blue的值 //再将获取到的值转换为 string类型 方便下面的substring运算 String r1 = Integer.toBinaryString((Integer)color.getRed()); String g1 = Integer.toBinaryString((Integer)color.getGreen()); String b1 = Integer.toBinaryString((Integer)color.getBlue()); //判断count有没有超出二进制数组的最大长度,进行substring运算来将二进制数组bit里面的值直接赋值给red,green和blue if(count+2<bit.length) { b1 = b1.substring(0, b1.length() - 1) + String.valueOf(bit[count+2]); } if(count+1<bit.length) { g1 = g1.substring(0, g1.length() - 1) + String.valueOf(bit[count+1]); } if(count<bit.length) { r1 = r1.substring(0, r1.length() - 1) + String.valueOf(bit[count]); } //将新的red green 和blue 用Integer.parseInt(red,2)来转换为数字,并组成新的rgb rgb = new Color(Integer.parseInt(r1, 2),Integer.parseInt(g1, 2),Integer.parseInt(b1, 2)).getRGB(); //将新的rgb重新填入到图片当中 image.setRGB(imgX, imgY, rgb); //一轮结束后因为 red green blue 用掉了三个值 所以count+3 count = count + 3; } } //for循环结束之后 将新的图片保存到 image文件夹下 //httpServletRequest.getRealPath("image") 是通过image这个名字获取该文件夹的路径 //ImageIO可以直接写入图片 ImageIO.write(image, "bmp", new File(httpServletRequest.getRealPath("image") + "/image.bmp")); }
判断结果是什么都不是:
else break;
这就完成了Image的写入操作
完成对图片的读取操作:
//通过文件名的路径来一个文件夹 //httpServletRequest.getRealPath("image")可以获取image的路径 File imgfile = new File(httpServletRequest.getRealPath("image") + "/image.bmp"); //用BufferedImage新建img 通过ImageIO.read(file)获取图片 BufferedImage img = ImageIO.read(imgfile); //将数组new一下 不new的话将会报空指针的错误 bit = new byte[197024 * 8]; //int 两个新的数来计数 int count = 0; int n = 0; //new一个新的byte数组存放二进制数 byte[] bt = new byte[bit.length*8]; //通过获取图片rgb来获取red green blue的最后一位 for(int imgX = 0 ; imgX < img.getWidth() ; imgX++) { for(int imgY = 0 ; imgY < img.getHeight() ; imgY++ ) { int rgb = img.getRGB(imgX, imgY); Color color = new Color(rgb); int r = color.getRed(); int g = color.getGreen(); int b = color.getBlue(); if(count<bit.length) { bt[count] = (byte) ( r & 0x01); } if(count+1<bit.length) { bt[count+1] = (byte) ( g & 0x01); } if(count+2<bit.length) { bt[count+2] = (byte) ( b & 0x01); } //因为red blue green 用掉了三个计数的 所以cout+3 count = count+3; } } //将二进制数组bt 转换为byte数组 //byte数组由8个二进制数组成 所以第二个循环的大小为8 //左移7-j得到的是由高到低的二进制 再相加 //相加后的整数赋值给bit里面的bit[n] 一个j循环 n加一次 代表的就是8个二进制数组成一个byte for(int i = 0 ;i < bt.length; i=i+8 ) { count = 0; for(int j = 0 ; j < 8 ; j++) { count = count + (bt[i+j]<<(7-j)); } bit[n] = (byte) count; n++; } //将bit传给respContext respContext.setEntity(bit);
这就完成了Image的读出操作
web.xml中需要将request和response配置一下 由于provider和filter(过滤器)和intercepter(拦截器)都是配置再provider 里面的:
<context-param> <param-name>resteasy.providers</param-name> <param-value> restful.filter.SteganalysisRequestFilter , restful.filter.SteganalysisResponseFilter </param-value> </context-param>
整个项目的各个文件的配置
MyAPI的内容:
package restful.api;import javax.ws.rs.GET;import javax.ws.rs.POST;import javax.ws.rs.Path;@Path("/a")public class MyAPI { @POST @Path("writeImage") public String writeImage() { return "<script>window.location.href = '../image/image.bmp' </script>"; } @GET @Path("readImage") public String readImage() { return ""; }}
SteganalysisRequestFilter的内容:
package restful.filter;import java.awt.Color;import java.awt.image.BufferedImage;import java.io.File;import java.io.IOException;import java.io.InputStream;import java.util.List;import javax.imageio.ImageIO;import javax.servlet.http.HttpServletRequest;import javax.ws.rs.container.ContainerRequestContext;import javax.ws.rs.container.ContainerRequestFilter;import javax.ws.rs.core.Context;import org.apache.commons.fileupload.DiskFileUpload;import org.apache.commons.fileupload.FileItem;import org.apache.commons.fileupload.FileUploadException;public class SteganalysisRequestFilter implements ContainerRequestFilter { @Context private HttpServletRequest httpServletRequest; private byte[] bit; @Override public void filter(ContainerRequestContext reqContext) throws IOException { if(httpServletRequest.getRequestURL().toString().contains(("writeImage"))) { DiskFileUpload diskFileUpload = new DiskFileUpload(); List<FileItem> list = null; try { list = diskFileUpload.parseRequest(httpServletRequest); } catch (FileUploadException e) { // TODO Auto-generated catch block e.printStackTrace(); } for(FileItem file : list) { if(file.getFieldName().equals("docField")) { //字符串用equals byte[] bt = file.get(); int len = (bt.length+1)*8; bit = new byte[len]; for(int i = 0 ; i < bt.length ; i++) { for(int j = 0 ; j <= 7 ; j++) { //通过右移将byte数组转换为二进制 先右移再和0x01与得到最后一位 再赋值给二进制数组 bit[ i*8 + j] = (byte)((bt[i]>>(7-j)) & 0x01); } } } else if(file.getFieldName().equals("imageField")) { InputStream img = file.getInputStream(); BufferedImage image = ImageIO.read(img); int height = image.getHeight(); //获取图片的高度 int width = image.getWidth();//获取图片宽度 int count = 0; //定义一个数来计数 for(int imgX = 0 ; imgX < width ; imgX++ ) { for(int imgY = 0 ; imgY < height ; imgY++ ) { int rgb = image.getRGB(imgX, imgY); //获取image图片的rgb值 Color color = new Color(rgb); //通过rgb值来定义color 再通过color分别获取red,green,blue的值 //再将获取到的值转换为 string类型 方便下面的substring运算 String r1 = Integer.toBinaryString((Integer)color.getRed()); String g1 = Integer.toBinaryString((Integer)color.getGreen()); String b1 = Integer.toBinaryString((Integer)color.getBlue()); //判断count有没有超出二进制数组的最大长度,进行substring运算来将二进制数组bit里面的值直接赋值给red,green和blue if(count+2<bit.length) { b1 = b1.substring(0, b1.length() - 1) + String.valueOf(bit[count+2]); } if(count+1<bit.length) { g1 = g1.substring(0, g1.length() - 1) + String.valueOf(bit[count+1]); } if(count<bit.length) { r1 = r1.substring(0, r1.length() - 1) + String.valueOf(bit[count]); } //将新的red green 和blue 用Integer.parseInt(red,2)来转换为数字,并组成新的rgb rgb = new Color(Integer.parseInt(r1, 2),Integer.parseInt(g1, 2),Integer.parseInt(b1, 2)).getRGB(); //将新的rgb重新填入到图片当中 image.setRGB(imgX, imgY, rgb); //一轮结束后因为 red green blue 用掉了三个值 所以count+3 count = count + 3; } } //for循环结束之后 将新的图片保存到 image文件夹下 //httpServletRequest.getRealPath("image") 是通过image这个名字获取该文件夹的路径 //ImageIO可以直接写入图片 ImageIO.write(image, "bmp", new File(httpServletRequest.getRealPath("image") + "/image.bmp")); } else break; } } }}
StegananlysisResponseFilter的内容:
package restful.filter;import java.awt.Color;import java.awt.image.BufferedImage;import java.io.File;import java.io.IOException;import javax.imageio.ImageIO;import javax.servlet.http.HttpServletRequest;import javax.ws.rs.container.ContainerRequestContext;import javax.ws.rs.container.ContainerResponseContext;import javax.ws.rs.container.ContainerResponseFilter;import javax.ws.rs.core.Context;public class SteganalysisResponseFilter implements ContainerResponseFilter { @Context private HttpServletRequest httpServletRequest; private byte[] bit; @Override public void filter(ContainerRequestContext reqContext, ContainerResponseContext respContext) throws IOException { if(httpServletRequest.getRequestURL().toString().contains("readImage")) { //通过文件名的路径来一个文件夹 //httpServletRequest.getRealPath("image")可以获取image的路径 File imgfile = new File(httpServletRequest.getRealPath("image") + "/image.bmp"); //用BufferedImage新建img 通过ImageIO.read(file)获取图片 BufferedImage img = ImageIO.read(imgfile); //将数组new一下 不new的话将会报空指针的错误 bit = new byte[197024 * 8]; //int 两个新的数来计数 int count = 0; int n = 0; //new一个新的byte数组存放二进制数 byte[] bt = new byte[bit.length*8]; //通过获取图片rgb来获取red green blue的最后一位 for(int imgX = 0 ; imgX < img.getWidth() ; imgX++) { for(int imgY = 0 ; imgY < img.getHeight() ; imgY++ ) { int rgb = img.getRGB(imgX, imgY); Color color = new Color(rgb); int r = color.getRed(); int g = color.getGreen(); int b = color.getBlue(); if(count<bit.length) { bt[count] = (byte) ( r & 0x01); } if(count+1<bit.length) { bt[count+1] = (byte) ( g & 0x01); } if(count+2<bit.length) { bt[count+2] = (byte) ( b & 0x01); } //因为red blue green 用掉了三个计数的 所以cout+3 count = count+3; } } //将二进制数组bt 转换为byte数组 //byte数组由8个二进制数组成 所以第二个循环的大小为8 //左移7-j得到的是由高到低的二进制 再相加 //相加后的整数赋值给bit里面的bit[n] 一个j循环 n加一次 代表的就是8个二进制数组成一个byte for(int i = 0 ;i < bt.length; i=i+8 ) { count = 0; for(int j = 0 ; j < 8 ; j++) { count = count + (bt[i+j]<<(7-j)); } bit[n] = (byte) count; n++; } //将bit传给respContext respContext.setEntity(bit); } }}
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_3_0.xsd" version="3.0"> <display-name>restful</display-name> <context-param> <param-name>resteasy.resources</param-name> <param-value>restful.api.MyAPI</param-value> </context-param> <context-param> <param-name>resteasy.providers</param-name> <param-value> restful.filter.SteganalysisRequestFilter,restful.filter.SteganalysisResponseFilter </param-value> </context-param> <listener> <listener-class>org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class> </listener> <servlet> <servlet-name>Resteasy</servlet-name> <servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class> </servlet> <context-param> <param-name>resteasy.servlet.mapping.prefix</param-name> <param-value>/</param-value> </context-param> <servlet-mapping> <servlet-name>Resteasy</servlet-name> <url-pattern>/a/*</url-pattern> </servlet-mapping></web-app>
index.jsp 的内容:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><script type="text/javascript" src="js/jquery-3.1.0.min.js"></script><title></title></head><body> <form action="${pageContext.request.contextPath}/a/writeImage" method="post" enctype="multipart/form-data"> <div align="center"> <fieldset style="width:80%"> <legend>上传文件</legend><br/> <div align="left">需要保密的文件</div> <div align="left"> <input type="file" name="docField"/> </div> <div align="left">保密信息载体BMP图片文件</div> <div align="left"> <input type="file" name="imageField"/> </div> <div> <div align='left'> <input type='submit' value="上传文件"/> </div> </div> </fieldset> </div> </form> <script> </script></body></html>
阅读全文
0 0
- 编写过滤器,完成对bmp图片的信息隐写操作和读取
- JAVA实现对BMP图片的读取
- java实现bmp图片信息隐写
- 读取bmp图片的文件头,与位图信息头
- 通过Delphi在SQL Server2000对BMP图像的存储和读取操作
- 关于Java读取和编写BMP文件的总结
- 详解javaPrintStream类完成对学生的信息读取和排序
- 读取bmp图片的一部分
- java编写的一个读取图片信息的小程序
- 游戏中bmp图片文件的读取
- PHP读取BMP格式图片的函数
- Flex 读取 bmp 格式的图片
- C语言读取BMP格式的图片
- PHP读取BMP格式图片的函数
- bmp图片的头相关信息
- 编写一工具栏,完成数据库的连接,并将数据库的信息写到配置文件中。
- 编写一工具栏,完成数据库的连接,并将数据库的信息写到配置文件中。
- java读取BMP图片
- TensorFlow restore模型时报错tensorflow.python.framework.errors_impl.NonArgumentError exception str()
- 关于反爬虫,看这一篇就够了!
- java JDBC方式操作mysql数据库
- 有点意思的程序员名言
- 音频视频学习日记
- 编写过滤器,完成对bmp图片的信息隐写操作和读取
- matplotlib函数库使用contour绘制等高线图形
- 防止tableview下移
- 伤害网站seo的javascript技术
- libsvm库简介及使用
- 小游戏---贪吃蛇
- HTML百度首页
- ios-ARC和MRC混编问题
- Android ViewPager轮播