मेरे ऐप के लिए गैलरी (एसडी कार्ड) से एक छवि कैसे चुनें?


343

यह सवाल मूल रूप से एंड्रॉइड 1.6 के लिए पूछा गया था।

मैं अपने ऐप में फोटो विकल्पों पर काम कर रहा हूं।

मेरी गतिविधि में एक बटन और एक ImageView है। जब मैं बटन पर क्लिक करता हूं तो यह गैलरी में रीडायरेक्ट हो जाएगा और मैं एक छवि का चयन कर सकूंगा। चयनित छवि मेरे ImageView में दिखाई देगी।


1
इस उत्तर को देखें, मैंने एक बेहतर कोड पोस्ट किया है जिसमें फ़ाइल मैनेजरों से भी पिक्स सँभालने के लिए stackoverflow.com/questions/2169649/…
mad

जवाबों:


418

अद्यतन उत्तर, लगभग 5 साल बाद:

मूल उत्तर में कोड अब मज़बूती से काम नहीं करता है, क्योंकि विभिन्न स्रोतों से छवियां कभी-कभी एक अलग सामग्री यूआरआई के content://बजाय वापस आती हैं, अर्थात file://। एक बेहतर समाधान केवल उपयोग करने के लिए है context.getContentResolver().openInputStream(intent.getData()), कि के रूप में एक InputStream है कि आप आपके द्वारा चुने गए के रूप में संभाल कर सकते हैं वापस आ जाएगी।

उदाहरण के लिए, BitmapFactory.decodeStream()इस स्थिति में पूरी तरह से काम करता है, जैसा कि आप तब भी विकल्प का उपयोग कर सकते हैं और बड़ी छवियों को डाउन करने और स्मृति समस्याओं से बचने के लिए फ़ील्ड का उपयोग कर सकते हैं।

हालाँकि, Google ड्राइव जैसी चीजें 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);
        }
    }
}

इसके बाद, आपको चयनित छवि को "yourSelectedImage" में संग्रहीत किया जाता है, जो भी आप चाहते हैं। यह कोड ContentResolver डेटाबेस में छवि का स्थान प्राप्त करके काम करता है, लेकिन यह अपने आप में पर्याप्त नहीं है। प्रत्येक छवि में लगभग 18 कॉलम होते हैं, जिसमें इसकी फ़ाइलपथ से लेकर 'तारीख अंतिम संशोधन' तक के जीपीएस निर्देशांक होते हैं, जहां फोटो ली गई थी, हालांकि कई फ़ील्ड वास्तव में उपयोग नहीं किए जाते हैं।

समय बचाने के लिए जैसा कि आपको वास्तव में अन्य क्षेत्रों की आवश्यकता नहीं है, कर्सर खोज एक फिल्टर के साथ की जाती है। फ़िल्टर आपके इच्छित स्तंभ के नाम को निर्दिष्ट करके काम करता है, MediaStore.Images.Media.DATA, जो पथ है, और फिर कर्सर स्ट्रिंग क्वेरी में उस स्ट्रिंग [] को दे रहा है। कर्सर क्वेरी पथ के साथ लौटती है, लेकिन आपको पता नहीं है कि columnIndexकोड का उपयोग करने तक यह किस कॉलम में है । वह बस अपने नाम के आधार पर कॉलम की संख्या प्राप्त करता है, वही जो फ़िल्टरिंग प्रक्रिया में उपयोग किया जाता है। एक बार जब आप मिल जाते हैं, तो आप अंततः कोड के अंतिम पंक्ति के साथ एक बिटमैप में छवि को डीकोड करने में सक्षम होते हैं।


4
कर्सर। लोवट फ़र्स्ट () अस्तित्व के लिए जाँच की जानी चाहिए: अगर (कर्सर। लोवट फ़र्स्ट ()) {कर्सर डेटा के साथ कुछ करें}
मिस्किन

14
कर्सर के बजाय आपको इस तरह से छवि प्राप्त करनी चाहिए: Bitmap b = MediaStore.Images.Media.getBitmap (this.getContentResolver (), selectImage);
लुइगी एगोस्टी

4
लुइगी, अगर बिटमैप बड़ा है मीडियास्टोरी ।mages.Media.getBitmap () आउटऑफमेरी अपवाद का कारण बन सकता है। स्टीव की विधि छवि को मेमोरी में लोड करने से पहले नीचे स्केल करने की अनुमति देती है।
फ्रैंक हार्पर

9
यह मेरे लिए काम नहीं कर रहा है, मुझे कर्सर से एक नल मिलता है।
एलेक्सिस पॉट्रोट

9
इस पद्धति के साथ सावधानी: फ़ाइल नाम 'शून्य' होगा जब उपयोगकर्ता एक पिकसा एल्बम या Google+ फ़ोटो ऐप से एक फ़ोटो का चयन करता है।
सिस्के बोकेलो

315
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);

    }

8
स्मृति त्रुटि में वीएम के परिणामस्वरूप 100px इमेजव्यू द्वारा मेरे छोटे 100px में 1.5MB जेपीआर डालने से परिणाम हो गया। डाउनसमलिंग
ने

