2015-02-10 10 views
27

Come ridurre la dimensione dell'immagine senza perdere la sua qualità in Android.
Ho un ImageView nel mio progetto, devo inserire un'immagine di dimensioni maggiori in esso.
Sono nuovo ad Android.
per favore aiuto.Riduci le dimensioni dell'immagine senza perdere la sua qualità in Android

+0

I ho usato il ritaglio. ma. Ritagliare un'immagine danneggia la sua qualità ... dopo il ritaglio posso aggiungere l'immagine a imageview.ma riduce la qualità dell'immagine..ma quando sto scattando un'immagine più grande..la immagine non viene mostrata .. –

+0

Ora come posso diminuisci la dimensione dell'immagine senza perdere la sua qualità..Può che qualcuno fornisca del codice di esempio..plzz help..grazie in anticipo .. –

risposta

48

seguito codice di lavoro immagine di scala a rapporto d'aspetto:

Bitmap bitmapImage = BitmapFactory.decodeFile("Your path"); 
int nh = (int) (bitmapImage.getHeight() * (512.0/bitmapImage.getWidth())); 
Bitmap scaled = Bitmap.createScaledBitmap(bitmapImage, 512, nh, true); 
your_imageview.setImageBitmap(scaled); 

comprimere l'immagine senza comprometterne la qualità come whatsapp

public String compressImage(String imageUri) { 

     String filePath = getRealPathFromURI(imageUri); 
     Bitmap scaledBitmap = null; 

     BitmapFactory.Options options = new BitmapFactory.Options(); 

//  by setting this field as true, the actual bitmap pixels are not loaded in the memory. Just the bounds are loaded. If 
//  you try the use the bitmap here, you will get null. 
     options.inJustDecodeBounds = true; 
     Bitmap bmp = BitmapFactory.decodeFile(filePath, options); 

     int actualHeight = options.outHeight; 
     int actualWidth = options.outWidth; 

//  max Height and width values of the compressed image is taken as 816x612 

     float maxHeight = 816.0f; 
     float maxWidth = 612.0f; 
     float imgRatio = actualWidth/actualHeight; 
     float maxRatio = maxWidth/maxHeight; 

//  width and height values are set maintaining the aspect ratio of the image 

     if (actualHeight > maxHeight || actualWidth > maxWidth) { 
      if (imgRatio < maxRatio) { 
       imgRatio = maxHeight/actualHeight; 
       actualWidth = (int) (imgRatio * actualWidth); 
       actualHeight = (int) maxHeight; 
      } else if (imgRatio > maxRatio) { 
       imgRatio = maxWidth/actualWidth; 
       actualHeight = (int) (imgRatio * actualHeight); 
       actualWidth = (int) maxWidth; 
      } else { 
       actualHeight = (int) maxHeight; 
       actualWidth = (int) maxWidth; 

      } 
     } 

//  setting inSampleSize value allows to load a scaled down version of the original image 

     options.inSampleSize = calculateInSampleSize(options, actualWidth, actualHeight); 

//  inJustDecodeBounds set to false to load the actual bitmap 
     options.inJustDecodeBounds = false; 

//  this options allow android to claim the bitmap memory if it runs low on memory 
     options.inPurgeable = true; 
     options.inInputShareable = true; 
     options.inTempStorage = new byte[16 * 1024]; 

     try { 
//   load the bitmap from its path 
      bmp = BitmapFactory.decodeFile(filePath, options); 
     } catch (OutOfMemoryError exception) { 
      exception.printStackTrace(); 

     } 
     try { 
      scaledBitmap = Bitmap.createBitmap(actualWidth, actualHeight, Bitmap.Config.ARGB_8888); 
     } catch (OutOfMemoryError exception) { 
      exception.printStackTrace(); 
     } 

     float ratioX = actualWidth/(float) options.outWidth; 
     float ratioY = actualHeight/(float) options.outHeight; 
     float middleX = actualWidth/2.0f; 
     float middleY = actualHeight/2.0f; 

     Matrix scaleMatrix = new Matrix(); 
     scaleMatrix.setScale(ratioX, ratioY, middleX, middleY); 

     Canvas canvas = new Canvas(scaledBitmap); 
     canvas.setMatrix(scaleMatrix); 
     canvas.drawBitmap(bmp, middleX - bmp.getWidth()/2, middleY - bmp.getHeight()/2, new Paint(Paint.FILTER_BITMAP_FLAG)); 

//  check the rotation of the image and display it properly 
     ExifInterface exif; 
     try { 
      exif = new ExifInterface(filePath); 

      int orientation = exif.getAttributeInt(
        ExifInterface.TAG_ORIENTATION, 0); 
      Log.d("EXIF", "Exif: " + orientation); 
      Matrix matrix = new Matrix(); 
      if (orientation == 6) { 
       matrix.postRotate(90); 
       Log.d("EXIF", "Exif: " + orientation); 
      } else if (orientation == 3) { 
       matrix.postRotate(180); 
       Log.d("EXIF", "Exif: " + orientation); 
      } else if (orientation == 8) { 
       matrix.postRotate(270); 
       Log.d("EXIF", "Exif: " + orientation); 
      } 
      scaledBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0, 
        scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix, 
        true); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

     FileOutputStream out = null; 
     String filename = getFilename(); 
     try { 
      out = new FileOutputStream(filename); 

//   write the compressed bitmap at the destination specified by filename. 
      scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 80, out); 

     } catch (FileNotFoundException e) { 
      e.printStackTrace(); 
     } 

     return filename; 

    } 

    public String getFilename() { 
     File file = new File(Environment.getExternalStorageDirectory().getPath(), "MyFolder/Images"); 
     if (!file.exists()) { 
      file.mkdirs(); 
     } 
     String uriSting = (file.getAbsolutePath() + "/" + System.currentTimeMillis() + ".jpg"); 
     return uriSting; 

    } 

    private String getRealPathFromURI(String contentURI) { 
     Uri contentUri = Uri.parse(contentURI); 
     Cursor cursor = getContentResolver().query(contentUri, null, null, null, null); 
     if (cursor == null) { 
      return contentUri.getPath(); 
     } else { 
      cursor.moveToFirst(); 
      int index = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA); 
      return cursor.getString(index); 
     } 
    } 

    public int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { 
     final int height = options.outHeight; 
     final int width = options.outWidth; 
     int inSampleSize = 1; 

     if (height > reqHeight || width > reqWidth) { 
      final int heightRatio = Math.round((float) height/(float) reqHeight); 
      final int widthRatio = Math.round((float) width/(float) reqWidth); 
      inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio; 
     } 
     final float totalPixels = width * height; 
     final float totalReqPixelsCap = reqWidth * reqHeight * 2; 
     while (totalPixels/(inSampleSize * inSampleSize) > totalReqPixelsCap) { 
      inSampleSize++; 
     } 

     return inSampleSize; 
    } 
