从FilePath转换为字节数组时的OutOfMemory

时间:2016-09-17 09:13:47

标签: android image

我有一个代码来在将数据上传到服务器之前调整Image的大小。但有时它会抛出错误。我认为这是由属性options.inSampleSize = 2引起的。那么,我该如何解决问题呢?

public byte[] resizeImage(String filePath) {
    BitmapFactory.Options options = new BitmapFactory.Options();
    options.outWidth = 50; // pixels
    options.outHeight = 50; // pixels
    options.inSampleSize = 2;
    File file = new File(filePath);
    FileInputStream in = null; // here, you need to get your context.
    try {
        in = new FileInputStream(file);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }
    Bitmap bitmap = BitmapFactory.decodeStream(in, null, options);
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    bitmap.compress(Bitmap.CompressFormat.JPEG, 50, baos);
    byte[] bitmapdata = baos.toByteArray();
    return bitmapdata;
}

1 个答案:

答案 0 :(得分:0)

您需要修改此类代码,它将返回压缩图像路径

public static String compressImage(String imageUri) {

        String filePath = 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;*/
        int actualHeight;
        int actualWidth;
        if (options.outHeight < 1000 || options.outWidth < 800) {
            actualHeight = options.outHeight;
            actualWidth = options.outWidth;
        } else {
            actualHeight = 1000;
            actualWidth = 800;
        }

       /* int actualHeight = 1000;
        int actualWidth = 800;*/

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

        float maxHeight = 1600.0f;
        float maxWidth = 2100.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);
        options.inSampleSize = calculateInSampleSize(options, actualWidth, actualWidth);

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

        if (scaledBitmap != null)
            scaledBitmap.recycle();
        if (bmp != null)
            bmp.recycle();
        return filename;

    }

此方法用于调整图像大小

public Bitmap resizeBitmap(String photoPath, int targetW, int targetH) {
    BitmapFactory.Options bmOptions = new BitmapFactory.Options();
    bmOptions.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(photoPath, bmOptions);
    int photoW = bmOptions.outWidth;
    int photoH = bmOptions.outHeight;

    int scaleFactor = 1;
    if ((targetW > 0) || (targetH > 0)) {
            scaleFactor = Math.min(photoW/targetW, photoH/targetH);        
    }

    bmOptions.inJustDecodeBounds = false;
    bmOptions.inSampleSize = scaleFactor;
    bmOptions.inPurgeable = true; //Deprecated API 21

    return BitmapFactory.decodeFile(photoPath, bmOptions);            
}