Resize bitmap without blurring

Asked

Viewed 602 times

1

I’m using a code to make the Imageview circular. The problem is that I need to use "scaleType:centerCrop", what leaves the image oval instead of circular, depending on its resolution.

I tried to use the code below to resize the image, but it ends up losing a lot of quality. I’ve been thinking instead of resizing, show just what the Imageview can show. That is, if the Imageview has 150px for 150px, will only show 150px/150px image, ignoring the rest. But I don’t know how I can do this.

Code to resize:

public Bitmap getResizedBitmap(Bitmap bm, int newWidth, int newHeight){
    int Width = bm.getWidth();
    int Height = bm.getHeight();
    float scaleWidth = ((float) newWidth / Width);
    float scaleHeight = ((float) newHeight / Height);

    //Create a matrix for manipulation
    Matrix matrix = new Matrix();
    //Resize the bitmap
    matrix.postScale(scaleWidth, scaleHeight);

    //Recreate bitmap
    Bitmap resizedBitmap = Bitmap.createBitmap
            ( bm, 0, 0, Width, Height, matrix, false );
    bm.recycle();

    return resizedBitmap;
}

Here’s the class I use to make Imageview circular:

import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.drawable.Drawable;

public class RoundImage extends Drawable {

    private final Bitmap mBitmap;
    private final Paint mPaint;
    private final RectF mRectF;
    private final int mBitmapWidth;
    private final int mBitmapHeight;

    public RoundImage(Bitmap bitmap) {
        mBitmap = bitmap;
        mRectF = new RectF();
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setDither(true);
        final BitmapShader shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
        mPaint.setShader(shader);

        mBitmapWidth = mBitmap.getWidth();
        mBitmapHeight = mBitmap.getHeight();
    }

    @Override
    public void draw(Canvas canvas) {
        canvas.drawOval(mRectF, mPaint);
    }

    @Override
    protected void onBoundsChange(Rect bounds) {
        super.onBoundsChange(bounds);
        mRectF.set(bounds);
    }

    @Override
    public void setAlpha(int alpha) {
        if (mPaint.getAlpha() != alpha) {
            mPaint.setAlpha(alpha);
            invalidateSelf();
        }
    }

    @Override
    public void setColorFilter(ColorFilter cf) {
        mPaint.setColorFilter(cf);
    }

    @Override
    public int getOpacity() {
        return PixelFormat.TRANSLUCENT;
    }

    @Override
    public int getIntrinsicWidth() {
        return mBitmapWidth;
    }

    @Override
    public int getIntrinsicHeight() {
        return mBitmapHeight;
    }

    public void setAntiAlias(boolean aa) {
        mPaint.setAntiAlias(aa);
        invalidateSelf();
    }

    @Override
    public void setFilterBitmap(boolean filter) {
        mPaint.setFilterBitmap(filter);
        invalidateSelf();
    }

    @Override
    public void setDither(boolean dither) {
        mPaint.setDither(dither);
        invalidateSelf();
    }

    public Bitmap getBitmap() {
        return mBitmap;
    }

}
  • It is probably leaving the image oval when the image has one of the dimensions (width or height) larger than the other, have you ever tried to cut the image to form a perfect square before resizing? for example: the original image was 160px by 150px, ai vc cut in width 5px on each side to stay with 150 x 150

1 answer

2


Android SDK provides the class Roundedbitmapdrawablefactory which make it possible to obtain drawables with the rounded corners.
Your methods return a Roundedbitmapdrawable using the method setCornerRadius() allows defining the radius to be applied to the corners.

If the drawable is not square the generated image will be an oval.

This example of use first cuts the image so as to make it square so that the image shown is a circle:

ImageView imageView = (ImageView)findViewById(R.id.imageView1);

Resources res = getResources();
Bitmap src = BitmapFactory.decodeResource(res, R.drawable.image);

//Determina o menor lado
int diameter = Math.min(src.getHeight(), src.getWidth());

//Cria um bitmap a partir do canto superior esquerdo do bitmap scr com
// com largura e altura igual a diameter 
Bitmap resizedBitmap=Bitmap.createBitmap(src, 0, 0, diameter, diameter);

RoundedBitmapDrawable roundBitmap = RoundedBitmapDrawableFactory.create(res, resizedBitmap);
roundBitmap.setAntiAlias(true);

//Define o raio dos cantos igual a meio diâmetro
roundBitmap.setCornerRadius(diameter / 2);

//Atribui o drawable à image view
imageView.setImageDrawable(roundBitmap);

Notes:

  • The class documentation Roundedbitmapdrawable shows that there is a method called setCircular() which, I suppose, would avoid the need to rather square the image to get a circle. However, in the tests I’ve been doing, I haven’t been able to access that method(The method setCircle() is Undefined for the type Roundedbitmapdrawable).

  • If the dimensions of Imageview are smaller than the image I suggest you see here a more efficient way to obtain the Bitmap.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.