大体的实现是,这样的,在 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" />
然后效果如下:
就是这样子的,图片被缩小了,(不是被裁切),然后居中显示在控件的正中心了。