+0

@Jitty Aandyan Come reagirà il tuo codice se le dimensioni e le dimensioni delle immagini sono troppo piccole o troppo grandi ... E perché 816x612 è hard coded possiamo calcolarlo in modo programmatico – Akshay

+1

in pratica il codice sopra è usato per ridurre la dimensione delle immagini mantenendo le proporzioni. la cosa più importante è che ogni immagine dovrebbe avere un'altezza e una larghezza particolari che sono definite dai requisiti della tua app. se si utilizzano immagini di alta qualità per la foto del profilo, è possibile modificare l'altezza massima della larghezza massima a 300, quindi il rispetto per la propria implementazione. Inoltre, puoi controllare l'altezza e la larghezza effettive prima di comprimere se è maggiore del tuo requisito puoi eseguire la compressione. –

+0

Come renderlo dinamico per tutte le dimensioni delle immagini e per tutti i dispositivi con diversa risoluzione ,, – Akshay

0

Crea classe Per CompressFile Immagine

public class CompressFile { 
    public static File getCompressedImageFile(File file, Context mContext) { 
     try { 
      BitmapFactory.Options o = new BitmapFactory.Options(); 
      o.inJustDecodeBounds = true; 

      if (getFileExt(file.getName()).equals("png") || getFileExt(file.getName()).equals("PNG")) { 
       o.inSampleSize = 6; 
      } else { 
       o.inSampleSize = 6; 
      } 

      FileInputStream inputStream = new FileInputStream(file); 
      BitmapFactory.decodeStream(inputStream, null, o); 
      inputStream.close(); 

      // The new size we want to scale to 
      final int REQUIRED_SIZE = 100; 

      // Find the correct scale value. It should be the power of 2. 
      int scale = 1; 
      while (o.outWidth/scale/2 >= REQUIRED_SIZE && 
        o.outHeight/scale/2 >= REQUIRED_SIZE) { 
       scale *= 2; 
      } 

      BitmapFactory.Options o2 = new BitmapFactory.Options(); 
      o2.inSampleSize = scale; 
      inputStream = new FileInputStream(file); 

      Bitmap selectedBitmap = BitmapFactory.decodeStream(inputStream, null, o2); 

      ExifInterface ei = new ExifInterface(file.getAbsolutePath()); 
      int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION, 
        ExifInterface.ORIENTATION_UNDEFINED); 

      switch (orientation) { 

       case ExifInterface.ORIENTATION_ROTATE_90: 
        rotateImage(selectedBitmap, 90); 
        break; 

       case ExifInterface.ORIENTATION_ROTATE_180: 
        rotateImage(selectedBitmap, 180); 
        break; 

       case ExifInterface.ORIENTATION_ROTATE_270: 
        rotateImage(selectedBitmap, 270); 
        break; 

       case ExifInterface.ORIENTATION_NORMAL: 

       default: 
        break; 
      } 
      inputStream.close(); 


      // here i override the original image file 
      File folder = new File(Environment.getExternalStorageDirectory() + "/FolderName"); 
      boolean success = true; 
      if (!folder.exists()) { 
       success = folder.mkdir(); 
      } 
      if (success) { 
       File newFile = new File(new File(folder.getAbsolutePath()), file.getName()); 
       if (newFile.exists()) { 
        newFile.delete(); 
       } 
       FileOutputStream outputStream = new FileOutputStream(newFile); 

       if (getFileExt(file.getName()).equals("png") || getFileExt(file.getName()).equals("PNG")) { 
        selectedBitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream); 
       } else { 
        selectedBitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream); 
       } 

       return newFile; 
      } else { 
       return null; 
      } 
     } catch (Exception e) { 
      return null; 
     } 
    } 

    public static String getFileExt(String fileName) { 
     return fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length()); 
    } 

    public static Bitmap rotateImage(Bitmap source, float angle) { 
     Matrix matrix = new Matrix(); 
     matrix.postRotate(angle); 
     return Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), 
       matrix, true); 
    } 
} 
Problemi correlati