安卓图片缩放原理

通过设置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做任何操作。

你可能感兴趣的:(安卓图片缩放原理)