图像加密
Image Encryption
我正在做图像隐写术,如果我输入大于 3 个字符的消息进行加密,则有一个例外,即量化 table 0x01 未定义并且消息小于 3 个字符,我得到了一个加密图像作为我需要。我认为这是由于 JPEG 格式(我认为在图像字节数组中注入位时我破坏了图像的 属性 和属性)。帮帮我,我确定它与元数据有关,但不要`了解的不多。
我正在添加我正在做的代码
Creating_image()
{
File f=new File(file.getParent()+"/encrypt.jpg");
if(file==null)
{
JOptionPane.showMessageDialog(rootPane, "file null ho gyi encrypt mein");
}
try{
FileInputStream imageInFile = new FileInputStream(file);
byte imageData[] = new byte[(int) file.length()];
imageInFile.read(imageData);
// Converting Image byte array into Base64 String
String imageDataString = Base64.encode(imageData);
// Converting a Base64 String into Image byte array
pixels = Base64.decode(imageDataString);
// Write a image byte array into file system
imageInFile.close();
}
catch(Exception as)
{
JOptionPane.showMessageDialog(rootPane,"Please first select an Image");
}
String msg=jTextArea1.getText();
byte[] bmsg=msg.getBytes();
String as=Base64.encode(bmsg);
bmsg=Base64.decode(as);
int len=msg.length();
byte[] blen=inttobyte(len);
String sd=Base64.encode(blen);
blen=Base64.decode(sd);
pixels=encode(pixels,blen,32);
pixels=encode(pixels,bmsg,64);
try{
// Converting Image byte array into Base64 String
String imageDataString = Base64.encode(pixels);
// Converting a Base64 String into Image byte array
pixels = Base64.decode(imageDataString);
InputStream baisData = new ByteArrayInputStream(pixels,0,pixels.length);
image= ImageIO.read(baisData);
if(image == null)
{
System.out.println("imag is empty");
}
ImageIO.write(image, "jpg", f);
}
catch(Exception s)
{
System.out.println(s.getMessage());
}
}
这就是 encode fxn 的样子
byte[] encode(byte [] old,byte[] add,int offset)
{
try{ if(add.length+offset>old.length)
{
JOptionPane.showMessageDialog(rootPane, "File too short");
}
}
catch(Exception d)
{
JOptionPane.showMessageDialog(rootPane, d.getLocalizedMessage());
}
byte no;
for(int i=0;i<add.length;i++)
{
no=add[i];
for(int bit=7;bit>=0;bit--,++offset)
{
int b=(no>>bit)&1;
old[offset]=(byte)((old[offset]&0xfe)|b);
}
}
return old;
}
你是对的,你打乱了文件结构。 JPEG 格式包含高度压缩的数据,其字节的 none 点直接表示任何像素值。事实上,JPEG甚至不存储像素值,而是存储像素块的DCT系数。
您读取文件原始字节的方法仅适用于像 BMP 这样的格式,其中像素直接存储在文件中。但是,您仍然必须跳过前几个字节 (header),其中包含图像的宽度和高度、颜色平面数和每像素位数等信息。
如果您想通过修改像素的最低有效位来嵌入消息,则必须 load the actual pixels in a byte array. Then you can modify the pixels with your encode()
method. To save the data to a file, convert the byte array to a BuffferedImage object 并使用 ImageIO.write()
。但是,您必须使用不涉及有损压缩的格式,因为这会扭曲像素值,从而破坏您的消息。无损压缩(或未压缩)文件格式包括 BMP 和 PNG,而 JPEG 是有损的。
如果您仍想进行 JPEG 隐写术,这个过程会涉及更多,但 this answer 几乎涵盖了您需要做的一切。简而言之,您想借用 jpeg 编码器的源代码,因为编写一个非常复杂并且需要对整个格式有复杂的理解。编码器会将像素转换为一堆不同的数字(有损步骤)并将它们紧凑地存储到一个文件中。然后应该在这两个步骤之间注入您的隐写术算法,您可以在将它们保存到文件之前修改这些数字。
我正在做图像隐写术,如果我输入大于 3 个字符的消息进行加密,则有一个例外,即量化 table 0x01 未定义并且消息小于 3 个字符,我得到了一个加密图像作为我需要。我认为这是由于 JPEG 格式(我认为在图像字节数组中注入位时我破坏了图像的 属性 和属性)。帮帮我,我确定它与元数据有关,但不要`了解的不多。
我正在添加我正在做的代码
Creating_image()
{
File f=new File(file.getParent()+"/encrypt.jpg");
if(file==null)
{
JOptionPane.showMessageDialog(rootPane, "file null ho gyi encrypt mein");
}
try{
FileInputStream imageInFile = new FileInputStream(file);
byte imageData[] = new byte[(int) file.length()];
imageInFile.read(imageData);
// Converting Image byte array into Base64 String
String imageDataString = Base64.encode(imageData);
// Converting a Base64 String into Image byte array
pixels = Base64.decode(imageDataString);
// Write a image byte array into file system
imageInFile.close();
}
catch(Exception as)
{
JOptionPane.showMessageDialog(rootPane,"Please first select an Image");
}
String msg=jTextArea1.getText();
byte[] bmsg=msg.getBytes();
String as=Base64.encode(bmsg);
bmsg=Base64.decode(as);
int len=msg.length();
byte[] blen=inttobyte(len);
String sd=Base64.encode(blen);
blen=Base64.decode(sd);
pixels=encode(pixels,blen,32);
pixels=encode(pixels,bmsg,64);
try{
// Converting Image byte array into Base64 String
String imageDataString = Base64.encode(pixels);
// Converting a Base64 String into Image byte array
pixels = Base64.decode(imageDataString);
InputStream baisData = new ByteArrayInputStream(pixels,0,pixels.length);
image= ImageIO.read(baisData);
if(image == null)
{
System.out.println("imag is empty");
}
ImageIO.write(image, "jpg", f);
}
catch(Exception s)
{
System.out.println(s.getMessage());
}
}
这就是 encode fxn 的样子
byte[] encode(byte [] old,byte[] add,int offset)
{
try{ if(add.length+offset>old.length)
{
JOptionPane.showMessageDialog(rootPane, "File too short");
}
}
catch(Exception d)
{
JOptionPane.showMessageDialog(rootPane, d.getLocalizedMessage());
}
byte no;
for(int i=0;i<add.length;i++)
{
no=add[i];
for(int bit=7;bit>=0;bit--,++offset)
{
int b=(no>>bit)&1;
old[offset]=(byte)((old[offset]&0xfe)|b);
}
}
return old;
}
你是对的,你打乱了文件结构。 JPEG 格式包含高度压缩的数据,其字节的 none 点直接表示任何像素值。事实上,JPEG甚至不存储像素值,而是存储像素块的DCT系数。
您读取文件原始字节的方法仅适用于像 BMP 这样的格式,其中像素直接存储在文件中。但是,您仍然必须跳过前几个字节 (header),其中包含图像的宽度和高度、颜色平面数和每像素位数等信息。
如果您想通过修改像素的最低有效位来嵌入消息,则必须 load the actual pixels in a byte array. Then you can modify the pixels with your encode()
method. To save the data to a file, convert the byte array to a BuffferedImage object 并使用 ImageIO.write()
。但是,您必须使用不涉及有损压缩的格式,因为这会扭曲像素值,从而破坏您的消息。无损压缩(或未压缩)文件格式包括 BMP 和 PNG,而 JPEG 是有损的。
如果您仍想进行 JPEG 隐写术,这个过程会涉及更多,但 this answer 几乎涵盖了您需要做的一切。简而言之,您想借用 jpeg 编码器的源代码,因为编写一个非常复杂并且需要对整个格式有复杂的理解。编码器会将像素转换为一堆不同的数字(有损步骤)并将它们紧凑地存储到一个文件中。然后应该在这两个步骤之间注入您的隐写术算法,您可以在将它们保存到文件之前修改这些数字。