从Uri打开图像,调整大小并返回Base64

时间:2012-11-13 23:21:40

标签: android image resize base64 uri

我尝试从特定的uri打开图像,检查此图像是否太大而无法调整大小,并将其作为Base64返回。我的问题是我必须重新调整图像的代码从不调整图像大小(从不表示图像太大)。我找了类似的其他问题,但我没有得到任何答案。 我不知道为什么总是在这两个代码行中值为-1:

        final int height = options.outHeight; // Always -1 WHY?
    final int width = options.outWidth; // Always -1 WHY?

我附上我的代码:

private class WriteImage extends AsyncTask<Object, Void, String>{
            private static Bitmap decodeSampledBitmapFromStream(InputStream is,
                                                    int reqWidth,
                                                    int reqHeight) {

    // First decode with inJustDecodeBounds=true to check dimensions
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    InputStream aux = inputStreamCopy(is);
    BitmapFactory.decodeStream(is, null, options);  // SkImageDecoder::Factory returned null
    try {
        is.close();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;
    return BitmapFactory.decodeStream(aux, null, options);
}

private static InputStream inputStreamCopy(InputStream is) {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    int len;
    byte[] buffer = new byte[1024];

    try {
        while ((len = is.read(buffer)) > -1) baos.write(buffer, 0, len);
    } catch (IOException e) {
        e.printStackTrace();
    }
    return new ByteArrayInputStream(baos.toByteArray());
}

private static int calculateInSampleSize(
        BitmapFactory.Options options, int reqWidth, int reqHeight) {
    // Raw height and width of image
    final int height = options.outHeight; // Always -1 WHY?
    final int width = options.outWidth; // Always -1 WHY?
    int inSampleSize = 1;

    if (height > reqHeight || width > reqWidth) {
        if (width > height)
            inSampleSize = Math.round((float)height / (float)reqHeight);
        else
            inSampleSize = Math.round((float)width / (float)reqWidth);

        // This offers some additional logic in case the image has a strange
        // aspect ratio. For example, a panorama may have a much larger
        // width than height. In these cases the total pixels might still
        // end up being too large to fit comfortably in memory, so we should
        // be more aggressive with sample down the image (=larger
        // inSampleSize).
        final float totalPixels = width * height;

        // Anything more than 2x the requested pixels we'll sample down
        // further.
        final float totalReqPixelsCap = reqWidth * reqHeight * 2;

        while (totalPixels / (inSampleSize * inSampleSize) > totalReqPixelsCap)
            inSampleSize++;
    }
    for (int i=5; i>0; i--){
        if (Math.pow(2, i)<=inSampleSize){
            inSampleSize = (int) Math.pow(2, i);
            break;
        }
    }
    return inSampleSize;
}


    @Override
    protected void onPreExecute(){  
    }

    @Override
    protected void onProgressUpdate(Void... values){
    }

    @Override
    protected String doInBackground(Object... params) {
        try {
            InputStream is = ((android.app.Activity) params[1]).getContentResolver().openInputStream((Uri) params[0]);

            Bitmap bitmap = decodeSampledBitmapFromStream(is, 300, 300);
            int bytes = bitmap.getWidth()*bitmap.getHeight()*4;
            ByteBuffer buffer = ByteBuffer.allocate(bytes);
            bitmap.copyPixelsToBuffer(buffer);
            return Base64.encodeToString(buffer.array(), Base64.DEFAULT);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onPostExecute(String result){
    }
}

1 个答案:

答案 0 :(得分:0)

解决方案就是这个!替换以下内容:

decodeSampledBitmapFromStream 功能中:

    private Bitmap decodeSampledBitmapFromStream(InputStream is,
                                                    int reqWidth,
                                                    int reqHeight) {

    // First decode with inJustDecodeBounds=true to check dimensions
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;

    InputStream aux = inputStreamCopy(is);
    BitmapFactory.decodeStream(aux, null, options);  // SkImageDecoder::Factory returned null
    try {
        aux.reset();
    } catch (IOException e) {
        e.printStackTrace();
    }

    // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;
    return BitmapFactory.decodeStream(aux, null, options);
}

doInBackground 方法中:

        @Override
    protected String doInBackground(Object... params) {
        try {
            InputStream is = ((android.app.Activity) params[1]).getContentResolver().openInputStream((Uri) params[0]);
            Bitmap bitmap = decodeSampledBitmapFromStream(is, 300, 300);
            System.gc();
            int bytes = bitmap.getWidth()*bitmap.getHeight()*2;
            ByteBuffer buffer = ByteBuffer.allocate(bytes);
            bitmap.copyPixelsToBuffer(buffer);
            return Base64.encodeToString(buffer.array(), Base64.DEFAULT);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

:)