通过设置ImageView的Matrix
,可以对图片做缩放的效果,很多图片查看器也是通过这种方式来实现的。
1.那么底层是如何实现的?
2.放大后是否会占用更大的内存?
带着这两个问题,去研究下源码。
首先是ImageView的设置Matrix方法:
//设置了mMatrix,然后执行了configureBounds方法
public void setImageMatrix(Matrix matrix) {
mMatrix.set(matrix);
configureBounds();
invalidate();
}
configureBounds
方法很关键:
//根据不同缩放类型,对mDrawMatrix进行了缩放位移等操作。
private void configureBounds() {
if (ScaleType.FIT_XY == mScaleType) {
mDrawable.setBounds(0, 0, vwidth, vheight);
} else {
mDrawable.setBounds(0, 0, dwidth, dheight);
if (ScaleType.MATRIX == mScaleType) {
mDrawMatrix = mMatrix;
}else if (ScaleType.CENTER == mScaleType) {
mDrawMatrix = mMatrix;
mDrawMatrix.setTranslate(Math.round((vwidth - dwidth) * 0.5f),
Math.round((vheight - dheight) * 0.5f));
} else if (ScaleType.CENTER_CROP == mScaleType) {
mDrawMatrix.setScale(scale, scale);
mDrawMatrix.postTranslate(Math.round(dx), Math.round(dy));
} else if (ScaleType.CENTER_INSIDE == mScaleType) {
mDrawMatrix = mMatrix;
mDrawMatrix.setScale(scale, scale);
mDrawMatrix.postTranslate(dx, dy);
}
}
}
到此为止,mDrawable的bounds和matrix就设置好了。然后看onDraw方法。
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mDrawMatrix != null) {
canvas.concat(mDrawMatrix);
}
mDrawable.draw(canvas);
}
最终canvas执行了这个matrix,对即将到来的绘制进行了变幻。
最后看BitmapDrawable的draw方法。
//在draw方法中,将bitmap绘制到canvas中
@Override
public void draw(Canvas canvas) {
canvas.drawBitmap(bitmap, null, mDstRect, paint);
}
总结
针对开篇提的两个问题:
1.ImageView的缩放,实际上最终是对canvas做缩放。
2.放大后,不会占用更大的内存,因为没有对bitmap做任何操作。