Hello wendykierp, thanks for you brilliant work! But I have came across some nasty problems, can you give me some advice?
it seems that after all jobs has been done, sometime the jtransforms fails to end..
I have to manually stop the program most of time.
why is this happening?
Does it have something about the multi-threading?
or the size of input images matters?
then never ends.
here is the attached code..
import org.jtransforms.fft.DoubleFFT_2D;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;
import static java.lang.Math.min;
import static java.lang.Math.rint;
/**
* Project: blindwatermark
* Created by longx on 2016/11/3.
*/
public class Parser {
private static int[] hmap,wmap;
private static double alpha=10;
private static int defaultSeed=666666;
private final boolean DEBUG=false;
public static double[][][] getImageRGB(String filename)throws Exception{
BufferedImage im= ImageIO.read(new File(filename));
int[] image;
int h=im.getHeight(), w=im.getWidth(), type=im.getType(),cnt=0,tmp;
image=im.getRGB(0,0,w,h,null,0,w);
double[][][] ret=new double[3][h][2*w];
for(int i=0;i<h;i++)
for(int j=0;j<w;j++){
tmp=image[cnt++];
ret[0][i][2*j]=(tmp&0xFF); //B
ret[1][i][2*j]=((tmp&0xFF00)>>8); //G
ret[2][i][2*j]=((tmp&0xFF0000)>>16); //R
}
return ret;
}
public static void setImageRGB(double[][][] im, String filename)throws Exception{
File file=new File(filename);
if(!file.exists()) file.createNewFile();
int h=im[0].length,w=im[0][0].length/2,cnt=0,r,g,b;
BufferedImage bim =new BufferedImage(w,h,BufferedImage.TYPE_INT_RGB);
int[] out=new int[h*w];
for(int i=0;i<h;i++)
for(int j=0;j<w;j++){
b=min(new Double(rint(im[0][i][2*j])).intValue(),255);
g=min(new Double(rint(im[1][i][2*j])).intValue(),255);
r=min(new Double(rint(im[2][i][2*j])).intValue(),255);
out[cnt++]=(r<<16)|(g<<8)|(b);
}
bim.setRGB(0,0,w,h,out,0,w);
ImageIO.write(bim,"PNG",file);
}
public static void setAlpha(double x){
if(x<=0)System.out.println("Set Fail: The alpha must be positive");
else if(x>=100)System.out.println("Set Fail: The alpha must be smaller than 100");
else{
System.out.println("Set Success!");
alpha=x;
}
}
public static void setDefaultSeed(int s){
System.out.println("Set Success!");
defaultSeed=s;
}
private static int[] setMap(int seed,int len){
int[] save=new int[len];
ArrayList<Integer> sh=new ArrayList<>();
for(int i=0;i<len;i++)sh.add(i);
Collections.shuffle(sh,new Random(seed));
for(int i=0;i<len;i++)save[i]=sh.get(i);
return save;
}
private static double[][][] encode(double[][][] input,int h,int w,int seed){
hmap=setMap(seed,h/2);wmap=setMap(seed+1,w/2);
double[][][] ret=new double[input.length][h][w];
for(int ch=0;ch<input.length;ch++){
for(int i=0;i<input[0].length;i++)
for(int j=0;j<input[0][0].length/2;j++)
ret[ch][hmap[i]][2*wmap[j]]=input[ch][i][2*j];
for(int i=0;i<h/2;i++)
for(int j=0;j<w/2;j++)
ret[ch][h-1-i][w-2*(j+1)]=ret[ch][i][2*j];
}
return ret;
}
private static double[][][] decode(double[][][] input,int h,int w,int seed){
hmap=setMap(seed,h/2);wmap=setMap(seed+1,w/2);
double[][][] wm=new double[3][h][w];
for(int ch=0;ch<3;ch++){
for(int j=0;j<h/2;j++)
for(int k=0;k<w/2;k++)
wm[ch][j][2*k]=input[ch][hmap[j]][2*wmap[k]];
for(int j=0;j<h/2;j++)
for(int k=0;k<w;k+=2)
wm[ch][h-1-j][w-2-k]=wm[ch][j][k];
}
return wm;
}
private static void cpxfft(double[][] input){
DoubleFFT_2D f2d=new DoubleFFT_2D(input.length,input[0].length/2);
f2d.complexForward(input);
}
private static void cpxifft(double[][] input){
DoubleFFT_2D f2d=new DoubleFFT_2D(input.length,input[0].length/2);
f2d.complexInverse(input,true);
}
public static void encrypt(String fn1,String fn2,String output)throws Exception{
double[][][] im=getImageRGB(fn1);
double[][][] wm=getImageRGB(fn2);
assert(im[0].length>2*wm[0].length&&im[0][0].length>=wm[0][0].length);
double[][][] rwm=encode(wm,im[0].length,im[0][0].length,defaultSeed);
for(int i=0;i<im.length;i++){
cpxfft(im[i]);
for(int j=0;j<im[0].length;j++)
for(int k=0;k<im[0][0].length;k++)
im[i][j][k]+=rwm[i][j][k]*alpha;
cpxifft(im[i]);
}
setImageRGB(im,output);
System.out.println("Encrypt Completed!");
}
public static void decrypt(String fn1,String fn2,String output)throws Exception{
double[][][] im=getImageRGB(fn1);
double[][][] src=getImageRGB(fn2);
assert( src.length==im.length&&
src[0].length==im[0].length&&
src[0][0].length==im[0][0].length);
int ch=src.length,h=src[0].length,w=src[0][0].length;
double[][][] dwm=new `double[ch][h][w];`
for(int i=0;i<ch;i++){
cpxfft(src[i]);
cpxfft(im[i]);
for(int j=0;j<h;j++)
for(int k=0;k<w;k+=2)
dwm[i][j][k]=(im[i][j][k]-src[i][j][k])/alpha;
}
double[][][] wm=decode(dwm,h,w,defaultSeed);
setImageRGB(wm,output);
System.out.println("Decrypt Completed!");
}
}`
public class Check {
static final boolean showDiff=true;
public static void main(String[] args)throws Exception{
Parser.encrypt("res//Kato_Megumi.jpg","res//wm2.bmp","TestOutput.jpg");
Parser.decrypt("res//Kato_Megumi.jpg","TestOutput.jpg","decoded.png");
if(showDiff){
double[][][] src=Parser.getImageRGB("res//Kato_Megumi.jpg");
double[][][] cdx=Parser.getImageRGB("TestOutput.jpg");
double[][][] diff=new double[src.length][src[0].length][src[0][0].length];
for(int i=0;i<src.length;i++)
for(int j=0;j<src[0].length;j++)
for(int k=0;k<src[0][0].length;k+=2)
diff[i][j][k]=cdx[i][j][k]-src[i][j][k];
Parser.setImageRGB(diff,"diff.jpg");
}
}
}
Thank you very much.