Please Enable JavaScript!
Gon[ Enable JavaScript ]

반응형

안드로이드(Android) - 저장된 이미지를 불러와 갤러리 기능 구현

 

개발환경 : JDK 1.5, Android 2.1, Eclipse Galieo

 

전체내용

 

이 글은 SD 카드에 저장되어있는 모든 이미지를 불러와 보여주는 갤러리 기능을 구현한

것입니다. 두개의 화면으로 구성되어있으며 첫번째 화면은 모든 그림정보를 불러와

리스트로 보여주죠. 두번째 화면은 이미지를 클릭해 큰 화면으로 볼수 있도록 구현되었다.

그리고 버튼을 클릭하면 리스트로 돌아오게 되어있습니다.

 

첫번째 화면구현

 

첫번째 리스트를 구현한 화면의 내용입니다.

GridView 위젯과 GridView setOnItemClickListener 함수를 이용해 클릭시

상세 화면으로 갈수 있는 기능을 구현하였습니다.


GridView gv = (GridView)findViewById(R.id.ImgGridView);
   final ImageAdapter ia = new ImageAdapter(this);
   gv.setAdapter(ia);
   gv.setOnItemClickListener(new OnItemClickListener(){
   public void onItemClick(AdapterView parent, View v, int position, long id){
       ia.callImageViewer(position);
   }
});

GridView 의 내용을 표현하기 위해서는 Adapter 클래스가 필요합니다. 그래서 BaseAdapter

상속받아 ImageAdapter 가 구현되었습니다. GridView 에 들어가는 개별 View ImageView

위젯을 사용합니다. ImageView 위젯에 Bitmap 정보를 넣어서 넘기면 되는것입니다.

Bitmap 정보를 설정하는 소스 입니다.

ImageView 의 레이아웃 설정은 setLayoutParams 으로 하며, setScaleType 을 사용하여 이미지를

View 크기에 어떻게 넣을 건지 설정합니다. 그리고 아래에 소스에서는 이미지를 Bitmap 객체에

불러와 크기를 새로 치수에 맞게 새로 설정해서 셋팅하였다.
ImageView imageView;
if (convertView == null){
	imageView = new ImageView(mContext);
	imageView.setLayoutParams(new GridView.LayoutParams(95, 95));
	imageView.setAdjustViewBounds(false);
	imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
	imageView.setPadding(2, 2, 2, 2);
}else{
	imageView = (ImageView) convertView;
}
// 이미지 크기를 새로 설정한다.
BitmapFactory.Options bo = new BitmapFactory.Options();
bo.inSampleSize = 8;
Bitmap bmp = BitmapFactory.decodeFile(thumbsDataList.get(position), bo);
Bitmap resized = Bitmap.createScaledBitmap(bmp, 95, 95, true);
imageView.setImageBitmap(resized); 

여기서 중요하게 다루어지는 내용중 하나는 managedQuery 를 사용하여

SD 카드에 그림들을 전부 불러오는 부분입니다. 첫번째 들어가는 파라미터에 따라

다양한 정보들을 불러 올수있도록 Url 정보를 넘기는데 미디어 정보인  이미지를 가져오기

위해서는 MediaStore.Images.Media.EXTERNAL_CONTENT_URI 필요합니다.

그리고 어떤 데이터를 받을지 String 배열을 파라미터로 설정해 넘기면 된다.

리턴값으로 Cursor 객체를 받게 되는데 그것을 이용해서 화면을 표현하면 된다.
String[] proj = {MediaStore.Images.Media._ID,
                MediaStore.Images.Media.DATA,
                MediaStore.Images.Media.DISPLAY_NAME,
	       MediaStore.Images.Media.SIZE};
Cursor imageCursor = 
    managedQuery(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
    proj, null, null, null);

managedQuery 의 함수와 파라미터 정보를 사용해 동영상,이미지 등 다양한 정보를

Cursor 객체로 받을수 있다. 그리고 쿼리의 where 절 처럼 두번째 쿼리에 값을 설정하면

특정 데이터를 불러 올수 있다.

Cursor imageCursor = managedQuery(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
    proj, "_ID='"+ thumbID +"'", null, null);
