Bir Uri'den Bitmap nasıl alınır?


209

Uygulamamda kullanmak için bir Uri'den bir Bitmap nesnesi nasıl alınır ( /data/data/MYFOLDER/myimage.pngveya içinde saklamayı başarırsam file///data/data/MYFOLDER/myimage.png)?

Bunun nasıl yapılacağı hakkında bir fikri olan var mı?


30
Benimkinden daha iyi cevaplar olduğu için bu yayındaki kabul edilen cevabınızı güncellemelisiniz.
Vidar Vestnes

1
İkinci cevap , doğru olanı üçüncü cevabı daha tamamlandı.
IgniteCoders

@VidarVestnes Neden silmiyorsunuz?
Carlos López Marí

Yanıtlar:


-35

. . ÖNEMLİ: Daha iyi bir çözüm için aşağıdaki @Mark Ingram ve @pjv yanıtlarına bakın. . .

Bunu deneyebilirsiniz:

public Bitmap loadBitmap(String url)
{
    Bitmap bm = null;
    InputStream is = null;
    BufferedInputStream bis = null;
    try 
    {
        URLConnection conn = new URL(url).openConnection();
        conn.connect();
        is = conn.getInputStream();
        bis = new BufferedInputStream(is, 8192);
        bm = BitmapFactory.decodeStream(bis);
    }
    catch (Exception e) 
    {
        e.printStackTrace();
    }
    finally {
        if (bis != null) 
        {
            try 
            {
                bis.close();
            }
            catch (IOException e) 
            {
                e.printStackTrace();
            }
        }
        if (is != null) 
        {
            try 
            {
                is.close();
            }
            catch (IOException e) 
            {
                e.printStackTrace();
            }
        }
    }
    return bm;
}

Ancak unutmayın, bu yöntem yalnızca bir iş parçacığından (GUI -dread değil) çağrılmalıdır. Ben bir AsyncTask.


2
URI'yi bir url'ye dönüştürmeye ne dersiniz, örneğin yourUri.toURL () yöntemini kullanarak?
Vidar Vestnes

7
@VidarVestnes dostum, dosya yolu URL'de nasıl dönüştürülebilir?
dharam

7
Bunun seçilen cevap nasıl olduğunu anlamıyorum
Nick Cardoso

11
Katılıyorum, bu cevap en iyisi olarak kabul edilmemeli. Belki seçilmiştir çünkü ilk cevaptı. Eski bir yazı. Her neyse, daha iyi çözümler için aşağıdaki cevaplara bakınız.
Vidar Vestnes

8
@VidarVestnes sadece cevabını sil
winklerrr

564

İşte bunu yapmanın doğru yolu:

protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode == RESULT_OK)
    {
        Uri imageUri = data.getData();
        Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), imageUri);
    }
}

Çok büyük görüntüler yüklemeniz gerekiyorsa, aşağıdaki kod döşemeye yüklenir (büyük bellek ayırmalarından kaçınır):

BitmapRegionDecoder decoder = BitmapRegionDecoder.newInstance(myStream, false);  
Bitmap region = decoder.decodeRegion(new Rect(10, 10, 50, 50), null);

Cevabı burada görün


3
Bu kod daha büyük görüntülerle ilgilenmez (temelde herhangi bir duvar kağıdı boyutu). getBitmap () gelen OOM hata ile başarısız decodeStream () çağırır stackoverflow.com/questions/2220949/handling-large-bitmaps . Başka tavsiye var mı? MediaStore.Images.Thumbnails.getThumbnail () görünüşte bir contentURI almıyor.
pjv

1
Cevabı buradan görebilirsiniz: stackoverflow.com/questions/4753013/…
Mark Ingram

@MarkIngram Bu herhangi bir yerel görüntü veya sadece kamera görüntüsü ile çalışır mı?
Narendra Singh

@MarkIngram data.getData () 'a erişimimiz yoksa, galeriden bir görüntü açarsam ve hepsinin yoluyla ilgili olduğunu biliyorum, nasıl uri ve bitmap alabilirim?
Umair

@Umair cevap yorumlarında sormak yerine yeni bir soru sormalısınız. Bu arada: buraya bir göz atın developer.android.com/reference/android/net/Uri.html
winklerrr

112

Bellek kullanımını da takip ederek doğru şekilde yapmanın yolu:

protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
  super.onActivityResult(requestCode, resultCode, data);
  if (resultCode == RESULT_OK)
  {
    Uri imageUri = data.getData();
    Bitmap bitmap = getThumbnail(imageUri);
  }
}

