【问题标题】:Android Bitmap compress from gallery cause OutOfMemoryError in Xiomi phonesAndroid Bitmap 从图库中压缩导致小米手机出现 OutOfMemoryError
【发布时间】:2015-09-16 04:57:22
【问题描述】:

以下代码给出OutOfMemoryError,而仅在小米、华硕Zenfone2和三星S5设备上执行压缩方法。

  Bitmap bm = BitmapFactory.decodeFile(<sd_card_path_here>);
  bm.compress(Bitmap.CompressFormat.JPEG, 20, out);

目标 sd 卡路径有一个用 0 字节创建的文件

非常感谢任何帮助,并在此先感谢。

【问题讨论】:

  • 我用的是小米mi3,我试过这个,没有outOfMemoryError。你想知道你到底在做什么吗?

标签: android bitmap out-of-memory android-imageview


【解决方案1】:

您应该有效地阅读加载位图,以便基本了解您可能遇到 OutOfMemory 异常的原因。 此外,处理位图应该在 UI 线程之外完成,以避免 ANR 错误。

参考: http://developer.android.com/training/displaying-bitmaps/load-bitmap.html#load-bitmap

【讨论】:

    【解决方案2】:

    位图的宽度/高度是多少?

    Android 的 OpenGL 版本限制每个位图为 4096*4096 像素(65 兆字节未压缩图像)

    您也可以尝试在 AndroidManifest.xml 中增加应用程序内存

     <application ...
        android:largeHeap="true"..></application>
    

    如果这没有帮助,您必须按照http://developer.android.com/training/displaying-bitmaps/load-bitmap.html#load-bitmap 中所述缩小图像

    【讨论】:

      【解决方案3】:

      我从这里得到了有效的答案:

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

      参考链接:LINK

      【讨论】:

        猜你喜欢
        • 2021-07-18
        • 1970-01-01
        • 2014-09-07
        • 1970-01-01
        • 1970-01-01
        • 2013-05-01
        • 2014-05-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多