安卓:调整图片大小会导致应用崩溃



我有以下一段代码,应该在从相机捕获图像后调整图像大小。 每次它到达createScaledBitmap部分时,它都会强制关闭应用程序。 不确定这条信息是否重要,但这个应用程序是用网络视图完成的。

private Bitmap resize(String path){
    // create the options
        BitmapFactory.Options opts = new BitmapFactory.Options();
    //just decode the file
        opts.inJustDecodeBounds = true;
        Bitmap bp = BitmapFactory.decodeFile(path, opts);
        //get the original size
        int originalHeight = opts.outHeight;
        int originalWidth = opts.outWidth;
        int x = 0, y = 0;
        if(originalHeight > originalWidth){
            if(originalHeight > 1024){
                x = originalHeight / 2;
                y = originalWidth / 2;
            }   
        }
        else if(originalWidth > originalHeight){
            if(originalWidth > 1024){
                x = originalHeight / 2;
                y = originalWidth / 2;
            }
        }
        Bitmap resized = Bitmap.createScaledBitmap(bp, y, x, false);
        bp = resized;
        opts.inJustDecodeBounds = false;
        bp = BitmapFactory.decodeFile(path,opts);
        return bp;

这是崩溃发生时 logCat 输出的内容。

01-08 09:05:39.888: E/AndroidRuntime(2292): FATAL EXCEPTION: main
01-08 09:05:39.888: E/AndroidRuntime(2292): java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1, result=-1, data=null} to activity {mobile311.mobile311webapp/mobile311.mobile311webapp.MainActivity}: java.lang.NullPointerException
01-08 09:05:39.888: E/AndroidRuntime(2292):     at android.app.ActivityThread.deliverResults(ActivityThread.java:2536)
01-08 09:05:39.888: E/AndroidRuntime(2292):     at android.app.ActivityThread.handleSendResult(ActivityThread.java:2578)
01-08 09:05:39.888: E/AndroidRuntime(2292):     at android.app.ActivityThread.access$2000(ActivityThread.java:117)
01-08 09:05:39.888: E/AndroidRuntime(2292):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:965)
01-08 09:05:39.888: E/AndroidRuntime(2292):     at android.os.Handler.dispatchMessage(Handler.java:99)
01-08 09:05:39.888: E/AndroidRuntime(2292):     at android.os.Looper.loop(Looper.java:130)
01-08 09:05:39.888: E/AndroidRuntime(2292):     at android.app.ActivityThread.main(ActivityThread.java:3687)
01-08 09:05:39.888: E/AndroidRuntime(2292):     at java.lang.reflect.Method.invokeNative(Native Method)
01-08 09:05:39.888: E/AndroidRuntime(2292):     at java.lang.reflect.Method.invoke(Method.java:507)
01-08 09:05:39.888: E/AndroidRuntime(2292):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:842)
01-08 09:05:39.888: E/AndroidRuntime(2292):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
01-08 09:05:39.888: E/AndroidRuntime(2292):     at dalvik.system.NativeStart.main(Native Method)
01-08 09:05:39.888: E/AndroidRuntime(2292): Caused by: java.lang.NullPointerException
01-08 09:05:39.888: E/AndroidRuntime(2292):     at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:344)
01-08 09:05:39.888: E/AndroidRuntime(2292):     at mobile311.mobile311webapp.MainActivity.resize(MainActivity.java:173)
01-08 09:05:39.888: E/AndroidRuntime(2292):     at mobile311.mobile311webapp.MainActivity.onActivityResult(MainActivity.java:56)
01-08 09:05:39.888: E/AndroidRuntime(2292):     at android.app.Activity.dispatchActivityResult(Activity.java:3908)
01-08 09:05:39.888: E/AndroidRuntime(2292):     at android.app.ActivityThread.deliverResults(ActivityThread.java:2532)
01-08 09:05:39.888: E/AndroidRuntime(2292):     ... 11 more

任何帮助将不胜感激,以解决我遇到的问题。

bmp 为空。这意味着您的BitmapFactory.decodeFile()返回 null。确保您输入的文件路径是实际有效的文件路径。 如果无法解码文件,BitmapFactory.decodeFile()返回 null,因此如果此文件不存在,则无法对其进行解码(这是最常见的原因)。

查看源代码(2.3 rev1)。 bp为 null,表示 BitmapFactory.decodeFile(path, opts); 返回的 null

