我想知道是否有人有任何想法我的LSB隐写应用程序出了什么问题。问题是我无法获得修改后的图像文件(隐藏在LSB中的秘密文本)来保存。我已经在一个小的测试程序中测试了算法,使用零字节数组(00000000)来隐藏一个小消息,它确实按照预期修改了LSB。我无法解决在尝试保存它时出现的问题,并且已经尝试了各种方法(FileOutPutStream,Image.io write),但这些方法似乎都无法正常工作。它成功保存,但每次生成一个空白图像文件(文件大小合适,但是,当打开时全黑,有些应用程序根本无法打开它 - 在我尝试过的所有保存方法上都这样做)。
该程序有一个缓冲图像/文本(缓冲区)的类,从缓冲的图像/文本(GetBytes)中提取字节数据并保存修改后的文件(SaveFile)。我已经包含了hide方法和算法以及SaveFile类,因为我认为这可能是问题所在。如果需要更多信息/代码,请告诉我。
以下是我的代码:
LSB隐藏方法和算法
public class LSB_oneBit implements LSB {
//Variables ending in R are for reveal method not yet implemented.
protected byte[] imageBytes;
protected byte[] textBytes;
protected BufferedImage image;
//protected byte[] imageBytesR;
//protected byte[] textBytesR;
protected int offset;
//protected int offsetR;
protected int messageLength;
protected SaveFile file;
protected GetBytes imageB;
protected GetBytes textB;
//protected GetBytes revealImageR;
protected String dirName;
protected String imageFileName;
//protected String imageFileNameR;
protected String textFileName;
//protected String messageR;
protected String saveFileName;
//protected String saveFileNameR;
//protected OutputStream out;
protected InputStream in;
public LSB_oneBit() throws IOException
{
}
@Override
public boolean hide(String imageFileName, String textFileName, String saveFileName, String dirName, int offset)throws IOException
{
this.imageFileName = imageFileName;
this.textFileName = textFileName;
imageB = new GetBytes();
imageBytes = imageB.getImageBytes(imageFileName);
textB = new GetBytes();
textBytes = textB.getTextBytes(textFileName);
for(byte x: textBytes)
{
System.out.println("Text bytes: " + Integer.toBinaryString(0x100 + x).substring(1));
}
this.saveFileName = saveFileName;
this.dirName = dirName;
this.offset = offset;
if(algorithm()!=false)
{
//All in one way of reading ByteArray.
in = new ByteArrayInputStream(imageBytes);
image = ImageIO.read(in);
System.out.println("Modified image buffered");
file = new SaveFile(saveFileName);
file.writeImage(image);
return true;
//Method for returning byte[] to SaveFile class instead of bufferedImage
/*InputStream in = new ByteArrayInputStream(imageBytes);
//BufferedImage modifiedImage = ImageIO.read(in);
System.out.println("Modified image buffered");
file = new SaveFile(saveFileName, modifiedImage, dirName);
file.writeImage();
return true;*/
//Method for writing to file straight from LSB_oneBit class using FileOutputStream
/*File myFile = new File(dirName,saveFileName);
System.out.println("Filename is: " + saveFileName);
try
{
out = new FileOutputStream(myFile);
}
catch (FileNotFoundException ex)
{
Logger.getLogger(LSB_oneBit.class.getName()).log(Level.SEVERE, null, ex);
}
try
{
out.write(imageBytes);
System.out.println("Image file written successfully");
return true;
}
catch(IOException e)
{
System.out.println("Cannot save file " + e.getMessage());
e.printStackTrace();
e.getMessage();
return false;
}
finally
{
out.close();
}*/
}
else
return false;
}
public boolean algorithm()
{
if(checkSize()!=false)
{
try
{
for (int i = 0; i<textBytes.length; i++)
{
int textByteValue = textBytes[i];
byte textByteValueB = (byte) textByteValue;
for(int x = 7; x>=0; x--)
{
int textBitValue = ((textByteValue>>>x)& 1);
byte textBitValueB = (byte)textBitValue;
imageBytes[offset] = (byte) ((imageBytes[offset]&0xFE) | textBitValueB);
offset++;
}
}
System.out.println("Image bytes modified");
return true;
}
catch (Exception e)
{
e.getMessage();
e.printStackTrace();
return false;
}
}
else
{
return false;
}
}
public boolean checkSize()
{
int imageSize = imageBytes.length;
System.out.println("Image size is: " + imageSize);
int textSize = textBytes.length;
System.out.println("Text size is: " + textSize);
if((textSize*8)<=imageSize)
{
System.out.println("Text can fit into the image");
return true;
}
return false;
}
}
保存文件类
public class SaveFile {
protected String saveFileName;
protected BufferedImage image;
protected BufferedWriter writer;
protected String dirName;
//Used for writing byte[] method
//protected byte[] imageBytes;
protected File file;
private BufferedImage bi;
protected Graphics graphics;
public SaveFile(String saveFileName /*String dirName*/ /*byte[] imageBytes*/ )
{
this.saveFileName = saveFileName;
//this.dirName = dirName;
//this.imageBytes = imageBytes;
}
public boolean writeImage(BufferedImage nImage)
{
this.image = nImage;
file = new File(saveFileName);
if (file.exists()== true)
{
String stringConfirm = JOptionPane.showInputDialog("File already exists, do you wish to overwrite? Y/N");
char confirm = stringConfirm.charAt(0);
if (confirm =='Y')
{
try
{
//Method for writing byte[] object
/*FileOutputStream output = new FileOutputStream(file);
output.write(imageBytes);
output.flush();
output.close();*/
//Method for writing BufferedImage object
bi = new BufferedImage(515,686, BufferedImage.TYPE_4BYTE_ABGR);
graphics = bi.getGraphics();
graphics.clearRect(0, 0, 515, 686);
graphics.drawImage(image, 0, 0, null);
graphics.dispose();
//file = new File(dirName);
ImageIO.write(bi, "png", file);
System.out.println("Image written to PNG file");
return true;
}
catch(IOException e)
{
System.out.println("Unable to write image to file" + e.getMessage());
return false;
}
}
else
return false;
}
else
{
try
{
bi = new BufferedImage(515,686, BufferedImage.TYPE_4BYTE_ABGR);
graphics = bi.getGraphics();
graphics.clearRect(0, 0, 515, 686);
graphics.drawImage(image, 0, 0, null);
graphics.dispose();
ImageIO.write(bi, "png", file);
/*FileOutputStream output = new FileOutputStream(file);
output.write(imageBytes);
output.flush();
output.close();
System.out.println("Image written to PNG file"); */
return true;
}
catch(IOException e)
{
System.out.println("Unable to write image to file" + e.getMessage());
return false;
}
}
}
public boolean writeText(String text)
{
writer = null;
try
{
writer = new BufferedWriter(new FileWriter(saveFileName));
writer.write(text);
return true;
}
catch(IOException e)
{
System.out.println("Cannot write to file");
e.getMessage();
e.printStackTrace();
return false;
}
finally
{
try
{
if(writer!=null)
writer.close();
}
catch(IOException e)
{
System.out.println("Cannot close writer");
e.getMessage();
e.printStackTrace();
}
}
}
}