Resize bitmap without blurring

1

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

I tried using the code below to resize the image, but it ended up losing a lot of quality. I've been thinking instead of resizing, show only what ImageView can show. That is, if ImageView has 150px for 150px , it will only display 150px / 150px in the image, remaining. But I do not know how I can do this.

Resize code:

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

}
    
asked by anonymous 19.10.2015 / 05:45

1 answer

2

The Android SDK provides the RoundedBitmapDrawableFactory class to get < in> drawables with rounded corners. Your methods return a RoundedBitmapDrawable using the setCornerRadius () allows you to define the radius to apply to the corners.

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

This usage example first cuts the image to square it so that the displayed image 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 RoundedBitmapDrawable class documentation shows that there is a method called setCircular () which, I suppose, would avoid the need to first make the square image to get a circle. However, in the tests I was doing, I was unable to access this method ( The method setCircle () is undefined for the RoundedBitmapDrawable type).

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

19.10.2015 / 17:01