2017-04-20 3 views
-2

서버에서 이미지 파일의 내용을 다운로드하려고하는 프로그램이 있습니다. 내가 그것을 다운로드하는 자바 소켓을 사용하고 있습니다. 다운로드가 끝나면 BitmapFactory.decodeByteArray()을 사용하여 비트 맵을 만듭니다.소켓에서 바이트를 가져 와서 비트 맵 생성을 사용하면 안드로이드 이미지가 나타나지 않습니다.

서버 측에서 파일은 .jpg 파일이며 약 180KBytes에 불과하므로 크기 조정을 시도 할 필요가 없습니다. 로그를 통해 파일의 정확한 바이트 수가 이미지 다운로드 코드로 수신되었음을 알 수 있습니다. 모든 바이트를 byte[] 배열에 저장하고 비트 맵으로 변환합니다.

처음에는 imageView이 숨겨져 있으며 이미지를 채운 후에 표시됩니다. 그러나 BitmapFactory.decodeByteArray()을 사용하면 항상 null을 반환합니다. null bitmap에 대한 다른 게시물을 보았지만 아무 것도이 문제에 대한 대답이없는 것 같습니다.

외부 라이브러리를 사용하고 싶지 않으므로 다른 라이브러리를 사용해 보지 마십시오. 누군가 코드에 어떤 문제라도 찾아 낼 수 있습니까? 서버 측 프로그램 또한 내 것이고, 브라우저를 사용하면 동일한 이미지 파일을 다운로드 할 수 있기 때문에 해당 부분이 정확하다는 것을 알고 있습니다. 아래에 복사하여 붙여 넣었습니다.

public class ImageDownloader { 
    private Socket    sockToSrvr; 
    private PrintWriter   strmToSrvr; 
    private BufferedInputStream strmFromSrvr; 
    private String    srvrAddr; 
    private int     port; 
    private String    remoteFile; 
    private Context    ctxt; 
    private Bitmap    imgBmap; 
    private View    parkSpotImgVwHldr; 
    private View    mngAndFndVwHldr; 
    private View    parkSpotImgVw; 

    public ImageDownloader(Context c) { 
     srvrAddr   = KloudSrvr.srvrIp(); 
     port    = KloudSrvr.port(); 
     sockToSrvr  = null; 
     strmFromSrvr  = null; 
     strmToSrvr  = null; 
     remoteFile  = null; 
     ctxt    = c; 
     imgBmap   = null; 
     parkSpotImgVwHldr = null; 
     mngAndFndVwHldr = null; 
     parkSpotImgVw  = null; 
    } 

    public void downloadFile(String remf, View parkSpotImgVwHldrVal, 
       View mngAndFndVwHldrVal, View parkSpotImgVwVal) { 
     remoteFile  = remf; 
     parkSpotImgVwHldr = parkSpotImgVwHldrVal; 
     mngAndFndVwHldr = mngAndFndVwHldrVal; 
     parkSpotImgVw  = parkSpotImgVwVal; 

     Thread dwnThrd = new Thread() { 
      @Override 
      public void run() { 
       imgBmap = null; 
       openServerConnection(); sendReq(); doDownload(); closeServerConnection(); 
       ((Activity)ctxt).runOnUiThread(new Runnable() { 
        public void run() { 
         ((Activity)ctxt).runOnUiThread(new Runnable() { 
          public void run() { 
           mngAndFndVwHldr.setVisibility(View.GONE); 
           parkSpotImgVwHldr.setVisibility(View.VISIBLE); 
           Toast.makeText(ctxt, "completed", Toast.LENGTH_LONG).show(); 
          } 
         }); 
        } 
       }); 
      } 
     }; 

     dwnThrd.start(); 
    } 

    private void sendReq() { 
     if(strmToSrvr == null) return; 
     String req = "GET /downloadFile " + remoteFile + " HTTP/1.1\r\n\r\n"; 
     Log.d("IMG-DWNL-LOG: ", "writing req msg to socket " + req); 
     strmToSrvr.write(req); strmToSrvr.flush(); 
    } 

