图像读写java.lang.IllegalArgumentException
我想创建一个非常简单的加密/解密项目。但首先,我想读取jpg文件并使用给定密码将其写入文件,然后再次读取该文件并检查文件中的密码和提供的密码,但我得到:图像读写java.lang.IllegalArgumentException,java,file-io,javax.imageio,Java,File Io,Javax.imageio,我想创建一个非常简单的加密/解密项目。但首先,我想读取jpg文件并使用给定密码将其写入文件,然后再次读取该文件并检查文件中的密码和提供的密码,但我得到: Exception in thread "main" java.lang.IllegalArgumentException: im == null! at javax.imageio.ImageIO.write(Unknown Source) at javax.imageio.ImageIO.write(Unknown Sour
Exception in thread "main" java.lang.IllegalArgumentException: im == null!
at javax.imageio.ImageIO.write(Unknown Source)
at javax.imageio.ImageIO.write(Unknown Source)
at GSM.AES.deccryption(AES.java:105)
at GSM.AES.main(AES.java:27)
我的代码:
public static void main(String args[])
{
myWrite();
String encryptedFilePath = System.getProperty("user.dir")+ "\\"+"Encrypted"+".mmlooloo";
String destinationFilePath = System.getProperty("user.dir") + "\\";
try {
myRead(encryptedFilePath,destinationFilePath,"123456");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return;
}
我的加密:
public static void myWrite() {
try {
System.out.println("Plesase Enter Number Of Pages !!!!!");
BufferedReader bufferRead = new BufferedReader(new InputStreamReader(System.in));
int numberOfPage = Integer.valueOf(bufferRead.readLine().toString());
String dirName= System.getProperty("user.dir")+"\\";
byte[] base64StringEnc;
ByteArrayOutputStream baos=new ByteArrayOutputStream(1000);
FileOutputStream myMatLabFileEnc = null;
String filePath = System.getProperty("user.dir")+ "\\"+"Encrypted"+".mmlooloo";
myMatLabFileEnc = new FileOutputStream (filePath);
String imagFileName;
String imgPathString;
String password = "123456";
myMatLabFileEnc.write(password.getBytes());
myMatLabFileEnc.write("\n".getBytes());
for(int i = 1 ; i<=numberOfPage ;i++)
{
imagFileName = Integer.toString(i) +".jpg";
BufferedImage img=ImageIO.read(new File(dirName,imagFileName));
ImageIO.write(img, "jpg", baos);
baos.flush();
myMatLabFileEnc.write(baos.toByteArray());
myMatLabFileEnc.write("\n".getBytes());
baos.reset();
imgPathString = dirName + imagFileName;
File f = new File(imgPathString);
f.delete();
}
myMatLabFileEnc.close();
baos.close();
return;
} catch (FileNotFoundException ex) {
System.out.println(ex.toString());
}catch(IOException ex){
System.out.println(ex.toString());
}
}
而AES.java:105是:
ImageIO.write(imagRecover, "jpg", new File(encryptedFileDir,outputRecoverdFileName));
我检查了ImageCover是否为空,但我不知道为什么?我想你可以试一下,只需将你的图像文件命名为1.jpg、2.jpg等等……免责声明:这不是完整的答案,但它太长,无法发表评论 这就是我所说的评论: 首先不要对图像进行解码/编码。只需复制字节 使用此代码,您将不会重新压缩JPEG,因此不会丢失质量 而不是以下代码:
imagFileName = Integer.toString(i) +".jpg";
BufferedImage img=ImageIO.read(new File(dirName,imagFileName));
ImageIO.write(img, "jpg", baos);
baos.flush();
只需将文件中的字节复制到baos,如下所示:
imagFileName = Integer.toString(i) +".jpg";
InputStream input = new FileInputStream(new File(dirName, imagFileName));
try {
copy(input, baos);
}
finally {
input.close();
}
复制方法:
public void copy(InputStream input, OutputStream output) throws IOException {
byte[] buffer = new byte[1024];
int len;
while ((len = input.read(buffer, 0, buffer.length)) >= 0) {
output.write(buffer, 0, len);
}
}
同样,在解密部分,替换:
byte[] bytearray = encryptedImag.getBytes();
BufferedImage imagRecover=ImageIO.read(new ByteArrayInputStream(bytearray));
String outputRecoverdFileName = Integer.toString(i)+"_recoverd.jpg";
ImageIO.write(imagRecover, "jpg", new File(encryptedFileDir,outputRecoverdFileName));
与:
你在写二进制数据。你不能保证在一个图像的二进制中没有一行的结尾。可能有很多的卡尔返回和结束线内的东西。。。您希望完全复制的每个线性图像都会使imageio.read失败并返回null,正如javadoc中针对该方法所述。我建议您在写入之前对每个图像进行base64编码,并使用printwriter将thw文件视为文本文件。否则,你应该尝试像thoae这样的WAD文件,保存每个文件的位置和长度。。。你读过关于java.util.zip的文章吗???@eduyayo谢谢,它很有效,但是为什么我会失去质量呢?例如,我的原始图像是551kB,但我的恢复是181KB。我使用Baase64编码-解码方法进行写入和读取。@mmlooloo当使用ImageIO.write时。。。您正在使用压缩/质量的默认参数。如果这些与您的输入文件已有的设置不匹配,您将得到一个更小/更大的文件。@haraldK谢谢您,如果您能告诉我该怎么做,我不会失去任何品质,我将接受您的回答。非常感谢您,现在我想我可以实现任何加密算法,对吗?!!!只要在解密后可以复制相同的字节,就可以继续使用了:-很好,特别是关于不使用字节[]的字符串。Java的特殊之处在于字符串是Unicode,能够将所有脚本组合在一个文本中。因此,在给定的编码中总是会转换为二进制数据,或者默认为操作系统的。这种转换不能在纯二进制数据上无损工作。
byte[] bytearray = encryptedImag.getBytes();
BufferedImage imagRecover=ImageIO.read(new ByteArrayInputStream(bytearray));
String outputRecoverdFileName = Integer.toString(i)+"_recoverd.jpg";
ImageIO.write(imagRecover, "jpg", new File(encryptedFileDir,outputRecoverdFileName));
byte[] bytearray = encryptedImag.getBytes();
InputStream input = new ByteArrayInputStream(bytearray));
String outputRecoverdFileName = Integer.toString(i) + "_recoverd.jpg";
OutputStream output = new FileOutputStream(new File(encryptedFileDir, outputRecoverdFileName)));
try {
copy(input, output);
}
finally {
output.close();
}