เดิมคำถามนี้ถูกถามสำหรับ Android 1.6
ฉันกำลังทำงานกับตัวเลือกรูปภาพในแอพของฉัน
ฉันมีปุ่มและ ImageView ในกิจกรรมของฉัน เมื่อฉันคลิกปุ่มมันจะเปลี่ยนเส้นทางไปยังแกลเลอรี่และฉันจะสามารถเลือกภาพได้ ภาพที่เลือกจะปรากฏใน ImageView ของฉัน
เดิมคำถามนี้ถูกถามสำหรับ Android 1.6
ฉันกำลังทำงานกับตัวเลือกรูปภาพในแอพของฉัน
ฉันมีปุ่มและ ImageView ในกิจกรรมของฉัน เมื่อฉันคลิกปุ่มมันจะเปลี่ยนเส้นทางไปยังแกลเลอรี่และฉันจะสามารถเลือกภาพได้ ภาพที่เลือกจะปรากฏใน ImageView ของฉัน
คำตอบ:
อัปเดตคำตอบเกือบ 5 ปีต่อมา:
รหัสในคำตอบเดิมไม่ทำงานได้อย่างน่าเชื่อถือเป็นภาพจากแหล่งต่าง ๆ บางครั้งก็กลับมาพร้อมกับเนื้อหาที่แตกต่างกัน URI คือมากกว่าcontent://
file://
ทางออกที่ดีกว่าคือใช้ง่ายๆเพียงแค่context.getContentResolver().openInputStream(intent.getData())
คืนค่า InputStream ที่คุณสามารถจัดการได้ตามที่คุณเลือก
ตัวอย่างเช่นBitmapFactory.decodeStream()
ทำงานได้อย่างสมบูรณ์แบบในสถานการณ์นี้เนื่องจากคุณสามารถใช้ฟิลด์ตัวเลือกและ inSampleSize เพื่อสุ่มภาพขนาดใหญ่และหลีกเลี่ยงปัญหาหน่วยความจำ
อย่างไรก็ตามสิ่งต่างๆเช่น Google Drive จะส่งคืน URIs ให้กับรูปภาพที่ยังไม่ได้ดาวน์โหลดจริง ดังนั้นคุณต้องดำเนินการรหัส 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);
}
}
}
หลังจากนี้คุณมีภาพที่เลือกเก็บไว้ใน "yourSelectedImage" เพื่อทำสิ่งที่คุณต้องการ รหัสนี้ทำงานโดยรับตำแหน่งของภาพในฐานข้อมูล ContentResolver แต่ตัวของมันเองยังไม่เพียงพอ แต่ละภาพมีข้อมูลประมาณ 18 คอลัมน์ตั้งแต่ filepath ไปจนถึง 'วันที่แก้ไขล่าสุด' ไปจนถึงพิกัด GPS ของตำแหน่งที่ถ่ายภาพถึงแม้ว่าจะไม่ได้ใช้ฟิลด์จำนวนมาก
เพื่อประหยัดเวลาในขณะที่คุณไม่ต้องการฟิลด์อื่นการค้นหาเคอร์เซอร์ทำได้ด้วยตัวกรอง ตัวกรองใช้งานได้โดยระบุชื่อของคอลัมน์ที่คุณต้องการ MediaStore.Images.Media.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);
}
}
}
หรือมิฉะนั้นคุณสามารถลดขนาดตัวอย่างรูปภาพของคุณเพื่อหลีกเลี่ยงข้อผิดพลาด OutOfMemory
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);
}
int scale = 1; for ( ; bfOptions.outWidth / scale > TARGET_SIZE && bfOptions.outWidth > TARGET_SIZE; scale*=2);
คุณต้องเริ่มเจตนาแกลเลอรี่เพื่อให้ได้ผลลัพธ์
Intent i = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, ACTIVITY_SELECT_IMAGE);
จากนั้นในการonActivityForResult
โทรintent.getData()
เพื่อรับ Uri ของภาพ จากนั้นคุณต้องรับภาพจาก ContentProvider
นี่คือรหัสที่ทดสอบสำหรับรูปภาพและวิดีโอมันจะใช้ได้กับ API ทั้งหมดที่น้อยกว่า 19 และมากกว่า 19 เช่นกัน
ภาพ:
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 ของภาพที่ถูกส่งกลับมาเพื่อตั้งค่าภาพใน ImageView ของคุณ
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
โทรวิธีเลือกภาพเหมือน -
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);
}