public static Bitmap getThumbnail(Uri uri) throws FileNotFoundException, IOException{
  InputStream input = this.getContentResolver().openInputStream(uri);

  BitmapFactory.Options onlyBoundsOptions = new BitmapFactory.Options();
  onlyBoundsOptions.inJustDecodeBounds = true;
  onlyBoundsOptions.inDither=true;//optional
  onlyBoundsOptions.inPreferredConfig=Bitmap.Config.ARGB_8888;//optional
  BitmapFactory.decodeStream(input, null, onlyBoundsOptions);
  input.close();

  if ((onlyBoundsOptions.outWidth == -1) || (onlyBoundsOptions.outHeight == -1)) {
    return null;
  }

  int originalSize = (onlyBoundsOptions.outHeight > onlyBoundsOptions.outWidth) ? onlyBoundsOptions.outHeight : onlyBoundsOptions.outWidth;

  double ratio = (originalSize > THUMBNAIL_SIZE) ? (originalSize / THUMBNAIL_SIZE) : 1.0;

  BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
  bitmapOptions.inSampleSize = getPowerOfTwoForSampleRatio(ratio);
  bitmapOptions.inDither = true; //optional
  bitmapOptions.inPreferredConfig=Bitmap.Config.ARGB_8888;//
  input = this.getContentResolver().openInputStream(uri);
  Bitmap bitmap = BitmapFactory.decodeStream(input, null, bitmapOptions);
  input.close();
  return bitmap;
}

private static int getPowerOfTwoForSampleRatio(double ratio){
  int k = Integer.highestOneBit((int)Math.floor(ratio));
  if(k==0) return 1;
  else return k;
}

Mark Ingram'ın gönderisinden getBitmap () çağrısı da decodeStream () öğesini çağırır, böylece herhangi bir işlevsellik kaybetmezsiniz.

Referanslar:


1
Bu anahtar kelimenin statik bir bağlamda kullanılamayacağından bahsetmeye değer olsa da, bu gerçekten bana yardımcı oldu. Bağımsız değişken olarak getThumbnail yöntemine geçtim ve bir cazibe gibi çalışıyor.
MacKinley Smith

8
Herhangi biri bana THUMBNAILSIZE ne değer vermesi gerektiğini söyleyebilir miyim
Abid

2
İlk BitmapFactory.decodeStream (...) çağrısı, akışın okuma konumunu sonuna kadar ayarladığından, InputStream'in kapatılması ve yeniden açılması gerçekten gereklidir;
DominicM

3
lütfen THUMBNAILSIZE
Mightian

3
Oranı kendiniz ikisinin gücü olarak hesaplamak gereksizdir, çünkü kod çözücünün kendisi numune boyutunu ikiye en yakın güce yuvarlar. Bu nedenle yöntem çağrısı getPowerOfTwoForSampleRatio()atlanabilir. Bakınız: developer.android.com/reference/android/graphics/…
winklerrr

42
try
{
    Bitmap bitmap = MediaStore.Images.Media.getBitmap(c.getContentResolver() , Uri.parse(paths));
}
catch (Exception e) 
{
    //handle exception
}

ve evet yolu böyle bir formatta olmalıdır

file:///mnt/sdcard/filename.jpg


1
teşekkürler Itay, bu basit, eğer u yol var sadece bu yolu geçmek ve Bitmap almak zorunda .. benim için çalışıyor, u da bunu deneyin umuyoruz ..
DjP

2
@Dhananjay Teşekkür ederim, ipucunuz günümü kurtarıyor ve İçerik Sağlayıcı'dan küçük resim bitmap'ini yüklemek için çalışıyor.
Nezneika

2
Ayrıca, Uri.parse () , URI.parse ("file: ///mnt/sdcard/filename.jpg") gibi URI biçimini içermelidir , eğer değilse java.io.FileNotFoundException: İçerik yok sağlayıcı .
Nezneika

Bazı editoryalleştirme iyi olurdu, ancak bu çoğu durumda çalışan OP sorusuna iyi ve kısa bir cevaptır. Bu, OP sorularına doğrudan cevap veren bu diğer cevapların parçasını damlatmak için sayfada olması güzel bir cevaptır.
umassthrower

1
@AndroidNewBee c Bağlam nesnesidir.
DjP

17

Bu en kolay çözümdür:

Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), uri);

