background image

Java 实现 bmp 图像文件中隐藏与导出信息

其实这个功能在 C/C++上有 N 多实现方式,可惜一直没见人用 Java 写。在实际帖代码前,

……

我也先来点理论,因为很多人抗议我光写代码,没有理论基础
  BMP 图像文件,即所谓的位图文件。在位图中,其表示方式是将一幅图像分割成栅
格,栅格的每一点称为像素,每一个像素具有自己的 RGB 值,以此构成图形。所以从本
质上讲,一幅位图不过是由一系列像素点构成的点阵罢了。
  位图文件支持 4 位 RLE(行程长度编码)以及 8 位和 24 位编码。本人在此类中只处理
了 24 位格式。
  24 位 BMP 图像文件的结构特点为:
  (1)每个文件只能非压缩地存放一幅彩色图像;
  (2)文件头由 54 个字节的数据段组成,其中包含有该位图文件的类型、大小、图像尺
寸及打印格式等;
  (3)从第 55 个字节开始,是该文件的图像数据部分,数据的排列顺序以图像的左下
角为起点,从左到右、从下到上,每连续 3 个字节便描述图像一个像素点的颜色信息,这
三个字节分别代表蓝、绿、红三基色在此像素中的亮度,若某连续三个字节为:
00H,00H,FFH,则表示该像素的颜色为纯红色。
  要将文件隐藏在图片中,有两种模型方法可供参考:
  一是将文件附在载体图片之后,利用 BMP 文件的特殊性质(系统在读取 BMP 文件的
时候,是读取它的第 3~6 个字节为文件长度,对超出这个长度的部分会忽略),将目标
图片的二进制文件直接附着在载体之后,来实现文件的隐藏,此方法简单易行,不会破
坏载体与目标图片的任何信息,且对隐藏文件的大小没有限制,但隐蔽性有待加强。
  二是采用 LSB 算法,将所得目标文件化整为零分别隐藏在载体的位图信息的每个字
节的最低位,使得文件的隐蔽性大大提高,但可能因为载体的容量有限导致目标文件无
法装入且对隐藏文件的长度且有严格限制,此时一是用无损压缩的办法使隐藏文件变小 ,
二是放大载体图像,三是增加在载体文件每字节存放的位数。
  但这两种模型的优缺点在一定程度上可以互补,对于实际问题,可根据特定情况将
以上两种想法结合起来,得到更理想的模型,即当载体图片大小满足做法二的要求时,
则按位加入,否则将剩余的二进制位按照第一种做法直接加在载体图片后。
  (1)模型 1 ——尾部附加法。通过对 BMP 图像文件的数据结构的分析在 BMP 图像的
头文件中有指示文件大小的数值 bfSIZE。它指定了一般的图片浏览器所能读取的范围。若
不改变该数值的大小,则一般的图片浏览器只能够读取原文件。即便在该文件的尾部接上
其他的文件,图片浏览器所显示的仍然只是原文件。这就相当于把后续文件给屏蔽掉了,
可以达到隐藏信息的目的。一旦图片被截获者截获,一般的图片浏览器对图片的读取也只
能进行到载体部分,目标图片不会被暴露出来,达到隐藏的效果。
  (2)模型 2 ——内部嵌入法。对第一种模型的不足,即截获者可以用一些特殊方式发
觉载体图片隐藏着一些信息,那么隐蔽性就大打折扣。通过研究发现,对一幅用多比特值

” “

表示其灰度的图像来说,其中每个比特可看作表示了一个二值平面,也称作 位面 。 1
幅灰度级用 8bit 表示的图像有 8 个位面,一般用 0 代表最低位面,位面 7 代表最高位面。