LoginSignup
29
26

More than 5 years have passed since last update.

Bitmapをアスペクト比を保ったままリサイズする

Posted at

クラスの内容はvolleyでImageRequestをした後に行われるリサイズ処理を抜き出して軽く機能を削ったものです。
これ単体でも何かと便利なので抜き出してBitmapのリサイズに使わせてもらっています。

URIを受け取って指定したmaxSizeに合わせてリサイズしたBitmapを返すクラスです。

BitmapResizer.java
public class BitmapResizer {
    private Context context;

    public BitmapResizer(Context context) {
        this.context = context;
    }

    public Bitmap resize(Uri uri,int mMaxWidth,int mMaxHeight) throws IOException {

        Bitmap bitmap = null;
        BitmapFactory.Options decodeOptions = new BitmapFactory.Options();
        decodeOptions.inJustDecodeBounds = true;
        InputStream inputStream = context.getContentResolver().openInputStream(uri);
        BitmapFactory.decodeStream(inputStream,null,decodeOptions);
        inputStream.close();
        int actualWidth = decodeOptions.outWidth;
        int actualHeight = decodeOptions.outHeight;

        int desiredWidth = getResizedDimension(mMaxWidth, mMaxHeight,
                actualWidth, actualHeight);
        int desiredHeight = getResizedDimension(mMaxHeight, mMaxWidth,
                actualHeight, actualWidth);

        decodeOptions.inJustDecodeBounds = false;
        decodeOptions.inSampleSize =
                findBestSampleSize(actualWidth, actualHeight, desiredWidth, desiredHeight);

        inputStream = context.getContentResolver().openInputStream(uri);
        Bitmap tempBitmap = BitmapFactory.decodeStream(inputStream,null,decodeOptions);
        inputStream.close();

        if (tempBitmap != null && (tempBitmap.getWidth() > desiredWidth ||
                tempBitmap.getHeight() > desiredHeight)) {
            bitmap = Bitmap.createScaledBitmap(tempBitmap,
                    desiredWidth, desiredHeight, true);
            tempBitmap.recycle();
        } else {
            bitmap = tempBitmap;
        }
        return bitmap;
    }

    private int getResizedDimension(int maxPrimary, int maxSecondary, int actualPrimary,
                                           int actualSecondary) {
        if ((maxPrimary == 0) && (maxSecondary == 0)) {
            return actualPrimary;
        }

        if (maxPrimary == 0) {
            double ratio = (double) maxSecondary / (double) actualSecondary;
            return (int) (actualPrimary * ratio);
        }

        if (maxSecondary == 0) {
            return maxPrimary;
        }

        double ratio = (double) actualSecondary / (double) actualPrimary;
        int resized = maxPrimary;

        if ((resized * ratio) < maxSecondary) {
            resized = (int) (maxSecondary / ratio);
        }
        return resized;
    }

    static int findBestSampleSize(
            int actualWidth, int actualHeight, int desiredWidth, int desiredHeight) {
        double wr = (double) actualWidth / desiredWidth;
        double hr = (double) actualHeight / desiredHeight;
        double ratio = Math.min(wr, hr);
        float n = 1.0f;
        while ((n * 2) <= ratio) {
            n *= 2;
        }
        return (int) n;
    }
}

使用例

Intentでギャラリーなどから画像のURIを取得して
その画像をリサイズします

MainActivity.java
public class MainActivity extends ActionBarActivity {
    private int REQUEST_GALLERY = 1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent();
                intent.setType("image/*");
                intent.setAction(Intent.ACTION_GET_CONTENT);
                startActivityForResult(intent, REQUEST_GALLERY);
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_GALLERY && resultCode == Activity.RESULT_OK) {
            BitmapResizer bitmapResizer = new BitmapResizer(this);
            try {
                Bitmap bitmap = bitmapResizer.resize(data.getData(),500,500);//アスペクト比を保ったままいい感じにリサイズされたBitmapが返ってくる
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

このサンプルではURIからbitmapを取得してリサイズしていますが
リソースからでもbyte[]からでもBitmapFactoryでBitmapを取得する処理の所を変えれば大丈夫です。

もともとのvolleyのソースはこちらです。
https://github.com/mcxiaoke/android-volley/blob/master/src/main/java/com/android/volley/toolbox/ImageRequest.java

29
26
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
29
26