2010-03-30 5 views

Répondre

10

Il est en fait très simple à faire. Utilisez

Bitmap yourBitmap = Bitmap.createBitmap(sourceBitmap, x to start from, y to start from, width, height)

Mise à jour: utiliser BitmapRegionDecoder

+3

Merci Steve, mais cela me obligerait à charger dans le sourceBitmap premier, et je suis en train d'éviter de faire cela, car il est trop grand pour tenir dans la mémoire, et je veux travailler avec un bitmap qui n'a pas été sous-échantillonnée . – Schermvlieger

+0

Oups, vous avez raison, je n'ai pas lu cette partie de votre question correctement. Je ne suis pas sûr alors comment faire ceci sans downsampling. En fait, un problème très similaire est aussi sur ma propre liste figure-out-to-do! –

9

essayer cette

InputStream istream = null; 
try { 
    istream = this.getContentResolver().openInputStream(yourBitmapUri); 
} catch (FileNotFoundException e1) { 
    e1.printStackTrace(); 
} 

BitmapRegionDecoder decoder  = null; 
try { 
    decoder = BitmapRegionDecoder.newInstance(istream, false); 
} catch (IOException e) { 
    e.printStackTrace(); 
} 
Bitmap bMap = decoder.decodeRegion(new Rect(istream, x to start from, y to start from, x to end with, y to end with), null);  
imageView.setImageBitmap(bMap); 
+0

oops..sorry .. une chose cette méthode est pour la version intented sdk 2.3 ou plus ... – Renjith

0

@RKN

Votre méthode peut aussi lancer OutOfMemoryError exception - si bitmap recadrée dépasse VM.

Ma méthode combine vôtre et la protection contre cette exeption: (l, t, r, b -% de l'image)

Bitmap cropBitmap(ContentResolver cr, String file, float l, float t, float r, float b) 
{ 
    try 
    { 
     BitmapFactory.Options options = new BitmapFactory.Options(); 
     options.inJustDecodeBounds = true; 

     // First decode with inJustDecodeBounds=true to check dimensions 
     BitmapFactory.decodeFile(file, options); 
     int oWidth = options.outWidth; 
     int oHeight = options.outHeight; 

     InputStream istream = cr.openInputStream(Uri.fromFile(new File(file))); 

     BitmapRegionDecoder decoder = BitmapRegionDecoder.newInstance(istream, false); 
     if (decoder != null) 
     { 
      options = new BitmapFactory.Options(); 

      int startingSize = 1; 
      if ((r - l) * oWidth * (b - t) * oHeight > 2073600) 
       startingSize = (int) ((r - l) * oWidth * (b - t) * oHeight/2073600) + 1; 

      for (options.inSampleSize = startingSize; options.inSampleSize <= 32; options.inSampleSize++) 
      { 
       try 
       { 
        return decoder.decodeRegion(new Rect((int) (l * oWidth), (int) (t * oHeight), (int) (r * oWidth), (int) (b * oHeight)), options);  
       } 
       catch (OutOfMemoryError e) 
       { 
        Continue with for loop if OutOfMemoryError occurs 
       } 
      } 
     } 
     else 
      return null; 
    } 
    catch (FileNotFoundException e) 
    { 
     e.printStackTrace(); 
    } 
    catch (IOException e) 
    { 
     e.printStackTrace(); 
    } 

    return null; 
} 

et retourne bitmap disponible max ou null

+0

si 'startingSize'> 32 parce que d'abord l'image d'entrée est si grand? – TWiStErRob

0

utilisation RapidDecoder.

Et tout simplement faire ce

import rapid.decoder.BitmapDecoder; 

Rect bounds = new Rect(left, top, right, bottom); 
Bitmap bitmap = BitmapDecoder.from(getResources(), R.drawable.image) 
     .region(bounds).decode(); 

Il nécessite Android 2.2 ou supérieur.

0

Vous pouvez charger la version réduite du bitmap avec des entièrement le chargement du bitmap en utilisant l'algorithme suivant

  • Calculer le inSampleSize maximum qui donne encore une image plus grand que votre cible.
  • Chargez l'image à l'aide de BitmapFactory.decodeFile (fichier, options), en passant inSampleSize comme option .
  • Resize aux dimensions désirées à l'aide de Bitmap.createScaledBitmap().

Vérifiez le message suivant Android: Resize a large bitmap file to scaled output file pour plus de détails.

Questions connexes