将图像转换为位图并减小其大小

3
我研究了许多不同的方法来创建图像的缩小版本,但它们都不能正常工作/我需要一些不同的东西。
这有点难以解释:-)
我需要的是一个保持图片比例,但大小小于某个特定大小的位图-例如1MB或等效的像素尺寸(因为此位图需要添加为putExtra()用于意图)。
到目前为止我遇到的问题是:
我看过的大多数方法创建了一个缩放版本的位图。所以: Image-> Bitmap1(未缩放)-> Bitmap2(已缩放)。但是,如果图像的分辨率非常高,则缩小的不够多。我认为解决方案是创建一个确切大小的位图,使任何分辨率都可以缩小到足够小的尺寸。
然而,这种方法的副作用将是已经小于所需大小的图像将被调整大小(或调整大小无效?)。因此,需要一个“if”来检查是否可以将图像转换为位图而不进行调整大小。
我不知道如何去做这件事,因此非常感谢任何帮助! :-)
这是我现在正在使用的(它不会做我想要它做的事情):
// This is called when an image is picked from the gallery
@Override
    public void onActivityResult(int requestCode, int resultCode,
            Intent imageReturnedIntent) {
        super.onActivityResult(requestCode, resultCode, imageReturnedIntent);

        switch (requestCode) { 
        case 0:
            if (resultCode == Activity.RESULT_OK) {
                selectedImage = imageReturnedIntent.getData();
                viewImage = imageReturnedIntent.getData();

                try {
                    decodeUri(selectedImage);
                } catch (FileNotFoundException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

                iv_preview.setImageBitmap(mImageBitmap);
            }
            break; // The rest is unnecessary

这是当前调整大小的部分:
private Bitmap decodeUri(Uri selectedImage) throws FileNotFoundException { 


        // Decode image size
        BitmapFactory.Options o = new BitmapFactory.Options();
        o.inJustDecodeBounds = true; //
        BitmapFactory.decodeStream(getActivity().getContentResolver()
                .openInputStream(selectedImage), null, o);

        // The new size we want to scale to
        final int REQUIRED_SIZE = 260; // Is this kilobites? 306

        // Find the correct scale value. It should be the power of 2.
        int width_tmp = o.outWidth, height_tmp = o.outHeight;
        int scale = 1;
        while (true) {
            if (width_tmp / 2 < REQUIRED_SIZE || height_tmp / 2 < REQUIRED_SIZE) {
                break;
            }
            width_tmp /= 2;
            height_tmp /= 2;
            scale *= 2;
        }


        // Decode with inSampleSize
        BitmapFactory.Options o2 = new BitmapFactory.Options();
        o2.inSampleSize = scale;
        o2.inScaled = false; // Better quality?
        mImageBitmap = BitmapFactory.decodeStream(getActivity()
                .getContentResolver().openInputStream(selectedImage), null, o2);
        return BitmapFactory.decodeStream(getActivity().getContentResolver()
                .openInputStream(selectedImage), null, o2);

    }

如果有任何需要解释的地方,请告诉我。
谢谢。

你的代码,AFAIU,是错误的。在哪里保留宽高比的逻辑? - Manoj Awasthi
请查看以下链接:https://dev59.com/T27Xa4cB1Zd3GeqPlxj1?rq=1 您将能够与之相关联。 - Manoj Awasthi
@ManojAwasthi 这段代码是错误的 - 它没有做我想要的事情,但它确实保持了纵横比。非常感谢您提供的链接。 - user2442638
1个回答

2

如何调用:

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

        Uri selectedImage = data.getData();
        String[] filePathColumn = { MediaStore.Images.Media.DATA };

        Cursor cursor = getContentResolver().query(selectedImage,
                filePathColumn, null, null, null);
        cursor.moveToFirst();

        int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
        String picturePath = cursor.getString(columnIndex);
        cursor.close();
        pho1.setImageBitmap(decodeSampledBitmapFromResource(picturePath,
                80, 60));

方法:

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

        if (height > reqHeight || width > reqWidth) {

            // Calculate ratios of height and width to requested height and
            // width
            final int heightRatio = Math.round((float) height
                    / (float) reqHeight);
            final int widthRatio = Math.round((float) width / (float) reqWidth);

            // Choose the smallest ratio as inSampleSize value, this will
            // guarantee
            // a final image with both dimensions larger than or equal to the
            // requested height and width.
            inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
        }

        return inSampleSize;
    }

    public static Bitmap decodeSampledBitmapFromResource(String path,
            int reqWidth, int reqHeight) {
        Log.d("path", path);
        // First decode with inJustDecodeBounds=true to check dimensions
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(path, options);

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

        // Decode bitmap with inSampleSize set
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeFile(path, options);
    }

非常感谢您提供的代码,但是当我从我的onActivityResult()中调用calculateInSampleSize(null, 100, 100)时,我遇到了nullpointerexception异常。我猜测是因为我写的null有问题,但我不知道该改成什么。 - user2442638
1
你使用它有点不对。calculateInSampleSize是一个支持方法,你不需要在任何地方调用它。使用decodeSampledBitmapFromResource(pathToImage, 100,100)。 - Yarh
可以随意使用更适合您需求的解码方法,参考http://developer.android.com/reference/android/graphics/BitmapFactory.html。由于我从SD卡中获取图像,因此我更喜欢使用decodeFile,并提供pathToImage参数。 - Yarh
谢谢。我如何将新位图设置为ImageView?我以前做过,但似乎无法使用此方法。 - user2442638
更新,注意:该方法返回位图,因此位图bitmap = decodeSampledBitmapFromResource(picturePath,80,60); - Yarh
显示剩余4条评论

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