    private void doDownload() { 
     boolean gotContLen = false; 
     int  contLen = 0; 
     while(true) { 
      String inLine = getLine(strmFromSrvr); if(inLine == null) break; 
      if((gotContLen == true) && 
       (inLine.replace("\r", "").replace("\n", "").isEmpty() == true)) break; 
      if(inLine.trim().startsWith("Content-Length:") == true) { 
       // an empty line after this signifies start of content 
       String s = inLine.replace("Content-Length:", "").trim(); 
       try {contLen = Integer.valueOf(s); gotContLen = true; continue;} 
       catch(NumberFormatException nfe) {contLen = 0;} 
      } 
     } 
     if((gotContLen == false) || (contLen <= 0)) return; 

     byte[] imgByts = new byte[contLen]; 
     int  totRdByts = 0, rdByts, chnk = 1024, avlByts; 
     while(true) { 
      try { 
       avlByts = strmFromSrvr.available(); if(avlByts < 0) break; 
       if(avlByts == 0) {try {Thread.sleep(1000);} catch(InterruptedException ie) {} continue;} 
       rdByts = (avlByts < chnk) ? avlByts : chnk; 
       rdByts = strmFromSrvr.read(imgByts, totRdByts, rdByts); if(rdByts < 0) break; 
       if(rdByts == 0) {try {Thread.sleep(1000);} catch(InterruptedException ie) {} continue;} 
       totRdByts += rdByts; 
       if(totRdByts >= contLen) break; 
      } catch(IOException ioe) {return;} 
     } 
     if(totRdByts < contLen) { 
      Log.d("IMG-DWNL-LOG: ", "error - bytes read " + totRdByts 
         + " less than content length " + contLen); 
      return; 
     } 
     if(totRdByts <= 0) return; 

     Log.d("IMG-DWNL-LOG: ", "read all image bytes successfully, setting image into view"); 
     BitmapFactory.Options options = new BitmapFactory.Options(); 
     Bitmap bitmap = BitmapFactory.decodeByteArray(imgByts, 0, contLen, options); 
     if(bitmap == null) {Log.d("IMG-DWNL-LOG: ", "got a null bitmap");} 
     ((ImageView)parkSpotImgVw).setImageBitmap(bitmap); 
    } 

    private void closeServerConnection() { 
     if(sockToSrvr == null) return; 
     if(strmFromSrvr != null) { 
      try {strmFromSrvr.close();} 
      catch(IOException e) {Log.d("IMG-DWNL-LOG: ", "Inp strm close exception");} 
     } 
     if(strmToSrvr != null) strmToSrvr.close(); 
     try {sockToSrvr.close();} 
     catch(IOException e) {Log.d("IMG-DWNL-LOG: ", "Conn close exception");} 
     strmFromSrvr = null; strmToSrvr = null; sockToSrvr = null; 
    } 

    private void openServerConnection() { 
     try {sockToSrvr = new Socket(InetAddress.getByName(srvrAddr), port);} 
     catch(UnknownHostException e) { 
      Log.d("IMG-DWNL-LOG: ", "Unknown host exception"); sockToSrvr = null; return; 
     } catch(IOException e) { 
      Log.d("IMG-DWNL-LOG: ", "Server connect exception"); sockToSrvr = null; return; 
     } 
     Log.d("IMG-DWNL-LOG: ", "Connected to server"); 

     try { 
      strmFromSrvr = new BufferedInputStream(sockToSrvr.getInputStream()); 
      strmToSrvr = new PrintWriter(new BufferedWriter(new OutputStreamWriter 
             (sockToSrvr.getOutputStream())), true); 
     } catch(IOException e) { 
      closeServerConnection(); 
      Log.d("IMG-DWNL-LOG: ", "Failed to open reader/writer. Closed the connection."); return; 
     } 
    } 

    private String getLine(BufferedInputStream dis) { 
     String outLine = ""; 
     while(true) { 
      try { 
       int c = dis.read(); if((c == -1) && (outLine.length() <= 0)) return(null); 
       outLine += Character.toString((char)c); 
       if(c == '\n') return(outLine); 
      } catch(IOException e) {if(outLine.length() <= 0) return(null); return(outLine);} 
     } 
    }  
} 

답변

0

.jpg 파일의 바이트를 Android 비트 맵 디코더로 직접 디코딩 할 수 있다고 가정 할 때 실수를 저 지르고 있습니다. 분명히 이것은 사실이 아닙니다. 그래서,받은 바이트를 폰 저장소의 임시 파일에 쓴 다음 BitmapFactory.decodeFile()을 호출하여 좋은 비트 맵을 반환하고 이미지를 보여줍니다. 이제 해결책을 찾아보십시오. 아직도 - 수신 된 바이트 (.jpg 파일에서 온 것임)에서 직접 디코딩하는 방법에 대해 더 좋은 제안이있는 사람은 더 효율적이기 때문에 직접 시도해 보는 것이 좋습니다. 감사.