if (imageCursor != null && imageCursor.moveToFirst()){
    if (imageCursor.getCount() > 0){
        int imgData = imageCursor.getColumnIndex(MediaStore.Images.Media.DATA);
        imageDataPath = imageCursor.getString(imgData);
    }
}

첫번째 화면의 전체소스


import java.util.ArrayList;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.AdapterView.OnItemClickListener;

import com.success.R;

public class ImageList extends Activity {
	
	private Context mContext;
	
	@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.image_list);
        mContext = this;
        
        GridView gv = (GridView)findViewById(R.id.ImgGridView);
        final ImageAdapter ia = new ImageAdapter(this);
        gv.setAdapter(ia);
        gv.setOnItemClickListener(new OnItemClickListener(){
        	public void onItemClick(AdapterView parent, View v, int position, long id){
        		ia.callImageViewer(position);
        	}
        });
	}
	
	/**========================================== 
	 * 		        Adapter class 
	 * ==========================================*/
	public class ImageAdapter extends BaseAdapter {
		private String imgData;
		private String geoData;
		private ArrayList thumbsDataList;
		private ArrayList thumbsIDList;
		
		ImageAdapter(Context c){
			mContext = c;
			thumbsDataList = new ArrayList();
			thumbsIDList = new ArrayList();
			getThumbInfo(thumbsIDList, thumbsDataList);
		}
		
		public final void callImageViewer(int selectedIndex){
			Intent i = new Intent(mContext, ImagePopup.class);
			String imgPath = getImageInfo(imgData, geoData, thumbsIDList.get(selectedIndex));
			i.putExtra("filename", imgPath);
			startActivityForResult(i, 1);
		}
		
		public boolean deleteSelected(int sIndex){
			return true;
		}
		
		public int getCount() {
			return thumbsIDList.size();
		}

		public Object getItem(int position) {
			return position;
		}

		public long getItemId(int position) {	
			return position;
		}

		public View getView(int position, View convertView, ViewGroup parent) {
			ImageView imageView;
			if (convertView == null){
				imageView = new ImageView(mContext);
				imageView.setLayoutParams(new GridView.LayoutParams(95, 95));
				imageView.setAdjustViewBounds(false);
				imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
				imageView.setPadding(2, 2, 2, 2);
			}else{
				imageView = (ImageView) convertView;
			}
			BitmapFactory.Options bo = new BitmapFactory.Options();
			bo.inSampleSize = 8;
			Bitmap bmp = BitmapFactory.decodeFile(thumbsDataList.get(position), bo);
			Bitmap resized = Bitmap.createScaledBitmap(bmp, 95, 95, true);
			imageView.setImageBitmap(resized);
			
			return imageView;
		}
		
		private void getThumbInfo(ArrayList thumbsIDs, ArrayList thumbsDatas){
			String[] proj = {MediaStore.Images.Media._ID,
							 MediaStore.Images.Media.DATA,
							 MediaStore.Images.Media.DISPLAY_NAME,
							 MediaStore.Images.Media.SIZE};
			
			Cursor imageCursor = managedQuery(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
					proj, null, null, null);
			
			if (imageCursor != null && imageCursor.moveToFirst()){
				String title;
				String thumbsID;
				String thumbsImageID;
				String thumbsData;
				String data;
				String imgSize;
				
				int thumbsIDCol = imageCursor.getColumnIndex(MediaStore.Images.Media._ID);
				int thumbsDataCol = imageCursor.getColumnIndex(MediaStore.Images.Media.DATA);
				int thumbsImageIDCol = imageCursor.getColumnIndex(MediaStore.Images.Media.DISPLAY_NAME);
				int thumbsSizeCol = imageCursor.getColumnIndex(MediaStore.Images.Media.SIZE);
				int num = 0;
				do {
					thumbsID = imageCursor.getString(thumbsIDCol);
					thumbsData = imageCursor.getString(thumbsDataCol);
					thumbsImageID = imageCursor.getString(thumbsImageIDCol);
					imgSize = imageCursor.getString(thumbsSizeCol);
					num++;
					if (thumbsImageID != null){
						thumbsIDs.add(thumbsID);
						thumbsDatas.add(thumbsData);
					}
				}while (imageCursor.moveToNext());
			}
			imageCursor.close();
			return;
		}
		
		private String getImageInfo(String ImageData, String Location, String thumbID){
			String imageDataPath = null;
			String[] proj = {MediaStore.Images.Media._ID,
					 MediaStore.Images.Media.DATA,
					 MediaStore.Images.Media.DISPLAY_NAME,
					 MediaStore.Images.Media.SIZE};
			Cursor imageCursor = managedQuery(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
					proj, "_ID='"+ thumbID +"'", null, null);
			
			if (imageCursor != null && imageCursor.moveToFirst()){
				if (imageCursor.getCount() > 0){
					int imgData = imageCursor.getColumnIndex(MediaStore.Images.Media.DATA);
					imageDataPath = imageCursor.getString(imgData);
				}
			}
			imageCursor.close();
			return imageDataPath;
		}
	}
}


