내 앱을 위해 갤러리(SD 카드)에서 이미지를 선택하는 방법은 무엇입니까?
이 질문은 원래 Android 1.6용으로 제기되었습니다.
저는 제 앱에서 사진 옵션 작업을 하고 있습니다.
활동에 단추와 이미지 보기가 있습니다.버튼을 클릭하면 갤러리로 리디렉션되고 이미지를 선택할 수 있습니다.선택한 이미지가 내 이미지 보기에 나타납니다.
거의 5년 후에 답변이 업데이트되었습니다.
원본 답변의 코드는 더 이상 안정적으로 작동하지 않습니다. 다양한 소스의 이미지가 때때로 다른 컨텐츠 URI(URI)로 반환되기 때문입니다.content://
file://
더 나은 솔루션은 단순하게 사용하는 것입니다.context.getContentResolver().openInputStream(intent.getData())
원하는 대로 처리할 수 있는 InputStream을 반환합니다.
를 들면, 들면를예,BitmapFactory.decodeStream()
옵션 및 inSampleSize 필드를 사용하여 큰 이미지를 다운샘플링하고 메모리 문제를 방지할 수도 있으므로 이 상황에서 완벽하게 작동합니다.
그러나 Google Drive와 같은 것들은 URI를 아직 실제로 다운로드되지 않은 이미지로 반환합니다.따라서 백그라운드 스레드에서 getContentResolver() 코드를 수행해야 합니다.
원답:
다른 답변들은 의도를 보내는 방법을 설명했지만, 응답을 처리하는 방법을 잘 설명하지 못했습니다.다음은 그 방법에 대한 몇 가지 샘플 코드입니다.
protected void onActivityResult(int requestCode, int resultCode,
Intent imageReturnedIntent) {
super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
switch(requestCode) {
case REQ_CODE_PICK_IMAGE:
if(resultCode == RESULT_OK){
Uri selectedImage = imageReturnedIntent.getData();
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = getContentResolver().query(
selectedImage, filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String filePath = cursor.getString(columnIndex);
cursor.close();
Bitmap yourSelectedImage = BitmapFactory.decodeFile(filePath);
}
}
}
그런 다음 선택한 이미지를 "선택한 이미지"에 저장하여 원하는 작업을 수행할 수 있습니다.이 코드는 ContentResolver 데이터베이스에서 이미지의 위치를 가져오는 방식으로 작동하지만 그 자체로는 충분하지 않습니다.각 이미지에는 파일 경로부터 '마지막으로 수정된 날짜', 사진이 촬영된 위치의 GPS 좌표에 이르기까지 약 18개의 정보 열이 있지만, 대부분의 필드는 실제로 사용되지 않습니다.
다른 필드가 실제로 필요하지 않기 때문에 시간을 절약하기 위해 커서 검색은 필터를 사용하여 수행됩니다.필터는 원하는 열의 이름인 MediaStore를 지정하여 작동합니다.이미지들.미디어입니다.DATA를 선택한 다음 해당 문자열[]을(를) 커서 쿼리에 제공합니다.되지만, 커서 쿼리가 어떤 알 수 .columnIndex
코드입니다. 필터링 프로세스에서 사용된 것과 동일한 이름을 기준으로 열의 번호를 얻습니다.일단 그것을 얻으면, 당신은 마침내 제가 준 마지막 줄의 코드로 이미지를 비트맵으로 디코딩할 수 있습니다.
private static final int SELECT_PHOTO = 100;
시작 의도
Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
photoPickerIntent.setType("image/*");
startActivityForResult(photoPickerIntent, SELECT_PHOTO);
처리결과
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) {
super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
switch(requestCode) {
case SELECT_PHOTO:
if(resultCode == RESULT_OK){
Uri selectedImage = imageReturnedIntent.getData();
InputStream imageStream = getContentResolver().openInputStream(selectedImage);
Bitmap yourSelectedImage = BitmapFactory.decodeStream(imageStream);
}
}
}
메모리 부족 오류를 방지하기 위해 이미지를 다운샘플링할 수도 있습니다.
private Bitmap decodeUri(Uri selectedImage) throws FileNotFoundException {
// Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(getContentResolver().openInputStream(selectedImage), null, o);
// The new size we want to scale to
final int REQUIRED_SIZE = 140;
// Find the correct scale value. It should be the power of 2.
int width_tmp = o.outWidth, height_tmp = o.outHeight;
int scale = 1;
while (true) {
if (width_tmp / 2 < REQUIRED_SIZE
|| height_tmp / 2 < REQUIRED_SIZE) {
break;
}
width_tmp /= 2;
height_tmp /= 2;
scale *= 2;
}
// Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
return BitmapFactory.decodeStream(getContentResolver().openInputStream(selectedImage), null, o2);
}
결과에 대한 갤러리 의도를 시작해야 합니다.
Intent i = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, ACTIVITY_SELECT_IMAGE);
그럼 인onActivityForResult
,불러intent.getData()
이미지의 URI를 가져옵니다.그런 다음 콘텐츠 공급자로부터 이미지를 가져와야 합니다.
다음은 테스트를 거친 이미지 및 비디오 코드입니다.19세 미만 및 19세 이상의 모든 API에서도 작동합니다.
이미지:
if (Build.VERSION.SDK_INT <= 19) {
Intent i = new Intent();
i.setType("image/*");
i.setAction(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(i, 10);
} else if (Build.VERSION.SDK_INT > 19) {
Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, 10);
}
비디오:
if (Build.VERSION.SDK_INT <= 19) {
Intent i = new Intent();
i.setType("video/*");
i.setAction(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(i, 20);
} else if (Build.VERSION.SDK_INT > 19) {
Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Video.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, 20);
}
.
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) {
if (requestCode == 10) {
Uri selectedImageUri = data.getData();
String selectedImagePath = getRealPathFromURI(selectedImageUri);
} else if (requestCode == 20) {
Uri selectedVideoUri = data.getData();
String selectedVideoPath = getRealPathFromURI(selectedVideoUri);
}
}
}
public String getRealPathFromURI(Uri uri) {
if (uri == null) {
return null;
}
String[] projection = {MediaStore.Images.Media.DATA};
Cursor cursor = getActivity().getContentResolver().query(uri, projection, null, null, null);
if (cursor != null) {
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
return uri.getPath();
}
갤러리를 시작하고 사용자가 이미지를 선택할 수 있도록 하려면 이 작업을 수행합니다.
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
startActivityForResult(intent, IMAGE_PICK);
그럼 당신의onActivityResult()
반환되는 이미지의 URI를 사용하여 이미지 보기에서 이미지를 설정합니다.
public class EMView extends Activity {
ImageView img,img1;
int column_index;
Intent intent=null;
// Declare our Views, so we can access them later
String logo,imagePath,Logo;
Cursor cursor;
//YOU CAN EDIT THIS TO WHATEVER YOU WANT
private static final int SELECT_PICTURE = 1;
String selectedImagePath;
//ADDED
String filemanagerstring;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
img= (ImageView)findViewById(R.id.gimg1);
((Button) findViewById(R.id.Button01))
.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
// in onCreate or any event where your want the user to
// select a file
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,
"Select Picture"), SELECT_PICTURE);
}
});
}
//UPDATED
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK) {
if (requestCode == SELECT_PICTURE) {
Uri selectedImageUri = data.getData();
//OI FILE Manager
filemanagerstring = selectedImageUri.getPath();
//MEDIA GALLERY
selectedImagePath = getPath(selectedImageUri);
img.setImageURI(selectedImageUri);
imagePath.getBytes();
TextView txt = (TextView)findViewById(R.id.title);
txt.setText(imagePath.toString());
Bitmap bm = BitmapFactory.decodeFile(imagePath);
// img1.setImageBitmap(bm);
}
}
}
//UPDATED!
public String getPath(Uri uri) {
String[] projection = { MediaColumns.DATA };
Cursor cursor = managedQuery(uri, projection, null, null, null);
column_index = cursor
.getColumnIndexOrThrow(MediaColumns.DATA);
cursor.moveToFirst();
imagePath = cursor.getString(column_index);
return cursor.getString(column_index);
}
}
public class BrowsePictureActivity extends Activity {
private static final int SELECT_PICTURE = 1;
private String selectedImagePath;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
((Button) findViewById(R.id.Button01))
.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,
"Select Picture"), SELECT_PICTURE);
}
});
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
if (requestCode == SELECT_PICTURE) {
Uri selectedImageUri = data.getData();
selectedImagePath = getPath(selectedImageUri);
}
}
}
public String getPath(Uri uri) {
if( uri == null ) {
return null;
}
// this will only work for images selected from gallery
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = managedQuery(uri, projection, null, null, null);
if( cursor != null ){
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
return uri.getPath();
}
}
어떤 이유로, 이 스레드의 모든 대답은,onActivityResult()
수신된 후 처리 시도Uri
이미지의 실제 경로를 얻은 다음 사용하는 것처럼.BitmapFactory.decodeFile(path)
을 얻기 위해Bitmap
.
이 단계는 불필요합니다.ImageView
클래스에는 다음과 같은 메서드가 있습니다.setImageURI(uri)
당신의 URI를 그것에 전달하면 당신은 끝날 것입니다.
Uri imageUri = data.getData();
imageView.setImageURI(imageUri);
전체 작업 예제를 보려면 다음을 참조하십시오. http://androidbitmaps.blogspot.com/2015/04/loading-images-in-android-part-iii-pick.html
PS:
다음 항목 가져오기Bitmap
로드할 이미지가 메모리에 맞지 않고 축소 작업이 필요한 경우에는 별도의 변수가 필요합니다.OurOfMemoryError
@siamii 답변에 나온 것처럼.
call chooseImage method like-
public void chooseImage(ImageView v)
{
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType("image/*");
startActivityForResult(intent, SELECT_PHOTO);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
if(imageReturnedIntent != null)
{
Uri selectedImage = imageReturnedIntent.getData();
switch(requestCode) {
case SELECT_PHOTO:
if(resultCode == RESULT_OK)
{
Bitmap datifoto = null;
temp.setImageBitmap(null);
Uri picUri = null;
picUri = imageReturnedIntent.getData();//<- get Uri here from data intent
if(picUri !=null){
try {
datifoto = android.provider.MediaStore.Images.Media.getBitmap(this.getContentResolver(), picUri);
temp.setImageBitmap(datifoto);
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
} catch (OutOfMemoryError e) {
Toast.makeText(getBaseContext(), "Image is too large. choose other", Toast.LENGTH_LONG).show();
}
}
}
break;
}
}
else
{
//Toast.makeText(getBaseContext(), "data null", Toast.LENGTH_SHORT).show();
}
}
#initialize in main activity
path = Environment.getExternalStorageDirectory()
+ "/images/make_machine_example.jpg"; #
ImageView image=(ImageView)findViewById(R.id.image);
//--------------------------------------------------||
public void FromCamera(View) {
Log.i("camera", "startCameraActivity()");
File file = new File(path);
Uri outputFileUri = Uri.fromFile(file);
Intent intent = new Intent(
android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
startActivityForResult(intent, 1);
}
public void FromCard() {
Intent i = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, 2);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 2 && resultCode == RESULT_OK
&& null != data) {
Uri selectedImage = data.getData();
String[] filePathColumn = { MediaStore.Images.Media.DATA };
Cursor cursor = getContentResolver().query(selectedImage,
filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String picturePath = cursor.getString(columnIndex);
cursor.close();
bitmap = BitmapFactory.decodeFile(picturePath);
image.setImageBitmap(bitmap);
if (bitmap != null) {
ImageView rotate = (ImageView) findViewById(R.id.rotate);
}
} else {
Log.i("SonaSys", "resultCode: " + resultCode);
switch (resultCode) {
case 0:
Log.i("SonaSys", "User cancelled");
break;
case -1:
onPhotoTaken();
break;
}
}
}
protected void onPhotoTaken() {
// Log message
Log.i("SonaSys", "onPhotoTaken");
taken = true;
imgCapFlag = true;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 4;
bitmap = BitmapFactory.decodeFile(path, options);
image.setImageBitmap(bitmap);
}
언급URL : https://stackoverflow.com/questions/2507898/how-to-pick-an-image-from-gallery-sd-card-for-my-app
'programing' 카테고리의 다른 글
깃 별칭을 삭제하려면 어떻게 해야 합니까? (0) | 2023.09.05 |
---|---|
Stop-Service Cmdlet이 존재하는 서비스를 열 수 없습니다. (0) | 2023.09.05 |
mariadb에 가상 열 생성 및 case 문 실패 (0) | 2023.06.17 |
오류: 기본 자격 증명을 로드할 수 없습니다(Firestore에 대한 Firebase 함수). (0) | 2023.06.17 |
C에는 논리적 할당 연산자가 없는 이유는 무엇입니까? (0) | 2023.06.17 |