2013-05-09 4 views
4

J'ai vraiment cherché sur l'ensemble du web avant de poster. Mon problème est que je ne peux pas redimensionner bitmap sans perdre la qualité de l'image (la qualité est vraiment mauvaise et pixélisée). Je prends le bitmap de l'appareil photo et ensuite je dois le réduire, donc je peux le télécharger plus rapidement sur le serveur.Android: redimensionnement des bitmaps sans perte de qualité

C'est la fonction qui fait l'échantillonnage

public Bitmap resizeBitmap(Bitmap bitmap){ 
     Canvas canvas = new Canvas(); 
     Bitmap resizedBitmap = null; 
     if (bitmap !=null) { 
       int h = bitmap.getHeight(); 
       int w = bitmap.getWidth(); 
       int newWidth=0; 
       int newHeight=0; 

       if(h>w){ 
        newWidth = 600; 
        newHeight = 800; 
       } 

       if(w>h){ 
        newWidth = 800; 
        newHeight = 600; 
        } 

       float scaleWidth = ((float) newWidth)/w; 
       float scaleHeight = ((float) newHeight)/h; 



       Matrix matrix = new Matrix(); 
       // resize the bit map 
       matrix.preScale(scaleWidth, scaleHeight); 

       resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0, w, h, matrix, true); 



       Paint paint = new Paint(); 
       paint.setAntiAlias(true); 
       paint.setFilterBitmap(true); 
       paint.setDither(true); 

       canvas.drawBitmap(resizedBitmap, matrix, paint); 



      } 


     return resizedBitmap; 

et voilà comment j'obtenir l'image du résultat de l'activité

protected void onActivityResult(int requestCode, int resultCode, 
      Intent data) { 
     if(resultCode != RESULT_CANCELED){ 

     if (requestCode == 0) { 
      if (resultCode == RESULT_OK) { 


        getContentResolver().notifyChange(mImageUri, null); 
        ContentResolver cr = this.getContentResolver(); 

        try 
        { 
         b = android.provider.MediaStore.Images.Media.getBitmap(cr, mImageUri); 
         Log.d("foto", Integer.toString(b.getWidth())); 
         Log.d("foto", Integer.toString(b.getHeight())); 
         addPhoto.setImageBitmap(b); 

        } 
        catch (Exception e) 
        { 
         Toast.makeText(this, "Failed to load", Toast.LENGTH_SHORT).show(); 
         Log.d("TAG", "Failed to load", e); 
        } 



      } 
     } 

Je commence à penser que la meilleure façon d'obtenir un petite taille d'image est de définir la résolution de l'appareil photo. Quelqu'un d'autre peut-il aider?

Répondre

1

Essayez Bitmap.createScaledBitmap. Il a également une option pour filtrer la source.

+2

merci ... mais j'ai essayé: resizedBitmap = Bitmap.createScaledBitmap (bitmap, newWidth, newHeight, true); Mais c'était la même chose ... encore blocky et pixélisé – Vahn84

+0

Je vois. Le dernier conseil que j'ai en tête est que vous vérifiez la classe BitmapFactory.Options, initialisez et utilisez les options pertinentes pour la qualité lors du décodage de votre Bitmap. Voici le lien de l'API: http://developer.android.com/reference/android/graphics/BitmapFactory.Options.html – Mena

+0

J'ai atteint quelque chose au moins acceptable en décodant le bitmap d'uri avec les options bitmap.factory. Mais ce n'est toujours pas la qualité que je pensais. Comment facebook et g + gèrent le téléchargement de photos? Je vois qu'ils redimensionnent toutes les images que vous téléchargez. Comment font-ils cela sans perdre un seul pixel de qualité? – Vahn84

2

Essayez le code mentionné ci-dessous pour redimensionner le bitmap. J'ai utilisé ce code pour réduire la taille de mon bitmap, et sa qualité, bien, était acceptable.

Espérons que cela aide.

+1

non, essayé mais c'est le même résultat comme avant – Vahn84

+0

Pas d'améliorations sur la qualité de Bitmap, obtenir les mêmes résultats que les précédents – sumeet

6

bon algorithme de downscaling (voisin le plus proche ne comme) se compose de 2 étapes (plus le calcul de la Rect exacte pour l'entrée/sortie des images de cultures):

  1. downscale utilisant BitmapFactory.Options :: inSampleSize- > BitmapFactory.decodeResource() aussi près que possible de la résolution que vous avez besoin, mais pas moins qu'il
  2. obtenir la résolution exacte par downscaling un peu en utilisant Canvas :: DrawBitmap()

Voici une explication détaillée comment SonyMobile résolu cette tâche: http://developer.sonymobile.com/2011/06/27/how-to-scale-images-for-your-android-application/

Voici le code source de utils échelle SonyMobile: http://developer.sonymobile.com/downloads/code-example-module/image-scaling-code-example-for-android/

+2

Cela devrait être la réponse acceptée. Juste mis en œuvre ce qui est décrit dans l'article lié et le résultat est nettement meilleur que l'utilisation de createScaledBitmap simplement, et utilise beaucoup moins lors de la réduction d'échelle. Le résultat n'est toujours pas aussi bon que lors de la réduction d'échelle, par ex. dans Photoshop cependant. –

+0

J'ai essayé cette méthode FIT et c'était exactement la même qualité que Bitmap.createScaledBitmap par défaut. Peut-être plus rapide/moins de mémoire consommée mais la qualité est la même. – lxknvlk

+0

upd - juste vérifié temps, les deux méthodes utilisent la même quantité de temps, dans mon cas, ceux-ci étaient 2-3 ms. Et je n'ai pas utilisé leurs méthodes de décodage, comme j'avais un bitmap prêt en entrée, donc pas de changements dans l'utilisation de la mémoire aussi. – lxknvlk

Questions connexes