2014-09-04 68 views
-1

我想创建一个非常简单的加密/解密项目。但起初,我想读的JPG文件,并将其写入与给定的密码文件,然后再次读取该文件与文件和所提供的密码检查密码,但我得到:图像读写java.lang.IllegalArgumentException

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()); 
      } 
     } 

和我的解密:

public static int myRead(String encryptedfilePath,String encryptedFileDir,String inputPassword) throws FileNotFoundException, IOException{ 

      FileReader encryptedFile=new FileReader(encryptedfilePath); 
      BufferedReader reader = new BufferedReader(encryptedFile); 
      String encryptedImag; 
      String encryptedSavesdPassword = reader.readLine(); 
      byte []encryptedInputPassword = inputPassword.getBytes(); 
      byte []temp = encryptedSavesdPassword.getBytes(); 
      if(!Arrays.equals(temp,encryptedInputPassword)){ 
       return -1; 
      } 
      int i = 1; 

      while((encryptedImag = reader.readLine()) != null){ 

       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)); 
       ++i; 
      } 

      return 1; 

     } 

和AES.java:105是:

ImageIO.write(imagRecover, "jpg", new File(encryptedFileDir,outputRecoverdFileName)); 

我检查imagRecover为空,但我不知道为什么?我认为你可以尝试它只是命名您的图像文件,如1.jpg,2.jpg等...

+0

你写binnary数据。你不能保证图像的二元组没有结束。可能有很多carre返回和线内行结束......你期望的每个linea是完全conatructed图像使imageio.read失败并返回null,如javadoc中针对该方法所述。在写入之前,我要求你对base64进行编码,并将这个文件作为文本文件与printwriter对待。否则,你应该尝试一种类似thoae的WAD文件在good'ol厄运,节省每个文件的poaition和长度。 – eduyayo 2014-09-04 22:06:44

+0

Btw ...你有没有读过java.util.zip? – eduyayo 2014-09-04 22:07:17

+0

@eduyayo谢谢它的作品,但为什么我会失去质量?例如我的原始图像是551kB,但我的恢复是181KB。我用Baase64编码解码方法来写和读。 – mmlooloo 2014-09-05 02:36:37

回答

2

免责声明:这不是完整的答案,但它太长的评论。

这就是我的意思由注释:

不解码/图像中的第一位置进行编码。只需复制字节。

使用此代码,您不会重新压缩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)); 

有了:

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(); 
} 
+0

非常感谢你,现在我认为我可以实现任何加密算法来包装我是吗? – mmlooloo 2014-09-05 14:09:53

+0

只要你可以在解密后重现相同的字节,你应该很好。 :-) – haraldK 2014-09-05 14:12:53

+1

很好,特别是关于'byte []'不使用'String'。 Java的特殊之处在于,字符串是Unicode能够将文本中的所有脚本组合在一起的。因此,总是存在向二进制数据的转换(在给定的编码中,或者默认为操作系统)。该转换在纯二进制数据上无法正常工作。 – 2014-09-05 14:13:40