工具类:ImageUtil.java MathTool.java
- package com.zeph.watermark.util;
- public class MathTool {
- public static double[][] intToDoubleMatrix(int[][] input) {
- int height = input.length;
- int width = input[0].length;
- double[][] output = new double[height][width];
- for (int i = 0; i < height; i++) {
- // 列
- for (int j = 0; j < width; j++) {
- // 行
- output[i][j] = Double.valueOf(String.valueOf(input[i][j]));
- System.out.print(output[i][j]);
- }
- System.out.println();
- }
- return output;
- }
- public static double[] intToDoubleArray(int[] input) {
- int length = input.length;
- double[] output = new double[length];
- for (int i = 0; i < length; i++)
- output[i] = Double.valueOf(String.valueOf(input[i]));
- return output;
- }
- public static void main(String[] args) {
- int[][] test = { { 4, 5, 6 }, { 1, 2, 3 } };
- MathTool.intToDoubleMatrix(test);
- }
- }
- package com.zeph.watermark.util;
- public class MathTool {
- public static double[][] intToDoubleMatrix(int[][] input) {
- int height = input.length;
- int width = input[0].length;
- double[][] output = new double[height][width];
- for (int i = 0; i < height; i++) {
- // 列
- for (int j = 0; j < width; j++) {
- // 行
- output[i][j] = Double.valueOf(String.valueOf(input[i][j]));
- System.out.print(output[i][j]);
- }
- System.out.println();
- }
- return output;
- }
- public static double[] intToDoubleArray(int[] input) {
- int length = input.length;
- double[] output = new double[length];
- for (int i = 0; i < length; i++)
- output[i] = Double.valueOf(String.valueOf(input[i]));
- return output;
- }
- public static void main(String[] args) {
- int[][] test = { { 4, 5, 6 }, { 1, 2, 3 } };
- MathTool.intToDoubleMatrix(test);
- }
- }
- package com.zeph.watermark.util;
- import java.awt.image.BufferedImage;
- import java.awt.image.WritableRaster;
- import java.io.File;
- import java.io.IOException;
- import javax.imageio.ImageIO;
- public class ImageUtil {
- /**
- * 获取图片
- *
- * @param filepath
- * @return
- */
- public static BufferedImage getImage(String filepath) {
- BufferedImage image = null;
- File file = new File(filepath);
- try {
- image = ImageIO.read(file);
- } catch (IOException e) {
- e.printStackTrace();
- }
- return image;
- }
- /**
- * 获取图像文件的像素(图片转换为像素)
- *
- * @param filepath
- * @param format
- */
- public int[] getImagePixels(String filepath) {
- BufferedImage image = null;
- File file = new File(filepath);
- try {
- image = ImageIO.read(file);
- } catch (IOException e) {
- e.printStackTrace();
- }
- WritableRaster raster = image.getRaster();
- // 得到图像的宽度
- int width = raster.getWidth();
- // 得到图像的高度
- int height = raster.getHeight();
- // RGB格式图像文件每一个点的颜色由红、绿、兰三种颜色构成,即实际图像可为3层,
- // 分别为R,G,B层,因此分解后的文件象素是实际坐标高度和宽度的三倍。
- int[] pixels = new int[3 * width * height];
- // 读取坐标的范围是从(0,0)坐标开始宽width,高height
- raster.getPixels(0, 0, width, height, pixels);
- return pixels;
- }
- /**
- * 像素转换成图像文件
- *
- * @param result
- * @param width
- * @param height
- * @param filepath
- * @param format
- */
- public static void setImage(double[] result, int width, int height,
- String filepath, String format, int type) {
- BufferedImage outImage = new BufferedImage(width, height, type);
- WritableRaster outRaster = outImage.getRaster();
- outRaster.setPixels(0, 0, width, height, result);
- // 图像文件的写入
- File outFile = new File(filepath);
- try {
- ImageIO.write(outImage, format, outFile);
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- /**
- * 一维数组转为二维数组
- *
- * @param m
- * @param width
- * @param height
- * @return
- */
- public static int[][] arrayToMatrix(int[] m, int width, int height) {
- int[][] result = new int[height][width];
- for (int i = 0; i < height; i++) {
- for (int j = 0; j < width; j++) {
- int p = j * height + i;
- result[i][j] = m[p];
- }
- }
- return result;
- }
- /**
- * 一维数组转换为三维数组
- *
- * @param pixels
- * @param width
- * @param height
- * @return
- */
- public static int[][][] getRGBArrayToMatrix(int[] pixels, int width,
- int height) {
- // 已知有3个二维数组组成分别代表RGB
- int[][][] result = new int[3][height][width];
- int[][] temp = new int[3][width * height];
- for (int i = 0; i < pixels.length; i++) {
- int m = i / 3;
- int n = i % 3;
- temp[n][m] = pixels[i];
- }
- result[0] = arrayToMatrix(temp[0], width, height);
- result[1] = arrayToMatrix(temp[1], width, height);
- result[2] = arrayToMatrix(temp[2], width, height);
- return result;
- }
- /**
- * 二维数组转为一维数组
- *
- * @param m
- * @return
- */
- public static double[] matrixToArray(double[][] m) {
- int p = m.length * m[0].length;
- double[] result = new double[p];
- for (int i = 0; i < m.length; i++) {
- for (int j = 0; j < m[i].length; j++) {
- int q = j * m.length + i;
- result[q] = m[i][j];
- }
- }
- return result;
- }
- /**
- * 三维数组转为一维数组
- *
- * @param m
- * @return
- */
- public static double[] getRGBMatrixToArray(double[][][] m) {
- int width = m[0].length;
- int height = m[0][0].length;
- int len = width * height;
- double[] result = new double[3 * len];
- double[][] temp = new double[3][len];
- temp[0] = matrixToArray(m[0]);
- temp[1] = matrixToArray(m[1]);
- temp[2] = matrixToArray(m[2]);
- for (int i = 0; i < 3; i++) {
- for (int j = 0; j < temp[i].length; j++)
- result[3 * j + i] = temp[i][j];
- }
- return result;
- }
- }
- package com.zeph.watermark.util;
- import java.awt.image.BufferedImage;
- import java.awt.image.WritableRaster;
- import java.io.File;
- import java.io.IOException;
- import javax.imageio.ImageIO;
- public class ImageUtil {
- /**
- * 获取图片
- *
- * @param filepath
- * @return
- */
- public static BufferedImage getImage(String filepath) {
- BufferedImage image = null;
- File file = new File(filepath);
- try {
- image = ImageIO.read(file);
- } catch (IOException e) {
- e.printStackTrace();
- }
- return image;
- }
- /**
- * 获取图像文件的像素(图片转换为像素)
- *
- * @param filepath
- * @param format
- */
- public int[] getImagePixels(String filepath) {
- BufferedImage image = null;
- File file = new File(filepath);
- try {
- image = ImageIO.read(file);
- } catch (IOException e) {
- e.printStackTrace();
- }
- WritableRaster raster = image.getRaster();
- // 得到图像的宽度
- int width = raster.getWidth();
- // 得到图像的高度
- int height = raster.getHeight();
- // RGB格式图像文件每一个点的颜色由红、绿、兰三种颜色构成,即实际图像可为3层,
- // 分别为R,G,B层,因此分解后的文件象素是实际坐标高度和宽度的三倍。
- int[] pixels = new int[3 * width * height];
- // 读取坐标的范围是从(0,0)坐标开始宽width,高height
- raster.getPixels(0, 0, width, height, pixels);
- return pixels;
- }
- /**
- * 像素转换成图像文件
- *
- * @param result
- * @param width
- * @param height
- * @param filepath
- * @param format
- */
- public static void setImage(double[] result, int width, int height,
- String filepath, String format, int type) {
- BufferedImage outImage = new BufferedImage(width, height, type);
- WritableRaster outRaster = outImage.getRaster();
- outRaster.setPixels(0, 0, width, height, result);
- // 图像文件的写入
- File outFile = new File(filepath);
- try {
- ImageIO.write(outImage, format, outFile);
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- /**
- * 一维数组转为二维数组
- *
- * @param m
- * @param width
- * @param height
- * @return
- */
- public static int[][] arrayToMatrix(int[] m, int width, int height) {
- int[][] result = new int[height][width];
- for (int i = 0; i < height; i++) {
- for (int j = 0; j < width; j++) {
- int p = j * height + i;
- result[i][j] = m[p];
- }
- }
- return result;
- }
- /**
- * 一维数组转换为三维数组
- *
- * @param pixels
- * @param width
- * @param height
- * @return
- */
- public static int[][][] getRGBArrayToMatrix(int[] pixels, int width,
- int height) {
- // 已知有3个二维数组组成分别代表RGB
- int[][][] result = new int[3][height][width];
- int[][] temp = new int[3][width * height];
- for (int i = 0; i < pixels.length; i++) {
- int m = i / 3;
- int n = i % 3;
- temp[n][m] = pixels[i];
- }
- result[0] = arrayToMatrix(temp[0], width, height);
- result[1] = arrayToMatrix(temp[1], width, height);
- result[2] = arrayToMatrix(temp[2], width, height);
- return result;
- }
- /**
- * 二维数组转为一维数组
- *
- * @param m
- * @return
- */
- public static double[] matrixToArray(double[][] m) {
- int p = m.length * m[0].length;
- double[] result = new double[p];
- for (int i = 0; i < m.length; i++) {
- for (int j = 0; j < m[i].length; j++) {
- int q = j * m.length + i;
- result[q] = m[i][j];
- }
- }
- return result;
- }
- /**
- * 三维数组转为一维数组
- *
- * @param m
- * @return
- */
- public static double[] getRGBMatrixToArray(double[][][] m) {
- int width = m[0].length;
- int height = m[0][0].length;
- int len = width * height;
- double[] result = new double[3 * len];
- double[][] temp = new double[3][len];
- temp[0] = matrixToArray(m[0]);
- temp[1] = matrixToArray(m[1]);
- temp[2] = matrixToArray(m[2]);
- for (int i = 0; i < 3; i++) {
- for (int j = 0; j < temp[i].length; j++)
- result[3 * j + i] = temp[i][j];
- }
- return result;
- }
- }
实现类:Dct.java FDct.java IFDct.java AddWatermark.java ExtractWatermark.java
- package com.zeph.watermark.fdct;
- public interface Dct {
- static double C1 = 0.98078528, C2 = 0.923879532, C3 = 0.831469612,
- C4 = 0.707106781, C5 = 0.555570233, C6 = 0.382683432,
- C7 = 0.195090322;
- }
- package com.zeph.watermark.fdct;
- public interface Dct {
- static double C1 = 0.98078528, C2 = 0.923879532, C3 = 0.831469612,
- C4 = 0.707106781, C5 = 0.555570233, C6 = 0.382683432,
- C7 = 0.195090322;
- }
- package com.zeph.watermark.fdct;
- public class FDct implements Dct {
- public static double[][] fDctTransform(double[][] ablk) {
- double[][] blk = new double[8][8];
- for (int i = 0; i < 8; i++) {
- for (int j = 0; j < 8; j++) {
- blk[i][j] = ablk[i][j];
- }
- }
- // 对行变换
- for (int i = 0; i <= 7; i++) {
- double S07, S16, S25, S34, S0734, S1625;
- double D07, D16, D25, D34, D0734, D1625;
- S07 = blk[i][0] + blk[i][7];
- S16 = blk[i][1] + blk[i][6];
- S25 = blk[i][2] + blk[i][5];
- S34 = blk[i][3] + blk[i][4];
- S0734 = S07 + S34;
- S1625 = S16 + S25;
- D07 = blk[i][0] - blk[i][7];
- D16 = blk[i][1] - blk[i][6];
- D25 = blk[i][2] - blk[i][5];
- D34 = blk[i][3] - blk[i][4];
- D0734 = S07 - S34;
- D1625 = S16 - S25;
- blk[i][0] = 0.5 * (C4 * (S0734 + S1625));
- blk[i][1] = 0.5 * (C1 * D07 + C3 * D16 + C5 * D25 + C7 * D34);
- blk[i][2] = 0.5 * (C2 * D0734 + C6 * D1625);
- blk[i][3] = 0.5 * (C3 * D07 - C7 * D16 - C1 * D25 - C5 * D34);
- blk[i][4] = 0.5 * (C4 * (S0734 - S1625));
- blk[i][5] = 0.5 * (C5 * D07 - C1 * D16 + C7 * D25 + C3 * D34);
- blk[i][6] = 0.5 * (C6 * D0734 - C2 * D1625);
- blk[i][7] = 0.5 * (C7 * D07 - C5 * D16 + C3 * D25 - C1 * D34);
- }
- // 对列变换
- for (int j = 0; j <= 7; j++) {
- double S07, S16, S25, S34, S0734, S1625;
- double D07, D16, D25, D34, D0734, D1625;
- S07 = blk[0][j] + blk[7][j];
- S16 = blk[1][j] + blk[6][j];
- S25 = blk[2][j] + blk[5][j];
- S34 = blk[3][j] + blk[4][j];
- S0734 = S07 + S34;
- S1625 = S16 + S25;
- D07 = blk[0][j] - blk[7][j];
- D16 = blk[1][j] - blk[6][j];
- D25 = blk[2][j] - blk[5][j];
- D34 = blk[3][j] - blk[4][j];
- D0734 = S07 - S34;
- D1625 = S16 - S25;
- blk[0][j] = 0.5 * (C4 * (S0734 + S1625));
- blk[1][j] = 0.5 * (C1 * D07 + C3 * D16 + C5 * D25 + C7 * D34);
- blk[2][j] = 0.5 * (C2 * D0734 + C6 * D1625);
- blk[3][j] = 0.5 * (C3 * D07 - C7 * D16 - C1 * D25 - C5 * D34);
- blk[4][j] = 0.5 * (C4 * (S0734 - S1625));
- blk[5][j] = 0.5 * (C5 * D07 - C1 * D16 + C7 * D25 + C3 * D34);
- blk[6][j] = 0.5 * (C6 * D0734 - C2 * D1625);
- blk[7][j] = 0.5 * (C7 * D07 - C5 * D16 + C3 * D25 - C1 * D34);
- }
- return blk;
- }
- }
- package com.zeph.watermark.fdct;
- public class FDct implements Dct {
- public static double[][] fDctTransform(double[][] ablk) {
- double[][] blk = new double[8][8];
- for (int i = 0; i < 8; i++) {
- for (int j = 0; j < 8; j++) {
- blk[i][j] = ablk[i][j];
- }
- }
- // 对行变换
- for (int i = 0; i <= 7; i++) {
- double S07, S16, S25, S34, S0734, S1625;
- double D07, D16, D25, D34, D0734, D1625;
- S07 = blk[i][0] + blk[i][7];
- S16 = blk[i][1] + blk[i][6];
- S25 = blk[i][2] + blk[i][5];
- S34 = blk[i][3] + blk[i][4];
- S0734 = S07 + S34;
- S1625 = S16 + S25;
- D07 = blk[i][0] - blk[i][7];
- D16 = blk[i][1] - blk[i][6];
- D25 = blk[i][2] - blk[i][5];
- D34 = blk[i][3] - blk[i][4];
- D0734 = S07 - S34;
- D1625 = S16 - S25;
- blk[i][0] = 0.5 * (C4 * (S0734 + S1625));
- blk[i][1] = 0.5 * (C1 * D07 + C3 * D16 + C5 * D25 + C7 * D34);
- blk[i][2] = 0.5 * (C2 * D0734 + C6 * D1625);
- blk[i][3] = 0.5 * (C3 * D07 - C7 * D16 - C1 * D25 - C5 * D34);
- blk[i][4] = 0.5 * (C4 * (S0734 - S1625));
- blk[i][5] = 0.5 * (C5 * D07 - C1 * D16 + C7 * D25 + C3 * D34);
- blk[i][6] = 0.5 * (C6 * D0734 - C2 * D1625);
- blk[i][7] = 0.5 * (C7 * D07 - C5 * D16 + C3 * D25 - C1 * D34);
- }
- // 对列变换
- for (int j = 0; j <= 7; j++) {
- double S07, S16, S25, S34, S0734, S1625;
- double D07, D16, D25, D34, D0734, D1625;
- S07 = blk[0][j] + blk[7][j];
- S16 = blk[1][j] + blk[6][j];
- S25 = blk[2][j] + blk[5][j];
- S34 = blk[3][j] + blk[4][j];
- S0734 = S07 + S34;
- S1625 = S16 + S25;
- D07 = blk[0][j] - blk[7][j];
- D16 = blk[1][j] - blk[6][j];
- D25 = blk[2][j] - blk[5][j];
- D34 = blk[3][j] - blk[4][j];
- D0734 = S07 - S34;
- D1625 = S16 - S25;
- blk[0][j] = 0.5 * (C4 * (S0734 + S1625));
- blk[1][j] = 0.5 * (C1 * D07 + C3 * D16 + C5 * D25 + C7 * D34);
- blk[2][j] = 0.5 * (C2 * D0734 + C6 * D1625);
- blk[3][j] = 0.5 * (C3 * D07 - C7 * D16 - C1 * D25 - C5 * D34);
- blk[4][j] = 0.5 * (C4 * (S0734 - S1625));
- blk[5][j] = 0.5 * (C5 * D07 - C1 * D16 + C7 * D25 + C3 * D34);
- blk[6][j] = 0.5 * (C6 * D0734 - C2 * D1625);
- blk[7][j] = 0.5 * (C7 * D07 - C5 * D16 + C3 * D25 - C1 * D34);
- }
- return blk;
- }
- }
- package com.zeph.watermark.fdct;
- public class IFDct implements Dct {
- public static double[][] iFDctTransform(double[][] ablk) {
- double[][] blk = new double[8][8];
- for (int i = 0; i < 8; i++) {
- for (int j = 0; j < 8; j++) {
- blk[i][j] = ablk[i][j];
- }
- }
- // 对列做IDCT
- for (int j = 0; j <= 7; j++) {
- double[] tmp = new double[16];
- // first step
- tmp[0] = blk[0][j] * C4 + blk[2][j] * C2;
- tmp[1] = blk[4][j] * C4 + blk[6][j] * C6;
- tmp[2] = blk[0][j] * C4 + blk[2][j] * C6;
- tmp[3] = -blk[4][j] * C4 - blk[6][j] * C2;
- tmp[4] = blk[0][j] * C4 - blk[2][j] * C6;
- tmp[5] = -blk[4][j] * C4 + blk[6][j] * C2;
- tmp[6] = blk[0][j] * C4 - blk[2][j] * C2;
- tmp[7] = blk[4][j] * C4 - blk[6][j] * C6;
- tmp[8] = blk[1][j] * C7 - blk[3][j] * C5;
- tmp[9] = blk[5][j] * C3 - blk[7][j] * C1;
- tmp[10] = blk[1][j] * C5 - blk[3][j] * C1;
- tmp[11] = blk[5][j] * C7 + blk[7][j] * C3;
- tmp[12] = blk[1][j] * C3 - blk[3][j] * C7;
- tmp[13] = -blk[5][j] * C1 - blk[7][j] * C5;
- tmp[14] = blk[1][j] * C1 + blk[3][j] * C3;
- tmp[15] = blk[5][j] * C5 + blk[7][j] * C7;
- // second step
- tmp[0] = 0.5 * (tmp[0] + tmp[1]);
- tmp[1] = 0.5 * (tmp[2] + tmp[3]);
- tmp[2] = 0.5 * (tmp[4] + tmp[5]);
- tmp[3] = 0.5 * (tmp[6] + tmp[7]);
- tmp[4] = 0.5 * (tmp[8] + tmp[9]);
- tmp[5] = 0.5 * (tmp[10] + tmp[11]);
- tmp[6] = 0.5 * (tmp[12] + tmp[13]);
- tmp[7] = 0.5 * (tmp[14] + tmp[15]);
- // third step
- blk[0][j] = tmp[0] + tmp[7];
- blk[1][j] = tmp[1] + tmp[6];
- blk[2][j] = tmp[2] + tmp[5];
- blk[3][j] = tmp[3] + tmp[4];
- blk[4][j] = tmp[3] - tmp[4];
- blk[5][j] = tmp[2] - tmp[5];
- blk[6][j] = tmp[1] - tmp[6];
- blk[7][j] = tmp[0] - tmp[7];
- }
- // 对行做IDCT
- for (int i = 0; i <= 7; i++) {
- double[] tmp = new double[16];
- // first step
- tmp[0] = blk[i][0] * C4 + blk[i][2] * C2;
- tmp[1] = blk[i][4] * C4 + blk[i][6] * C6;
- tmp[2] = blk[i][0] * C4 + blk[i][2] * C6;
- tmp[3] = -blk[i][4] * C4 - blk[i][6] * C2;
- tmp[4] = blk[i][0] * C4 - blk[i][2] * C6;
- tmp[5] = -blk[i][4] * C4 + blk[i][6] * C2;
- tmp[6] = blk[i][0] * C4 - blk[i][2] * C2;
- tmp[7] = blk[i][4] * C4 - blk[i][6] * C6;
- tmp[8] = blk[i][1] * C7 - blk[i][3] * C5;
- tmp[9] = blk[i][5] * C3 - blk[i][7] * C1;
- tmp[10] = blk[i][1] * C5 - blk[i][3] * C1;
- tmp[11] = blk[i][5] * C7 + blk[i][7] * C3;
- tmp[12] = blk[i][1] * C3 - blk[i][3] * C7;
- tmp[13] = -blk[i][5] * C1 - blk[i][7] * C5;
- tmp[14] = blk[i][1] * C1 + blk[i][3] * C3;
- tmp[15] = blk[i][5] * C5 + blk[i][7] * C7;
- // second step
- tmp[0] = 0.5 * (tmp[0] + tmp[1]);
- tmp[1] = 0.5 * (tmp[2] + tmp[3]);
- tmp[2] = 0.5 * (tmp[4] + tmp[5]);
- tmp[3] = 0.5 * (tmp[6] + tmp[7]);
- tmp[4] = 0.5 * (tmp[8] + tmp[9]);
- tmp[5] = 0.5 * (tmp[10] + tmp[11]);
- tmp[6] = 0.5 * (tmp[12] + tmp[13]);
- tmp[7] = 0.5 * (tmp[14] + tmp[15]);
- // third step
- blk[i][0] = tmp[0] + tmp[7];
- blk[i][1] = tmp[1] + tmp[6];
- blk[i][2] = tmp[2] + tmp[5];
- blk[i][3] = tmp[3] + tmp[4];
- blk[i][4] = tmp[3] - tmp[4];
- blk[i][5] = tmp[2] - tmp[5];
- blk[i][6] = tmp[1] - tmp[6];
- blk[i][7] = tmp[0] - tmp[7];
- }
- return blk;
- }
- }
- package com.zeph.watermark.fdct;
- public class IFDct implements Dct {
- public static double[][] iFDctTransform(double[][] ablk) {
- double[][] blk = new double[8][8];
- for (int i = 0; i < 8; i++) {
- for (int j = 0; j < 8; j++) {
- blk[i][j] = ablk[i][j];
- }
- }
- // 对列做IDCT
- for (int j = 0; j <= 7; j++) {
- double[] tmp = new double[16];
- // first step
- tmp[0] = blk[0][j] * C4 + blk[2][j] * C2;
- tmp[1] = blk[4][j] * C4 + blk[6][j] * C6;
- tmp[2] = blk[0][j] * C4 + blk[2][j] * C6;
- tmp[3] = -blk[4][j] * C4 - blk[6][j] * C2;
- tmp[4] = blk[0][j] * C4 - blk[2][j] * C6;
- tmp[5] = -blk[4][j] * C4 + blk[6][j] * C2;
- tmp[6] = blk[0][j] * C4 - blk[2][j] * C2;
- tmp[7] = blk[4][j] * C4 - blk[6][j] * C6;
- tmp[8] = blk[1][j] * C7 - blk[3][j] * C5;
- tmp[9] = blk[5][j] * C3 - blk[7][j] * C1;
- tmp[10] = blk[1][j] * C5 - blk[3][j] * C1;
- tmp[11] = blk[5][j] * C7 + blk[7][j] * C3;
- tmp[12] = blk[1][j] * C3 - blk[3][j] * C7;
- tmp[13] = -blk[5][j] * C1 - blk[7][j] * C5;
- tmp[14] = blk[1][j] * C1 + blk[3][j] * C3;
- tmp[15] = blk[5][j] * C5 + blk[7][j] * C7;
- // second step
- tmp[0] = 0.5 * (tmp[0] + tmp[1]);
- tmp[1] = 0.5 * (tmp[2] + tmp[3]);
- tmp[2] = 0.5 * (tmp[4] + tmp[5]);
- tmp[3] = 0.5 * (tmp[6] + tmp[7]);
- tmp[4] = 0.5 * (tmp[8] + tmp[9]);
- tmp[5] = 0.5 * (tmp[10] + tmp[11]);
- tmp[6] = 0.5 * (tmp[12] + tmp[13]);
- tmp[7] = 0.5 * (tmp[14] + tmp[15]);
- // third step
- blk[0][j] = tmp[0] + tmp[7];
- blk[1][j] = tmp[1] + tmp[6];
- blk[2][j] = tmp[2] + tmp[5];
- blk[3][j] = tmp[3] + tmp[4];
- blk[4][j] = tmp[3] - tmp[4];
- blk[5][j] = tmp[2] - tmp[5];
- blk[6][j] = tmp[1] - tmp[6];
- blk[7][j] = tmp[0] - tmp[7];
- }
- // 对行做IDCT
- for (int i = 0; i <= 7; i++) {
- double[] tmp = new double[16];
- // first step
- tmp[0] = blk[i][0] * C4 + blk[i][2] * C2;
- tmp[1] = blk[i][4] * C4 + blk[i][6] * C6;
- tmp[2] = blk[i][0] * C4 + blk[i][2] * C6;
- tmp[3] = -blk[i][4] * C4 - blk[i][6] * C2;
- tmp[4] = blk[i][0] * C4 - blk[i][2] * C6;
- tmp[5] = -blk[i][4] * C4 + blk[i][6] * C2;
- tmp[6] = blk[i][0] * C4 - blk[i][2] * C2;
- tmp[7] = blk[i][4] * C4 - blk[i][6] * C6;
- tmp[8] = blk[i][1] * C7 - blk[i][3] * C5;
- tmp[9] = blk[i][5] * C3 - blk[i][7] * C1;
- tmp[10] = blk[i][1] * C5 - blk[i][3] * C1;
- tmp[11] = blk[i][5] * C7 + blk[i][7] * C3;
- tmp[12] = blk[i][1] * C3 - blk[i][3] * C7;
- tmp[13] = -blk[i][5] * C1 - blk[i][7] * C5;
- tmp[14] = blk[i][1] * C1 + blk[i][3] * C3;
- tmp[15] = blk[i][5] * C5 + blk[i][7] * C7;
- // second step
- tmp[0] = 0.5 * (tmp[0] + tmp[1]);
- tmp[1] = 0.5 * (tmp[2] + tmp[3]);
- tmp[2] = 0.5 * (tmp[4] + tmp[5]);
- tmp[3] = 0.5 * (tmp[6] + tmp[7]);
- tmp[4] = 0.5 * (tmp[8] + tmp[9]);
- tmp[5] = 0.5 * (tmp[10] + tmp[11]);
- tmp[6] = 0.5 * (tmp[12] + tmp[13]);
- tmp[7] = 0.5 * (tmp[14] + tmp[15]);
- // third step
- blk[i][0] = tmp[0] + tmp[7];
- blk[i][1] = tmp[1] + tmp[6];
- blk[i][2] = tmp[2] + tmp[5];
- blk[i][3] = tmp[3] + tmp[4];
- blk[i][4] = tmp[3] - tmp[4];
- blk[i][5] = tmp[2] - tmp[5];
- blk[i][6] = tmp[1] - tmp[6];
- blk[i][7] = tmp[0] - tmp[7];
- }
- return blk;
- }
- }
- package com.zeph.watermark.fdct;
- import java.awt.image.BufferedImage;
- import java.awt.image.WritableRaster;
- import com.zeph.watermark.util.ImageUtil;
- import com.zeph.watermark.util.MathTool;
- public class AddWatermark {
- private static final int d = 5;
- public static void main(String[] args) {
- AddWatermark embed = new AddWatermark();
- embed.start();
- }
- public void start() {
- BufferedImage oImage = ImageUtil.getImage("D://lena.jpg");
- BufferedImage wImage = ImageUtil.getImage("D://zhong.bmp");
- int type = oImage.getType();
- WritableRaster oRaster = oImage.getRaster();
- WritableRaster wRaster = wImage.getRaster();
- int oWidth = oRaster.getWidth();
- int oHeight = oRaster.getHeight();
- int wWidth = wRaster.getWidth();
- int wHeight = wRaster.getHeight();
- int[] oPixels = new int[3 * oWidth * oHeight];
- int[] wPixels = new int[wWidth * wHeight];
- oRaster.getPixels(0, 0, oWidth, oHeight, oPixels);
- wRaster.getPixels(0, 0, wWidth, wHeight, wPixels);
- int[][][] RGBPixels = ImageUtil.getRGBArrayToMatrix(oPixels, oWidth,
- oHeight);
- // 得到RGB图像的三层矩阵表示
- double[][] rPixels = MathTool.intToDoubleMatrix(RGBPixels[2]);
- int[][] wDMatrix = ImageUtil.arrayToMatrix(wPixels, wWidth, wHeight);
- double[][] result = rPixels;
- // 嵌入算法
- for (int i = 0; i < wWidth; i++) {
- for (int j = 0; j < wHeight; j++) {
- double[][] blk = new double[8][8];
- // 对原始图像8 * 8 分块
- for (int m = 0; m < 8; m++) {
- for (int n = 0; n < 8; n++) {
- blk[m][n] = rPixels[8 * i + m][8 * j + n];
- }
- }
- double[][] dBlk = FDct.fDctTransform(blk);
- if (wDMatrix[i][j] == 0) {
- dBlk[3][3] = dBlk[3][3] - d;
- dBlk[3][4] = dBlk[3][4] - d;
- dBlk[3][5] = dBlk[3][5] - d;
- dBlk[4][3] = dBlk[4][3] - d;
- dBlk[5][3] = dBlk[5][3] - d;
- } else {
- dBlk[3][3] = dBlk[3][3] + d;
- dBlk[3][4] = dBlk[3][4] + d;
- dBlk[3][5] = dBlk[3][5] + d;
- dBlk[4][3] = dBlk[4][3] + d;
- dBlk[5][3] = dBlk[5][3] + d;
- }
- blk = IFDct.iFDctTransform(dBlk);
- for (int m = 0; m < 8; m++) {
- for (int n = 0; n < 8; n++) {
- result[8 * i + m][8 * j + n] = blk[m][n];
- }
- }
- }
- }
- double[][][] temp = new double[3][oWidth][oHeight];
- temp[0] = MathTool.intToDoubleMatrix(RGBPixels[0]);
- temp[1] = MathTool.intToDoubleMatrix(RGBPixels[1]);
- temp[2] = result;
- double[] rgbResult = ImageUtil.getRGBMatrixToArray(temp);
- // 将BufferedImage对象写入磁盘
- ImageUtil.setImage(rgbResult, oWidth, oHeight, "D://result.bmp",
- "bmp", type);
- }
- }
- package com.zeph.watermark.fdct;
- import java.awt.image.BufferedImage;
- import java.awt.image.WritableRaster;
- import com.zeph.watermark.util.ImageUtil;
- import com.zeph.watermark.util.MathTool;
- public class AddWatermark {
- private static final int d = 5;
- public static void main(String[] args) {
- AddWatermark embed = new AddWatermark();
- embed.start();
- }
- public void start() {
- BufferedImage oImage = ImageUtil.getImage("D://lena.jpg");
- BufferedImage wImage = ImageUtil.getImage("D://zhong.bmp");
- int type = oImage.getType();
- WritableRaster oRaster = oImage.getRaster();
- WritableRaster wRaster = wImage.getRaster();
- int oWidth = oRaster.getWidth();
- int oHeight = oRaster.getHeight();
- int wWidth = wRaster.getWidth();
- int wHeight = wRaster.getHeight();
- int[] oPixels = new int[3 * oWidth * oHeight];
- int[] wPixels = new int[wWidth * wHeight];
- oRaster.getPixels(0, 0, oWidth, oHeight, oPixels);
- wRaster.getPixels(0, 0, wWidth, wHeight, wPixels);
- int[][][] RGBPixels = ImageUtil.getRGBArrayToMatrix(oPixels, oWidth,
- oHeight);
- // 得到RGB图像的三层矩阵表示
- double[][] rPixels = MathTool.intToDoubleMatrix(RGBPixels[2]);
- int[][] wDMatrix = ImageUtil.arrayToMatrix(wPixels, wWidth, wHeight);
- double[][] result = rPixels;
- // 嵌入算法
- for (int i = 0; i < wWidth; i++) {
- for (int j = 0; j < wHeight; j++) {
- double[][] blk = new double[8][8];
- // 对原始图像8 * 8 分块
- for (int m = 0; m < 8; m++) {
- for (int n = 0; n < 8; n++) {
- blk[m][n] = rPixels[8 * i + m][8 * j + n];
- }
- }
- double[][] dBlk = FDct.fDctTransform(blk);
- if (wDMatrix[i][j] == 0) {
- dBlk[3][3] = dBlk[3][3] - d;
- dBlk[3][4] = dBlk[3][4] - d;
- dBlk[3][5] = dBlk[3][5] - d;
- dBlk[4][3] = dBlk[4][3] - d;
- dBlk[5][3] = dBlk[5][3] - d;
- } else {
- dBlk[3][3] = dBlk[3][3] + d;
- dBlk[3][4] = dBlk[3][4] + d;
- dBlk[3][5] = dBlk[3][5] + d;
- dBlk[4][3] = dBlk[4][3] + d;
- dBlk[5][3] = dBlk[5][3] + d;
- }
- blk = IFDct.iFDctTransform(dBlk);
- for (int m = 0; m < 8; m++) {
- for (int n = 0; n < 8; n++) {
- result[8 * i + m][8 * j + n] = blk[m][n];
- }
- }
- }
- }
- double[][][] temp = new double[3][oWidth][oHeight];
- temp[0] = MathTool.intToDoubleMatrix(RGBPixels[0]);
- temp[1] = MathTool.intToDoubleMatrix(RGBPixels[1]);
- temp[2] = result;
- double[] rgbResult = ImageUtil.getRGBMatrixToArray(temp);
- // 将BufferedImage对象写入磁盘
- ImageUtil.setImage(rgbResult, oWidth, oHeight, "D://result.bmp",
- "bmp", type);
- }
- }
- package com.zeph.watermark.fdct;
- import java.awt.image.BufferedImage;
- import java.awt.image.WritableRaster;
- import com.zeph.watermark.util.ImageUtil;
- import com.zeph.watermark.util.MathTool;
- public class ExtractWatermark {
- public static void main(String[] args) {
- ExtractWatermark distill = new ExtractWatermark();
- distill.start(32, 32);
- }
- public void start(int wWidth, int wHeight) {
- // mImage是嵌入水印后的图像
- BufferedImage mImage = ImageUtil.getImage("D://result.bmp");
- // 原始图像
- BufferedImage oImage = ImageUtil.getImage("D://lena.jpg");
- WritableRaster oRaster = oImage.getRaster();
- WritableRaster mRaster = mImage.getRaster();
- int oWidth = oRaster.getWidth();
- int oHeight = oRaster.getHeight();
- int[] oPixels = new int[3 * oWidth * oHeight];
- int[] mPixels = new int[3 * oWidth * oHeight];
- oRaster.getPixels(0, 0, oWidth, oHeight, oPixels);
- mRaster.getPixels(0, 0, oWidth, oHeight, mPixels);
- // 得rgb图像三层矩阵,mRgbPixels[0]表示b层分量
- int[][][] mRgbPixels = ImageUtil.getRGBArrayToMatrix(mPixels, oWidth,
- oHeight);
- int[][][] oRgbPixels = ImageUtil.getRGBArrayToMatrix(oPixels, oWidth,
- oHeight);
- double[][] oDPixels = MathTool.intToDoubleMatrix(mRgbPixels[2]);
- double[][] mDPixels = MathTool.intToDoubleMatrix(oRgbPixels[2]);
- double[][] result = new double[wWidth][wHeight];
- for (int i = 0; i < wWidth; i++) {
- for (int j = 0; j < wHeight; j++) {
- double[][] oBlk = new double[8][8];
- double[][] mBlk = new double[8][8];
- int d = 0;
- int f = 0;
- for (int m = 0; m < 8; m++) {
- for (int n = 0; n < 8; n++) {
- oBlk[m][n] = oDPixels[8 * i + m][8 * j + n];
- mBlk[m][n] = mDPixels[8 * i + m][8 * j + n];
- }
- }
- double[][] dOBlk = FDct.fDctTransform(oBlk);
- double[][] dMBlk = FDct.fDctTransform(mBlk);
- if (dOBlk[3][3] > dMBlk[3][3]) {
- d++;
- } else {
- f++;
- }
- if (dOBlk[3][4] > dMBlk[3][4]) {
- d++;
- } else {
- f++;
- }
- if (dOBlk[3][5] > dMBlk[3][5]) {
- d++;
- } else {
- f++;
- }
- if (dOBlk[4][3] > dMBlk[4][3]) {
- d++;
- } else {
- f++;
- }
- if (dOBlk[5][3] > dMBlk[5][3]) {
- d++;
- } else {
- f++;
- }
- if (d < f) {
- result[i][j] = 0;
- } else {
- result[i][j] = 1;
- }
- }
- }
- double[] outResult = ImageUtil.matrixToArray(result);
- // 把嵌入水印的结果写到BufferedImage对象
- ImageUtil.setImage(outResult, wWidth, wHeight, "D://mark.bmp", "bmp",
- BufferedImage.TYPE_BYTE_BINARY);
- }
- }
- package com.zeph.watermark.fdct;
- import java.awt.image.BufferedImage;
- import java.awt.image.WritableRaster;
- import com.zeph.watermark.util.ImageUtil;
- import com.zeph.watermark.util.MathTool;
- public class ExtractWatermark {
- public static void main(String[] args) {
- ExtractWatermark distill = new ExtractWatermark();
- distill.start(32, 32);
- }
- public void start(int wWidth, int wHeight) {
- // mImage是嵌入水印后的图像
- BufferedImage mImage = ImageUtil.getImage("D://result.bmp");
- // 原始图像
- BufferedImage oImage = ImageUtil.getImage("D://lena.jpg");
- WritableRaster oRaster = oImage.getRaster();
- WritableRaster mRaster = mImage.getRaster();
- int oWidth = oRaster.getWidth();
- int oHeight = oRaster.getHeight();
- int[] oPixels = new int[3 * oWidth * oHeight];
- int[] mPixels = new int[3 * oWidth * oHeight];
- oRaster.getPixels(0, 0, oWidth, oHeight, oPixels);
- mRaster.getPixels(0, 0, oWidth, oHeight, mPixels);
- // 得rgb图像三层矩阵,mRgbPixels[0]表示b层分量
- int[][][] mRgbPixels = ImageUtil.getRGBArrayToMatrix(mPixels, oWidth,
- oHeight);
- int[][][] oRgbPixels = ImageUtil.getRGBArrayToMatrix(oPixels, oWidth,
- oHeight);
- double[][] oDPixels = MathTool.intToDoubleMatrix(mRgbPixels[2]);
- double[][] mDPixels = MathTool.intToDoubleMatrix(oRgbPixels[2]);
- double[][] result = new double[wWidth][wHeight];
- for (int i = 0; i < wWidth; i++) {
- for (int j = 0; j < wHeight; j++) {
- double[][] oBlk = new double[8][8];
- double[][] mBlk = new double[8][8];
- int d = 0;
- int f = 0;
- for (int m = 0; m < 8; m++) {
- for (int n = 0; n < 8; n++) {
- oBlk[m][n] = oDPixels[8 * i + m][8 * j + n];
- mBlk[m][n] = mDPixels[8 * i + m][8 * j + n];
- }
- }
- double[][] dOBlk = FDct.fDctTransform(oBlk);
- double[][] dMBlk = FDct.fDctTransform(mBlk);
- if (dOBlk[3][3] > dMBlk[3][3]) {
- d++;
- } else {
- f++;
- }
- if (dOBlk[3][4] > dMBlk[3][4]) {
- d++;
- } else {
- f++;
- }
- if (dOBlk[3][5] > dMBlk[3][5]) {
- d++;
- } else {
- f++;
- }
- if (dOBlk[4][3] > dMBlk[4][3]) {
- d++;
- } else {
- f++;
- }
- if (dOBlk[5][3] > dMBlk[5][3]) {
- d++;
- } else {
- f++;
- }
- if (d < f) {
- result[i][j] = 0;
- } else {
- result[i][j] = 1;
- }
- }
- }
- double[] outResult = ImageUtil.matrixToArray(result);
- // 把嵌入水印的结果写到BufferedImage对象
- ImageUtil.setImage(outResult, wWidth, wHeight, "D://mark.bmp", "bmp",
- BufferedImage.TYPE_BYTE_BINARY);
- }
- }