16
private void uriToBitmap(Uri selectedFileUri) {
    try {
        ParcelFileDescriptor parcelFileDescriptor =
                getContentResolver().openFileDescriptor(selectedFileUri, "r");
        FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
        Bitmap image = BitmapFactory.decodeFileDescriptor(fileDescriptor);

        parcelFileDescriptor.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

3
tüm sdk üzerinde çalışıyor .. Teşekkürler. alternatif yoluBitmap bitmap = MediaStore.Images.Media.getBitmap(context.getContentResolver(), uri);
Jigar Patel

tüm SDK en gerçek cevap
Noaman Akram

13

O görünüyor MediaStore.Images.Media.getBitmapkullanımdan kaldırıldı API 29. Tavsiye edilen yol ImageDecoder.createSourceeklendi API 28.

Bitmap'in nasıl alınacağı aşağıda açıklanmıştır:

val bitmap = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
    ImageDecoder.decodeBitmap(ImageDecoder.createSource(requireContext().contentResolver, imageUri))
} else {
    MediaStore.Images.Media.getBitmap(requireContext().contentResolver, imageUri)
}

11

Bitmap'i böyle uri'den alabilirsiniz

Bitmap bitmap = null;
try {
    bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), imageUri);
} catch (IOException e) {
    e.printStackTrace();
}

10
Uri imgUri = data.getData();
Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), imgUri);

2
Lütfen bu kodun nasıl çalıştığı ve soruyu nasıl cevapladığı hakkında ayrıntılı bilgi verir misiniz?
Michael Dodd

2

Aşağıdaki gibi startActivityForResult metodunu kullanın

        startActivityForResult(new Intent(Intent.ACTION_PICK).setType("image/*"), PICK_IMAGE);

Ve şöyle sonuç alabilirsiniz:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (resultCode != RESULT_OK) {
        return;
    }
    switch (requestCode) {
        case PICK_IMAGE:
            Uri imageUri = data.getData();
            try {
                Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), imageUri);
            } catch (IOException e) {
                e.printStackTrace();
            }
         break;
    }
}

2

Bir çok yol denedim. Bu iş benim için mükemmel.

Galeri'den pictrue seçerseniz. Sen almanın eşya olması gerekiyor Uriden intent.clipdataveya intent.databunlardan biri farklı sürümde boş olabilir çünkü.

  private fun onChoosePicture(data: Intent?):Bitmap {
        data?.let {
            var fileUri:Uri? = null

              data.clipData?.let {clip->
                  if(clip.itemCount>0){
                      fileUri = clip.getItemAt(0).uri
                  }
              }
            it.data?.let {uri->
                fileUri = uri
            }


               return MediaStore.Images.Media.getBitmap(this.contentResolver, fileUri )
}

1

bu yapıyı yapabilirsiniz:

protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) {
    super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
    switch(requestCode) {
        case 0:
            if(resultCode == RESULT_OK){
                    Uri selectedImage = imageReturnedIntent.getData();
                    Bundle extras = imageReturnedIntent.getExtras();
                    bitmap = extras.getParcelable("data");
            }
            break;
   }

Bu şekilde bir uri'yi bitmap'e kolayca dönüştürebilirsiniz. umut yardım et.


1
Bu android nuga 7.1.1 sürümünde çalışmıyor. Bu extras.getParcelable ("veri"); null döndürüyor
Developer_vaibhav

1

Ankastre ait getBitmapolan şimdi KOTLIN içinde aşağıdaki yöntemi uygulayabilirsiniz BULUNMADI edilir

PICK_IMAGE_REQUEST ->
    data?.data?.let {
        val bitmap = BitmapFactory.decodeStream(contentResolver.openInputStream(it))
        imageView.setImageBitmap(bitmap)
    }

1
  InputStream imageStream = null;
    try {
        imageStream = getContext().getContentResolver().openInputStream(uri);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }
    final Bitmap selectedImage = BitmapFactory.decodeStream(imageStream);

1

(KOTLIN) 7 Nisan 2020 itibariyle, yukarıda belirtilen seçeneklerin hiçbiri işe yaramadı, ama benim için işe yarayan:

  1. Bitmap'i bir val'de saklamak ve onunla bir imageView ayarlamak istiyorsanız, bunu kullanın:

    val bitmap = BitmapFactory.decodeFile(currentPhotoPath).also { bitmap -> imageView.setImageBitmap(bitmap) }

  2. Bitmap'i ve imageView olarak ayarlamak istiyorsanız, bunu kullanın:

    BitmapFactory.decodeFile(currentPhotoPath).also { bitmap -> imageView.setImageBitmap(bitmap) }


0

Mobil galeriden görüntü uri almak için tam yöntem.

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

  if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data != null && data.getData() != null) {
                Uri filePath = data.getData();

     try { //Getting the Bitmap from Gallery
           Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), filePath);
           rbitmap = getResizedBitmap(bitmap, 250);//Setting the Bitmap to ImageView
           serImage = getStringImage(rbitmap);
           imageViewUserImage.setImageBitmap(rbitmap);
      } catch (IOException e) {
           e.printStackTrace();
      }


   }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.