2010-10-07 7 views
136

Как получить объект Bitmap из Uri (если мне удастся его сохранить в /data/data/MYFOLDER/myimage.png или file///data/data/MYFOLDER/myimage.png), чтобы использовать его в моей заявке?Как получить растровое изображение от Uri?

Есть ли у кого-нибудь идеи о том, как это сделать?

+17

Вы должны обновить принятый ответ на этот пост, поскольку есть лучшие ответы, чем мои. –

+0

[второй ответ] (https://stackoverflow.com/a/4717740/2835520) является правильным, [третий ответ] (https://stackoverflow.com/a/6228188/2835520) является более полным. – IgniteCoders

ответ

-16

. . ВАЖНО: см. Ответ от @Mark Ingram ниже и @pjv для лучшего решения. . .

Вы можете попробовать это:

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

Но помните, что этот метод должен вызываться только внутри потока (не GUI -thread). Я AsyncTask.

+0

thanx, но я говорю об URI, а не о URL-адресе – ilredelweb

+2

Что касается преобразования URI в URL-адрес, например, с помощью yourUri.toURL()? –

+5

@VidarVestnes приятель, как файл может быть преобразован на Url? – dhams

405

Вот правильный способ сделать это:

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

Если вам необходимо загрузить очень большие изображения, следующий код загрузит его в черепице (избегая больших выделения памяти):

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

Смотрите ответ here

+3

Этот код не имеет отношения к более крупным изображениям, хотя (в основном, размер обоев). getBitmap() вызывает decodeStream(), который не работает с ошибкой OOM из http://stackoverflow.com/questions/2220949/handling-large-bitmaps. Любой другой совет? MediaStore.Images.Thumbnails.getThumbnail(), по-видимому, не принимает contentURI. – pjv

+1

См. Ответ здесь: http://stackoverflow.com/questions/4753013/how-to-load-tiles-from-a-large-bitmap-in-android –

+0

@MarkIngram Работает ли это с любым локальным изображением или просто изображение камеры? – NarendraJi

93

Вот правильный способ сделать это, сохраняя закладки на использование памяти, а также:

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

Вызов getBitmap() из сообщения Марка Инграма также вызывает decodeStream(), поэтому вы не теряете никаких функций.

Ссылки:

+0

Спасибо за подробное объяснение. –

+1

Это действительно помогло мне, хотя я думаю, что стоит упомянуть, что это ключевое слово не может использоваться из статического контекста. Я передал его методу getThumbnail в качестве аргумента, и он работает как шарм. –

+0

Спасибо большое чувак! –

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

да и путь должен быть в формате, как это

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

+1

Добро пожаловать в Stack Overflow. Извините, но я не вижу, как это ответ на вопрос на этой странице. – Itay

+1

спасибо Itay, это просто, если у вас есть путь, который вам нужно пройти по этому пути и получить битмап .. он работает для меня, надеюсь, что и вы попробуете это. – Dhananjay

+2

@Dhananjay Спасибо, ваш намек сэкономит мне день, и он работает, чтобы загрузить растровое изображение миниатюр из Content Provider. – Nezneika

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

работает на всех sdk. . Благодаря. Это альтернативный способ «Bitmap bitmap = MediaStore.Images.Media.getBitmap (context.getContentResolver(), uri);' –

1

вы можете сделать эту структуру:

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

этим вы можете легко конвертировать в URI растрового изображения. надежда помощь u.

+0

Это не работает в версии 7.1.1 android nougat. Это extras.getParcelable («данные»); возвращается null –

2

Использование startActivityForResult Metod как ниже

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

И вы можете получить результат, как это:

@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; 
    } 
} 
0

Полный метод для получения изображения из URI мобильной галереи .....

защищенный 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 
        userImage = getStringImage(rbitmap); 
        imageViewUserImage.setImageBitmap(rbitmap); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 


     } 

}