public static Bitmap decodeFile (String pathName, BitmapFactory.Options opts)
Added in API level 1
Decode a file path into a bitmap. If the specified file name is null, or cannot be decoded into a bitmap, the function returns null.
Parameters
pathName    complete path name for the file to be decoded.
opts    null-ok; Options that control downsampling and whether the image should be completely decoded, or just is size returned.
Returns
The decoded bitmap, or null if the image data could not be decoded, or, if opts is non-null, if opts requested only the size be returned (in opts.outWidth and opts.outHeight)

http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.3_r1/android/graphics/Bitmap.java/

Caused by: java.lang.NullPointerException
at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:344)

331     public static Bitmap createScaledBitmap(Bitmap src, int dstWidth,
332             int dstHeight, boolean filter) {
333         Matrix m;
334         synchronized (Bitmap.class) {
335             // small pool of just 1 matrix
336             m = sScaleMatrix;
337             sScaleMatrix = null;
338         }
339 
340         if (m == null) {
341             m = new Matrix();
342         }
343 
344         final int width = src.getWidth(); // src is the Bitmap

当您将inJustDecodeBounds标志设置为true Options时,BitmapFactory.decodeFile()返回null,这可能会对您有所帮助...

private Bitmap resize(String path) {
    // create the options
    BitmapFactory.Options opts = new BitmapFactory.Options();
    // just decode the file
    opts.inJustDecodeBounds = true;
    Bitmap bp = BitmapFactory.decodeFile(path, opts);
    // get the original size
    int originalHeight = opts.outHeight;
    int originalWidth = opts.outWidth;
    int x = 0, y = 0;
    if (originalHeight > originalWidth) {
        if (originalHeight > 1024) {
            x = originalHeight / 2;
            y = originalWidth / 2;
        }
    } else if (originalWidth > originalHeight) {
        if (originalWidth > 1024) {
            x = originalHeight / 2;
            y = originalWidth / 2;
        }
    }
    opts.inJustDecodeBounds = false;
    opts.inSampleSize = calculateInSampleSize(originalWidth, originalHeight, x, y);
    Bitmap bitmap = BitmapFactory.decodeFile(path, opts);
    return bitmap;
}
public static int calculateInSampleSize(int width, int height,
        int reqWidth, int reqHeight) {
    // Raw height and width of image
    int inSampleSize = 1;
    if (height > reqHeight || width > reqWidth) {
        final int halfHeight = height / 2;
        final int halfWidth = width / 2;
        while ((halfHeight / inSampleSize) > reqHeight
                && (halfWidth / inSampleSize) > reqWidth) {
            inSampleSize *= 2;
        }
    }
    return inSampleSize;
}

确保您的文件路径有效...

我非常感谢 http://developer.android.com/training/displaying-bitmaps/load-bitmap.html

所以这是我最终得到的代码,让一切正常工作。 我还在调整大小的图像中添加了时间/日期戳。

private Bitmap resize(String path) throws IOException{
    // create the options
        BitmapFactory.Options opts = new BitmapFactory.Options();
    //just decode the file
        opts.inJustDecodeBounds = false;
        System.out.print(path);
        //uses the file path to 
        Bitmap bp = BitmapFactory.decodeFile(path, opts);
        //get the original size
        double height = opts.outHeight;
        double width = opts.outWidth;
        //checks orientation of the image and decreases the size of the dimensions
        while(width > 1280 || height > 1024){
            width = width * .9;
            height = height * .9;
        }
        //creates the new scaled bitmap image
        Bitmap resized = Bitmap.createScaledBitmap(bp, (int)width, (int)height, true);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
        String dateTime = sdf.format(Calendar.getInstance().getTime()); // reading local time in the system 
        Canvas cs = new Canvas(resized); //used for drawing on a bitmap
        Paint tPaint = new Paint(); //object that we're adding to the bitmap
        tPaint.setTextSize(35); 
        tPaint.setColor(Color.BLUE); 
        tPaint.setStyle(Style.FILL); 
        cs.drawBitmap(resized, 0f, 0f, null); //place the original image in our bitmap
        float height1 = tPaint.measureText("yY"); //get an offset based on textsize
        cs.drawText(dateTime, 20f, height1+15f, tPaint); //place the text on the canvas
        //outputs the new bitmap image to the sd card for upload later
        OutputStream fOut = null;
        resizedUrl = sdCardRoot + File.separator + "IMG_" + String.valueOf(System.currentTimeMillis()) + ".jpg";
        saveImg = new File(resizedUrl);
        fOut = new FileOutputStream(saveImg);
        resized.compress(Bitmap.CompressFormat.JPEG, 100, fOut);
        fOut.close();
        return resized;
    }

最新更新