📜  Java DIP-应用水印(1)

📅  最后修改于: 2023-12-03 14:42:13.818000             🧑  作者: Mango

Java DIP-应用水印

简介

Java DIP(Digital Image Processing)即数字图像处理,它是指使用数字化设备和计算机来实现各种图像处理算法和技术的研究和应用。在Java DIP中,应用水印可以非常方便地对图片进行隐形保护,为图片版权提供有效的保障。

水印的原理

水印的原理就是把信息嵌入到原始数据中,这个嵌入的过程将会对最终数据产生微小的影响。而水印信息的提取则是基于这个特点,通过对原始数据进行分析和处理,从中提取出嵌入的信息。

水印的分类

水印大体可以分为两类:隐式水印和显式水印。隐式水印主要是在图像直接进行信息嵌入,使得肉眼难以识别,只有特定解码算法才能完成信息的提取;显式水印则是在图像中添加可见的水印,在图像上可以看到水印的形状和位置,也可以通过特殊的算法进行提取。

Java DIP中的应用

Java DIP中的应用水印可以分为两种类型:基于空域的水印和基于频域的水印。

基于空域的水印

基于空域的水印是指将水印信息嵌入到空间域的图像中,通过对图像的像素进行修改,嵌入水印信息。常用的算法有LSB算法和Kercker算法。

LSB(Less Significant Bit)算法即最低有效位算法,它使用图像中像素最低位进行信息的嵌入,因为原始图片的像素值不会因此而明显改变,从而使嵌入的信息难以被察觉。但是,这种隐蔽性也造成了LSB算法的灵敏度较低,抵抗攻击的能力相对较弱。

Kercker算法则是一种更为复杂的基于空域的水印算法,它通过利用图像局部特征进行水印嵌入和提取,兼具隐蔽性和鲁棒性。

基于频域的水印

基于频域的水印是指将水印信息嵌入到图像的频域中,通过对图像频谱的修改来嵌入水印,常用的算法有DCT算法和DWT算法。

DCT(Discrete Cosine Transform)算法是将图片的像素点变换为频繁分量的一种方法,它可以将原始图像变成可分解为若干个具有不同发生频率的余弦波阵列,从而可以针对水印的空间范围进行有选择性的嵌入和提取。

DWT(Discrete Wavelet Transform)算法是将原始图像分解成不同尺度的图像,从而可以提高算法的稳健性和安全性。因为它可以防止攻击者针对单个像素进行攻击,在提高隐蔽性的同时可以提高鲁棒性。

示例代码
// Java DIP实现LSB水印算法
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
public class LSBWatermark extends BufferedImage {
   BufferedImage image;
   String message;
   public LSBWatermark(BufferedImage img, String msg) {
      image = img;
      message = msg;
   }
   public BufferedImage createWatermark() {
      byte b[] = message.getBytes();
      int width = image.getWidth();
      int height = image.getHeight();
      int msglen = b.length;
      int imageType = image.getType();
      BufferedImage bwImage = new BufferedImage(width, height, imageType);
      int k = 0;
      for (int i = 0; i < height; i++) {
         for (int j = 0; j < width; j++) {
            int rgb = image.getRGB(j, i);
            int r = (rgb >> 16) & 0xff;
            int g = (rgb >> 8) & 0xff;
            int b = rgb & 0xff;
            if (k < msglen) {
               int charAscii = (int) b[k];
               for (int bit = 7; bit >= 0; --bit, ++k) {
                  int embeddingBit = (charAscii >>> bit) & 1;
                  if (embeddingBit == 1) {
                     if (b % 2 == 0) {
                        ++b;
                     }
                  } else {
                     if (b % 2 == 1) {
                        --b;
                     }
                  }
               }
            }
            bwImage.setRGB(j, i, (r << 16) | (g << 8) | b);
         }
      }
      return bwImage;
   }
}

该示例代码实现了一个基于LSB算法的水印嵌入和提取,通过对图像的像素进行修改,实现了文本信息的水印嵌入和提取。