android canvas.drawBitmap(bitmap, matrix, paint) 中 利用 matrix 实现平移到中心点及中心点缩放

大体的实现是,这样的,在 res/drawable/ 目录下面放了一张图片,但是图片比较大,先根据view 的宽高,对 bitmap 进行等比缩放,缩放到能完全显示到 view 里面。(这时候如果直接调用canvas.drawBitmap()会把图片加载在当前view的左上角。) 然后,再通过 matrix 的平移与缩放,让 图片 居中显示在view中,并相对缩小了一点点。

代码如下:

public class ClipView extends View {
    private int mWidth;
    private int mHeight;
    private Matrix matrix;
    private Paint paint;
    private Bitmap bitmap;
    private Point center;
    private Point bmpCenter;
    private RectF oval;

    public ClipView(Context context) {
        super(context);
    }

    public ClipView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public ClipView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public ClipView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        this.mWidth = w;
        this.mHeight = h;
        matrix = new Matrix();
        paint = new Paint();
        paint.setAntiAlias(true);
        Bitmap temp = BitmapFactory.decodeResource(getResources(), R.drawable.bw);
        int bw = temp.getWidth();
        int bh = temp.getHeight();
        float scale = Math.min(1f * mWidth / bw, 1f * mHeight / bh);
        LogUtils.w("scale==" + scale);
        bitmap = scaleBitmap(temp, scale);
        // compute init left, top
        int bbw = bitmap.getWidth();
        int bbh = bitmap.getHeight();
        center = new Point(mWidth / 2, mHeight / 2);
        bmpCenter = new Point(bbw / 2, bbh / 2);
        matrix.postScale(0.9f, 0.9f, center.x, center.y); // 中心点参数是有用的
        matrix.postTranslate(center.x - bmpCenter.x, center.y - bmpCenter.y); // 移动到当前view 的中心
        oval = new RectF(center.x - bbw / 2, center.y - bbh / 2,
                center.x + bbw / 2, center.y + bbh / 2);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawBitmap(bitmap, matrix, paint);
//        canvas.scale(1.1f,1.1f,center.x,center.y);
//        canvas.drawRect(oval,paint);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                break;
            case MotionEvent.ACTION_MOVE:
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                break;
        }
        return super.onTouchEvent(event);
    }

    /**
     * 根据给定的宽和高进行拉伸
     *
     * @param origin 原图
     * @param scale  缩放比例
     * @return new Bitmap
     */
    private Bitmap scaleBitmap(Bitmap origin, float scale) {
        if (origin == null) {
            return null;
        }
        int height = origin.getHeight();
        int width = origin.getWidth();
        Matrix matrix = new Matrix();
        matrix.postScale(scale, scale);// 使用后乘
        Bitmap newBM = Bitmap.createBitmap(origin, 0, 0, width, height, matrix, false);
        if (!origin.isRecycled()) {
            origin.recycle();
        }
        return newBM;
    }
}

布局文件里面是这样的:

<com.cat.simpleapp20180620.view.ClipView
        android:id="@+id/clip_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="3dp" />

然后效果如下:

这里写图片描述

就是这样子的,图片被缩小了,(不是被裁切),然后居中显示在控件的正中心了。

猜你喜欢

转载自blog.csdn.net/ducklikejava/article/details/80930706