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

时间:2014-01-08 14:26:40

标签: android image-processing android-webview

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

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

在解决我遇到的问题时,我们将非常感谢任何帮助。

4 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

查看源代码(2.3 rev1)。 bp为空,表示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

答案 2 :(得分:0)

当您为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

答案 3 :(得分:0)

所以这就是我最终得到的一切代码。我还为调整大小的图像添加了时间/日期戳。

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