按比例调整位图大小

5

我有一个位图...如果位图的高度大于maxHeight,或者宽度大于maxWidth,我想等比例缩放图像,使其适合于 maxWidth X maxHeight。这是我的尝试:

    BitmapDrawable bmp = new BitmapDrawable(getResources(), PHOTO_PATH);

    int width = bmp.getIntrinsicWidth();
    int height = bmp.getIntrinsicHeight();

    float ratio = (float)width/(float)height;

    float scaleWidth = width;
    float scaleHeight = height;

    if((float)mMaxWidth/(float)mMaxHeight > ratio) {
        scaleWidth = (float)mMaxHeight * ratio;
    }
    else {
        scaleHeight = (float)mMaxWidth / ratio;
    }

    Matrix matrix = new Matrix();
    matrix.postScale(scaleWidth, scaleHeight);

    Bitmap out = Bitmap.createBitmap(bmp.getBitmap(), 
            0, 0, width, height, matrix, true);

    try {
        out.compress(Bitmap.CompressFormat.JPEG, 100, 
                new FileOutputStream(PHOTO_PATH));
    }
    catch(FileNotFoundException fnfe) {
        fnfe.printStackTrace();
    }

我遇到了以下异常:

java.lang.IllegalArgumentException: bitmap size exceeds 32bits

我在这里做错了什么?


你能把修正后的代码粘贴在这里吗?我还是得到同样的异常。 - Mahesh
3个回答

8
你的scaleWidth和scaleHeight应该是比例因子(不是非常大的数字),但你的代码似乎传递了实际的宽度和高度。所以你最终会大幅增加位图的大小。
我认为代码中还存在其他问题,用于推导scaleWidth和scaleHeight。首先,你的代码总是有一个scaleWidth = widthscaleHeight = height,并且只更改其中一个,因此你也会扭曲图像的长宽比。如果你只想调整图像大小,那么你应该只有一个scaleFactor
另外,为什么你的if语句要检查实际上的maxRatio > ratio?难道不应该检查width > maxWidthheight > maxHeight吗?

1

这是我做的方法:

public Bitmap decodeAbtoBm(byte[] b){
    Bitmap bm; // prepare object to return

    // clear system and runtime of rubbish
    System.gc();
    Runtime.getRuntime().gc();  

    //Decode image size only
    BitmapFactory.Options oo = new BitmapFactory.Options();
    // only decodes size, not the whole image
    // See Android documentation for more info.
    oo.inJustDecodeBounds = true;
    BitmapFactory.decodeByteArray(b, 0, b.length ,oo);

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

    // Important function to resize proportionally.
    //Find the correct scale value. It should be the power of 2.
    int scale=1;
    while(oo.outWidth/scale/2>=REQUIRED_SIZE
            && oo.outHeight/scale/2>=REQUIRED_SIZE)
            scale*=2; // Actual scaler

    //Decode Options: byte array image with inSampleSize
    BitmapFactory.Options o2 = new BitmapFactory.Options();
    o2.inSampleSize=scale; // set scaler
    o2.inPurgeable = true; // for effeciency
    o2.inInputShareable = true;

    // Do actual decoding, this takes up resources and could crash
    // your app if you do not do it properly
    bm = BitmapFactory.decodeByteArray(b, 0, b.length,o2);

    // Just to be safe, clear system and runtime of rubbish again!
    System.gc();
    Runtime.getRuntime().gc();

    return bm; // return Bitmap to the method that called it
}

1
这是因为scaleWidthscaleHeight的值太大了,scaleWidthscaleHeight是指放大或缩小的比例,而不是widthheight,过大的比例会导致bitmap大小超过32位。
matrix.postScale(scaleWidth, scaleHeight);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接