두번째 화면구현

 두번째는 리스트화면에서 클릭했을 때 그림을 확대해서 보여줍니다.

Intent 를 이용해 리스트화면에서 받은 이미지 경로와 파일명을 받습니다.

그리고 이미지 크기를 화면에 맞게 맞추어서 보여주면 됩니다.

 

/** 전송메시지 */

Intent i = getIntent();

Bundle extras = i.getExtras();

String imgPath = extras.getString("filename");

 

두번째 화면의 전체소스


import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;

import com.success.R;

public class ImagePopup extends Activity implements OnClickListener{
	private Context mContext = null;
	private final int imgWidth = 320;
	private final int imgHeight = 372;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.image_popup);
		mContext = this;
		
		/** 전송메시지 */
		Intent i = getIntent();
		Bundle extras = i.getExtras();
		String imgPath = extras.getString("filename");
		
		/** 완성된 이미지 보여주기  */
		BitmapFactory.Options bfo = new BitmapFactory.Options();
		bfo.inSampleSize = 2;
		ImageView iv = (ImageView)findViewById(R.id.imageView);
		Bitmap bm = BitmapFactory.decodeFile(imgPath, bfo);
		Bitmap resized = Bitmap.createScaledBitmap(bm, imgWidth, imgHeight, true);
		iv.setImageBitmap(resized);
		
		/** 리스트로 가기 버튼 */
		Button btn = (Button)findViewById(R.id.btn_back);
		btn.setOnClickListener(this);
	}
	/* (non-Javadoc)
	 * @see android.view.View.OnClickListener#onClick(android.view.View)
	 */
	public void onClick(View v) {
		switch(v.getId()){
		case R.id.btn_back:
			Intent intent = new Intent(mContext, ImageList.class);
			startActivity(intent);
			break;
		}
	}
}

빠진 xml 값을 넣었습니다.
// =====  image_list.xml  레이아웃설정을 위한 xml 값 =====//

     
        


위의 파일은 전체 프로젝트 파일입니다. 이것만 이클립스에서 import 시키시면

될겁니다. 그리고 현재 여기에 소개되어있는 아티클은 연습용이 아닌 어플

출시용으로 쓰기에는 무리가 있습니다. 안드로이드 시스템에 어떻게 Intent

날려서 데이타를 가져오는지에 대한 학습이 주요 목적입니다.

현재 내용은 이미지전체를 가져오기 때문에 상당한 로딩시간과 리소스가

소모됩니다. 그래서 섬네일로 불러와야 하는데 아래 처럼 파라미터로

MediaStore.Images.Thumbnails 넘깁니다.

String[] projection = {MediaStore.Images.Thumbnails._ID};
// Create the cursor pointing to the SDCard
imagecursor = managedQuery( MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI,
	projection, // Which columns to return
	null,       // Return all rows
        null,
        MediaStore.Images.Thumbnails.IMAGE_ID);

섬네일로 불러올려면 전체 이미지를 불러올때 섬네일이 없으면 섬네일 작업을

해서 넣어야 겠죠. 기회가 되면 업버전을 올리도록 하겠습니다.

현재 걸려있는 일들이 있어서 답변하는 수준밖에 안되 죄송하네요 ..

반응형
Posted by 녹두장군1
,