1
नमस्ते। क्या दोनों धाराएँ बंद नहीं होनी चाहिए?
डेनिस नियाज़ेव

नमस्कार @ siamii..I ने आपके कोड का पालन किया..लेकिन यह आंशिक रूप से मेरे लिए काम कर रहा है .. :( जब कैप्चर की गई इमेज सेक्शन के तहत गैलरी से इमेज को चुना गया है, तब यह json एरर दे रहा है, लेकिन जब ब्लूटूथ सेक्शन के तहत गैलरी से इमेज को चुना जाता है छवि एक्सेस की गई है और
सर्वर पर भेजी गई है..क्या

स्केल खोजने के बारे में अनुभाग के रूप में लिखा जा सकता है:int scale = 1; for ( ; bfOptions.outWidth / scale > TARGET_SIZE && bfOptions.outWidth > TARGET_SIZE; scale*=2);
The_Rafi

@siamii इस विधि को कहां और कैसे कॉल करें -------- डिकोडायरी
अक्षय कुमार

87

आपको परिणाम के लिए गैलरी का इरादा शुरू करना होगा।

Intent i = new Intent(Intent.ACTION_PICK,
               android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, ACTIVITY_SELECT_IMAGE); 

फिर onActivityForResult, intent.getData()छवि की उड़ी पाने के लिए कॉल करें । फिर आपको ContentProvider से छवि प्राप्त करने की आवश्यकता है।


ACTION_PICK दो अन्य उत्तरों में प्रयुक्त ACTION_GET_CONTENT से कैसे भिन्न होती है?
पेंग्विन 359

4
ACTION_PICK के साथ आप एक विशिष्ट URI निर्दिष्ट करते हैं और ACTION_GET_CONTENT के साथ आप एक mime_type निर्दिष्ट करते हैं। मैंने ACTION_PICK का उपयोग किया क्योंकि यह प्रश्न विशेष रूप से SDCARD के चित्र थे और सभी चित्र नहीं थे।
रॉबी पॉन्ड

2
ठंडा। यह वही है जो मुझे चाहिए था और एक आकर्षण की तरह काम किया था :) आश्चर्य है कि जहां से आप लोग यह सामान पाते हैं :)
जयशिल दवे

@WilliamKinaan ACTIVITY_SELECT_IMAGE कोई भी ऐसा अंतर मान नहीं है जिसे आप पहचानने के लिए निर्दिष्ट करते हैं, जिसके परिणामस्वरूप आपको प्राप्त होने की उम्मीद है। इसे फिर '' अनुरोधकोड '' के रूप में onActivityResult (int requestCode, int resultCode, Intent data) में वापस भेजा जाता है।
फिदो

@ फिडो मुझे एहसास हुआ कि बाद में, धन्यवाद
विलियम किनन

22

यहाँ छवि और वीडियो के लिए एक परीक्षण कोड दिया गया है। यह 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();
        }

14

गैलरी लॉन्च करने के लिए ऐसा करें और उपयोगकर्ता को एक छवि चुनने की अनुमति दें:

Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
startActivityForResult(intent, IMAGE_PICK);

फिर आपके onActivityResult()उपयोग में उस छवि का URI जो आपके ImageView पर छवि को सेट करने के लिए वापस आ गया है।


3
यह अभ्यस्त Android 4.4 उपकरणों के लिए काम करता है। यह हालिया दस्तावेज़ स्क्रीन लॉन्च करेगा।
नंदला संदीप

2
यहाँ किटकैट के लिए एक फिक्स है: stackoverflow.com/a/26690628/860488
मोर्टन होलगार्ड

11
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);
}

}

8
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();
}

}

यहाँ किटकैट के लिए एक फिक्स है: stackoverflow.com/a/26690628/860488
मोर्टन होल्मगार्ड

4

कुछ कारणों से, इस थ्रेड में सभी उत्तर onActivityResult()प्राप्त करने की प्रक्रिया को पोस्ट करने की कोशिश करते हैं Uri, जैसे कि छवि का वास्तविक पथ प्राप्त करना और फिर BitmapFactory.decodeFile(path)प्राप्त करने के लिए उपयोग करना Bitmap

यह कदम अनावश्यक है। ImageViewवर्ग एक विधि कहा जाता है setImageURI(uri)। इसके लिए अपने यूरी को पास करें और आपको किया जाना चाहिए।

Uri imageUri = data.getData();
imageView.setImageURI(imageUri);

पूर्ण कार्य उदाहरण के लिए आप यहां देख सकते हैं: http://androidbitmaps.blogspot.com/2015/04/loading-images-in-android-part-ii-pick.html

पुनश्च:
हो रही है Bitmapएक अलग चर में ऐसे मामलों में जहां छवि लोड करने के लिए में मतलब होता स्मृति में फिट करने के लिए बहुत बड़ा है, और ऑपरेशन नीचे पैमाने रोकने के लिए आवश्यक है OurOfMemoryError, @siamii जवाब में दिखाया गया है।


3

कॉल चयन पद्धति जैसे-

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();
    }
}

1
#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);


}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.