안드로이드 개발 질문/답변
(글 수 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를 먹는다는것?
아래 코드 참고해 보세요~
public static void copy(BufferedInputStream in, BufferedOutputStream out) throws IOException { try { while (true) { synchronized (buffer) { int amountRead = in.read(buffer); if (amountRead == -1) { break; } out.write(buffer, 0, amountRead); } } } catch(Exception e){ if (in != null) { in.close(); } if (out != null) { out.close(); } } finally { if (in != null) { in.close(); } if (out != null) { out.close(); } } } }