【问题标题】:Image compression like Whatsapp and other messengers on Android图像压缩,如 Whatsapp 和 Android 上的其他信使
【发布时间】:2014-11-14 11:06:24
【问题描述】:

我正在使用以下代码进行图像压缩。

代码压缩大于 2 MB 的图像文件。

但此代码需要时间,而且图像质量保持纯净。

public static String compressImage(String imagePath, Context context)
    {
        String resizeImagePath = null;
        String filePath = imagePath;
        CustomLogHandler.printDebug(TAG, "resizeImagePath:" + imagePath);
        Bitmap scaledBitmap = null;
        int imageScal = 1;

        // File size greater then 2mb
        DecimalFormat df = new DecimalFormat("0.00");
        File imgFile = new File(filePath);
        double bytes = imgFile.length();
        double kilobytes = (bytes / 1024);
        double megabytes = (kilobytes / 1024);

        AppConfig.makeLog(TAG, "image size in mb:" + df.format(megabytes), 0);

        double filesize = Double.parseDouble(df.format(megabytes));
        if (filesize > 2.00f)
        {

            for (int i = 0; i < filesize; i = i + 2)
            {

                imageScal++;
            }
            int remind = imageScal / 2;
            if (remind != 0)
            {
                imageScal = imageScal + 1;
            }

            makeLog(TAG, "image scale:" + imageScal, 0);

            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;
            Bitmap bmp = BitmapFactory.decodeFile(filePath, options);

            int actualHeight = options.outHeight;
            int actualWidth = options.outWidth;
            float maxHeight = 4000;
            float maxWidth = 6000;
            // float imgRatio = actualWidth / actualHeight;
            // float maxRatio = maxWidth / maxHeight;

            if (actualHeight > maxHeight)
            {
                imageScal = imageScal + 4;
            }

            if (actualWidth > maxWidth)
            {
                imageScal = imageScal + 8;
            }

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

            // options.inSampleSize = utils.calculateInSampleSize(options, actualWidth, actualHeight);
            options.inSampleSize = imageScal;
            options.inJustDecodeBounds = false;
            options.inDither = true;
            options.inPurgeable = true;
            options.inInputShareable = true;
            options.inTempStorage = new byte[16 * 1024];

            try
            {
                bmp = BitmapFactory.decodeFile(filePath, options);
                bmp = decodeFile(filePath);
            }
            catch (OutOfMemoryError exception)
            {
                exception.printStackTrace();

            }
            boolean done = false;

            while (!done)
            {
                try
                {
                    scaledBitmap = Bitmap.createBitmap(actualWidth, actualHeight, Bitmap.Config.ARGB_8888);

                    // scaledBitmap = Bitmap.createBitmap(actualWidth, actualHeight, Bitmap.Config.ARGB_8888);

                    done = true;
                }
                catch (OutOfMemoryError exception)
                {
                    // 15923 × 1790
                    // 5616 × 3744
                    // 8150 × 9154
                    actualWidth = actualWidth - ((actualWidth * 2) / 100);
                    actualHeight = actualHeight - ((actualHeight * 2) / 100);
                    // scaledBitmap = Bitmap.createBitmap(5616, 3744, Bitmap.Config.ARGB_8888);
                    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));

            // Resize image stored in sdcard
            FileOutputStream out = null;
            // filename =AppConfig.fileTosaveMedia(context, FileType.IMAGE, true).getAbsolutePath();
            int compress = 50;
            try
            {
                do
                {
                    imgFile = AppConfig.fileTosaveMedia(context, FileType.IMAGE, true);
                    out = new FileOutputStream(imgFile);
                    scaledBitmap.compress(Bitmap.CompressFormat.JPEG, compress, out);

                    resizeImagePath = imgFile.getAbsolutePath();

                    // Thread.sleep(15000);
                    // imgFile = new File(filename);
                    bytes = imgFile.length();
                    kilobytes = (bytes / 1024);
                    megabytes = (kilobytes / 1024);
                    System.out.println("resized image size in mb:" + df.format(megabytes));

                    filesize = Double.parseDouble(df.format(megabytes));
                    if (filesize > 2.00f)
                    {
                        compress = 30;
                    }
                } while (filesize > 2.00f);
                scaledBitmap.recycle();
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }
        else
        {

            FileOutputStream out = null;
            // FileInputStream in = null;
            imgFile = AppConfig.fileTosaveMedia(context, FileType.IMAGE, true);
            resizeImagePath = imgFile.getAbsolutePath();
            InputStream in = null;
            OutputStream outTemp = null;
            try
            {

                // create output directory if it doesn't exist

                in = new FileInputStream(filePath);
                outTemp = new FileOutputStream(resizeImagePath);

                byte[] buffer = new byte[1024];
                int read;
                while ((read = in.read(buffer)) != -1)
                {
                    outTemp.write(buffer, 0, read);
                }
                in.close();
                in = null;

                // write the output file (You have now copied the file)
                outTemp.flush();
                outTemp.close();
                outTemp = null;

            }
            catch (FileNotFoundException fnfe1)
            {
                Log.e("tag", fnfe1.getMessage());
            }
            catch (Exception e)
            {
                Log.e("tag", e.getMessage());
            }

            // try
            // {
            // Bitmap bmp = decodeFile(filePath);
            // // in = new FileInputStream(new File(imagePath));
            // // persistImage(bitmap, name);
            // out = new FileOutputStream(resizeImagePath);
            // bmp.compress(Bitmap.CompressFormat.JPEG, 100, out);
            // out.flush();
            // out.close();
            // // FileIO.copyStream(in, out);
            // }
            // catch (Exception e)
            // {
            // e.printStackTrace();
            // }
        }
        CustomLogHandler.printDebug(TAG, "resizeImagePath:" + resizeImagePath);
        return resizeImagePath;
    }

我花了很多时间在 Google 搜索和阅读博客上。然后在创建上面的代码之后,我找到了this。

上面的代码正确吗?或者有没有其他库可以用来压缩图片?

请帮帮我。

【问题讨论】:

    标签: android compression


    【解决方案1】:

    试试下面的代码:-

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

    有关信息,请参阅以下链接:-

    http://voidcanvas.com/whatsapp-like-image-compression-in-android/

    【讨论】:

    • 嗨 voidcanvas,我确实使用了你的代码,但它在我使用相机拍照的情况下不起作用,它只适用于画廊部分。错误并不清楚,因为它说:java.lang.RuntimeException:执行doInBackground()和com.ambalika.efficientimageloading.BitmapActivity$ImageCompressionAsyncTask.getRealPathFromURI(BitmapActivity.java:313)时发生错误...
    • @ombiro 没有让你正确
    • 您好,我目前正在使用您的代码,但遇到了一个小问题。给定的最大宽度和高度以像素为单位,因此当我从高分辨率手机单击图片并在压缩后将其传输到低分辨率时,图片会变得非常失真。
    • 我已经测试了来自 voidcanvas 的代码,真的很棒。很好。我用它把一张 3.82MB 的图片压缩到了 47.26KB。 @user3748230,我会建议你从上面给出的链接中查看完整的代码
    • @Senator。 Iv 运行相同的代码,但只能将 2.8MB 降低到大约 137KB。你的 maxWidth/maxLength 值是多少?
    【解决方案2】:

    希望对此有所帮助

      public static String compressImage(String filePath) {
    
    
        Bitmap scaledBitmap = null;
    
        BitmapFactory.Options options = new BitmapFactory.Options();
    
    
    
        options.inJustDecodeBounds = true;
    
        Bitmap bmp = BitmapFactory.decodeFile(filePath, options);
    
        int actualHeight = options.outHeight;
    
        int actualWidth = options.outWidth;
    
    
        float maxHeight = 400.0f;
        float maxWidth = 300.0f;
    
        float imgRatio = actualWidth / actualHeight;
    
        float maxRatio = maxWidth / maxHeight;
    
    
    
        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;
    
            }
        }
    
    
    
        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 static String getFilename() {
        File file = new File(Environment.getExternalStorageDirectory().getPath(), "Foldername/Images");
    
        if (!file.exists()) {
            file.mkdirs();
        }
        String uriSting = (file.getAbsolutePath() + "/" + System.currentTimeMillis() + ".jpg");
    
        return uriSting;
    
    }
    
    public static 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;
    }
    
    public static Bitmap highlightImage(Bitmap src) {
    
          // create new bitmap, which will be painted and becomes result image
    
          Bitmap bmOut = Bitmap.createBitmap(src.getWidth() + 96, src.getHeight() + 96, Bitmap.Config.ARGB_8888);
    
          // setup canvas for painting
    
          Canvas canvas = new Canvas(bmOut);
    
          // setup default color
    
          canvas.drawColor(0, PorterDuff.Mode.CLEAR);
    
          // create a blur paint for capturing alpha
    
          Paint ptBlur = new Paint();
    
          ptBlur.setMaskFilter(new BlurMaskFilter(15, Blur.NORMAL));
    
          int[] offsetXY = new int[2];
    
          // capture alpha into a bitmap
    
          Bitmap bmAlpha = src.extractAlpha(ptBlur, offsetXY);
    
          // create a color paint
          Paint ptAlphaColor = new Paint();
    
          ptAlphaColor.setColor(0xFFFFFFFF);
    
          // paint color for captured alpha region (bitmap)
    
          canvas.drawBitmap(bmAlpha, offsetXY[0], offsetXY[1], ptAlphaColor);
    
          // free memory
    
          bmAlpha.recycle();
    
          // paint the image source
          canvas.drawBitmap(src, 0, 0, null);
    
          // return out final image
          return bmOut;
         }
    

    【讨论】:

      【解决方案3】:

      试试这个代码

      private void previewCapturedImage() {
          try {
      
              int targetW = 450;
              int targetH = 450;
              Log.e("Get w", "width" + targetW);
              Log.e("Get H", "height" + targetH);
              // Get the dimensions of the bitmap
              BitmapFactory.Options bmOptions = new BitmapFactory.Options();
              bmOptions.inJustDecodeBounds = true;
              BitmapFactory.decodeFile(filename, bmOptions);
              int photoW = bmOptions.outWidth;
              int photoH = bmOptions.outHeight;
      
              // Determine how much to scale down the image
              int scaleFactor = Math.min(photoW / targetW, photoH / targetH);
      
              // Decode the image file into a Bitmap sized to fill the View
              bmOptions.inJustDecodeBounds = false;
              bmOptions.inSampleSize = scaleFactor << 1;
              bmOptions.inPurgeable = true;
              Bitmap bitmap = BitmapFactory.decodeFile(filename, bmOptions);
      
              Matrix mtx = new Matrix();
      
              try {
      
                  File imageFile = new File(filename);
                  imageFile1 = imageFile;
                  ExifInterface exif = new ExifInterface(
                          imageFile.getAbsolutePath());
                  int orientation = exif.getAttributeInt(
                          ExifInterface.TAG_ORIENTATION,
                          ExifInterface.ORIENTATION_NORMAL);
                  Log.e("Orintation", "  :-" + orientation);
                  switch (orientation) {
                  case ExifInterface.ORIENTATION_ROTATE_270:
      
                      mtx.postRotate(270);
                      rotatedBMP = Bitmap.createBitmap(bitmap, 0, 0,
                              bitmap.getWidth(), bitmap.getHeight(), mtx, true);
                      if (rotatedBMP != bitmap)
                          bitmap.recycle();
                      imgPreview.setImageBitmap(rotatedBMP);
                      break;
                  case ExifInterface.ORIENTATION_ROTATE_180:
      
                      mtx.postRotate(180);
                      rotatedBMP = Bitmap.createBitmap(bitmap, 0, 0,
                              bitmap.getWidth(), bitmap.getHeight(), mtx, true);
                      if (rotatedBMP != bitmap)
                          bitmap.recycle();
                      imgPreview.setImageBitmap(rotatedBMP);
                      break;
                  case ExifInterface.ORIENTATION_ROTATE_90:
      
                      mtx.postRotate(90);
                      rotatedBMP = Bitmap.createBitmap(bitmap, 0, 0,
                              bitmap.getWidth(), bitmap.getHeight(), mtx, true);
                      if (rotatedBMP != bitmap)
                          bitmap.recycle();
                      imgPreview.setImageBitmap(rotatedBMP);
                      break;
                  case ExifInterface.ORIENTATION_NORMAL:
      
                      mtx.postRotate(0);
                      rotatedBMP = Bitmap.createBitmap(bitmap, 0, 0,
                              bitmap.getWidth(), bitmap.getHeight(), mtx, true);
                      if (rotatedBMP != bitmap)
                          bitmap.recycle();
                      imgPreview.setImageBitmap(rotatedBMP);
                      break;
                  default:
                      mtx.postRotate(0);
                      rotatedBMP = Bitmap.createBitmap(bitmap, 0, 0,
                              bitmap.getWidth(), bitmap.getHeight(), mtx, true);
                      if (rotatedBMP != bitmap)
                          bitmap.recycle();
                      imgPreview.setImageBitmap(rotatedBMP);
                      // img_profilepic.setImageBitmap(BitmapFactory
                      // .decodeFile(mCurrentPhotoPath));
      
                  }
                  double megabytes = 0;
                  if (imageFile1.exists()) {
      
                      double bytes = imageFile1.length();
                      double kilobytes = (bytes / 1024);
                      megabytes = (kilobytes / 1024);
                      double gigabytes = (megabytes / 1024);
                      double terabytes = (gigabytes / 1024);
                      double petabytes = (terabytes / 1024);
                      double exabytes = (petabytes / 1024);
                      double zettabytes = (exabytes / 1024);
                      double yottabytes = (zettabytes / 1024);
                      Log.e("Image Size After in KB", "20th May:" + kilobytes);
                      Log.e("Image Size After in MB", "20th May:" + megabytes);
      
                  }
                  int AfterSize = rotatedBMP.getRowBytes()
                          * rotatedBMP.getHeight();
                  Log.e("After Compress Withd ",
                          "21st May ::" + rotatedBMP.getWidth());
                  Log.e("After Compress Withd ",
                          "21st May ::" + rotatedBMP.getWidth());
                  Log.i("RotateImage", "Exif orientation: " + orientation);
                  tv_After.setText("After Width:" + rotatedBMP.getWidth()
                          + " :Height:" + rotatedBMP.getHeight() + ":in MB :"
                          + megabytes + " :Bitmap: " + AfterSize);
              } catch (Exception e) {
                  e.printStackTrace();
              }
      
          } catch (NullPointerException e) {
              e.printStackTrace();
          }
      }
      

      也放这个方法。

      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++;
          }
          Log.e("In Sample Size..", "19th May :-" + inSampleSize);
          return inSampleSize;
      }
      

      【讨论】:

        【解决方案4】:

        我使用了最佳答案... 上述方法不起作用,它在某些小米手机中返回空路径,因为从 Uri 获取文件路径存在一些问题。 使用 getFilePath() 而不是 getRealPathFromURI()... 并将参数从 compressImage(String imageUri) 更改为 compressImage(Uri imageUri).

        private static String getFilePath(Context context, Uri uri) {
            String selection = null;
            String[] selectionArgs = null;
            // Uri is different in versions after KITKAT (Android 4.4), we need to
            if (Build.VERSION.SDK_INT >= 19 && DocumentsContract.isDocumentUri(context.getApplicationContext(), uri)) {
                if (isExternalStorageDocument(uri)) {
                    final String docId = DocumentsContract.getDocumentId(uri);
                    final String[] split = docId.split(":");
                    return Environment.getExternalStorageDirectory() + "/" + split[1];
                } else if (isDownloadsDocument(uri)) {
                    final String id = DocumentsContract.getDocumentId(uri);
                    uri = ContentUris.withAppendedId(
                            Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
                } else if (isMediaDocument(uri)) {
                    final String docId = DocumentsContract.getDocumentId(uri);
                    final String[] split = docId.split(":");
                    final String type = split[0];
                    if ("image".equals(type)) {
                        uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                    } else if ("video".equals(type)) {
                        uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                    } else if ("audio".equals(type)) {
                        uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                    }
                    selection = "_id=?";
                    selectionArgs = new String[]{
                            split[1]
                    };
                }
            }
            if ("content".equalsIgnoreCase(uri.getScheme())) {
                String[] projection = {
                        MediaStore.Images.Media.DATA
                };
                Cursor cursor = null;
                try {
                    cursor = context.getContentResolver()
                            .query(uri, projection, selection, selectionArgs, null);
                    int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
                    if (cursor.moveToFirst()) {
                        return cursor.getString(column_index);
                    }
                } catch (Exception e) {
                }
            } else if ("file".equalsIgnoreCase(uri.getScheme())) {
                return uri.getPath();
            }
            return null;
        }
        
        private static boolean isExternalStorageDocument(Uri uri) {
            return "com.android.externalstorage.documents".equals(uri.getAuthority());
        }
        
        private static boolean isDownloadsDocument(Uri uri) {
            return "com.android.providers.downloads.documents".equals(uri.getAuthority());
        }
        
        private static boolean isMediaDocument(Uri uri) {
            return "com.android.providers.media.documents".equals(uri.getAuthority());
        }
        

        【讨论】:

          【解决方案5】:

          我不了解 WhatsApp,但是通过阅读源代码,我设法了解了 Telegram 是如何做到这一点的,并且我在我的博客上发表了一篇关于他们如何逐步做到这一点的文章,你可以在这里找到 @ 987654321@.

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2016-04-12
            • 1970-01-01
            • 2016-08-22
            • 2017-12-11
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多