안드로이드 개발 질문/답변
(글 수 45,052)
안드로이드에서 이미지를 다운받아 sdcard에 저장했는데 이미지가 깨집니다.
노규남 저 Q&A로 배우는 안드로이드 프로그래밍 p160 소스 코드로 실행했습니다.
인터넷 주소(http://img.danawa.com/cms/img/2012/09/24/1348483580.JPG)를 BufferedInputStream 클래스로 읽어 들여 바이트 배열에 저장 후 FileOutputStream과 BufferedOutputStream 클래스를 통해 sdcard 경로에 저장하는 코드입니다.
다운받은 이미지 크기는 실제 크기와 동일합니다만, 이미지를 메모장(notepad)로 불러보니 이미지의 헤더 부분이 깨진 듯 합니다.
그래서 이미지를 바이트 배열에 저장하지 않고 BitmapFactory.decodeStream( BufferedInputStream ) 로 직접 받아들여 ImageView에 띄우니 잘 뜨네요.
제 생각에는 while문을 통해 바이트 배열로 이미지를 저장하는 부분에서 문제가 있는 것 같습니다.
다음은 소스 코드입니다. 바이트 배열로 변환하는 부분을 표시했습니다.
public class Q20Activity extends Activity implements OnClickListener{ /** Called when the activity is first created. */ @Override public void onCreate( Bundle savedInstanceState ){ super.onCreate( savedInstanceState ); StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); StrictMode.setThreadPolicy( policy ); setContentView( R.layout.activity_q20 ); findViewById( R.id.btnDownload ).setOnClickListener( this ); } public void onClick( View v ){ WriteFileFromHTTP(); } public void Log( String msg ){ EditText etResult = (EditText)findViewById( R.id.etResult ); etResult.setText( "" ); etResult.append( msg + "\n" ); } private void WriteFileFromHTTP(){ URL url = null; try{ url = new URL(" "http://img.danawa.com/cms/img/2012/09/24/1348483580.JPG" ); } catch( MalformedURLException e ){ e.printStackTrace(); } int bufSize = 1024 * 1024; byte buf[] = new byte[ bufSize ]; // 1MB int nRead = 0; int offset = 0; String sdcard = android.os.Environment.getExternalStorageDirectory().getAbsolutePath(); if ( null != url ){ try{ HttpURLConnection urlConn = (HttpURLConnection)url.openConnection(); BufferedInputStream in = new BufferedInputStream( urlConn.getInputStream() ); // 바이트 배열로 변환 while( true ){ nRead = in.read( buf, 0, bufSize - offset ); if ( nRead <= 0 ) break; offset += nRead; } in.close(); urlConn.disconnect(); } catch( IOException e ){ // TODO Auto-generated catch block e.printStackTrace(); } try{ File sdDir = new File( sdcard ); if ( sdDir.exists() && sdDir.canWrite() ){ File f = new File( sdDir.getAbsolutePath() + "/test.JPG" ); f.createNewFile(); FileOutputStream fos = new FileOutputStream( f ); BufferedOutputStream out = new BufferedOutputStream( fos ); out.write( buf, 0, offset ); out.close(); fos.close(); Log( "Writing " + offset + " bytes finished" ); } } catch( Exception e ){ Log( "Could not write file " + e.getMessage() ); } } } }
공지사항을 다 읽었음
<script language="javascript"> </script>
코드상의 문제라면, 구현된 코드는 1MB 가 넘는 이미지를 받아 올 수 가 없구요.
파일로 쓸 것인데도 굳이 버퍼를 크게 잡아서 메모리를 1MB를 먹는다는것?
아래 코드 참고해 보세요~