按比例调整位图大小

时间:2010-07-14 14:32:37

标签: android

我有一个位图...如果位图的高度大于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

我在这里做错了什么?

3 个答案:

答案 0 :(得分:8)

你的scaleWidth和scaleHeight应该是比例因子(所以不是很大的数字),但你的代码似乎传递了你正在寻找的实际宽度和高度。因此,您最终会大幅增加位图的大小。

我认为代码还有其他问题来导出scaleWidth和scaleHeight。首先,你的代码总是有 scaleWidth = width scaleHeight = height ,并且只改变其中一个,所以你会扭曲你的宽高比图像也是如此。如果您只想调整图像大小,那么您应该只有一个 scaleFactor

另外,为什么if语句会有效地检查 maxRatio> ?你不应该检查宽度> maxWidth height> maxHeight

答案 1 :(得分:1)

这是因为scaleWidthscaleHeight的值太大,scaleWidthscaleHeight意味着放大或缩小率,而不是{{1} }或width,过大的速率导致height大小超过32位

bitmap

答案 2 :(得分: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
}