剖析 ImageView 的源码,一览其像素级的艺术创作奥秘
2023-09-06 14:01:51
ImageView
在安卓应用程序开发中的位图绘制之旅
加载位图
ImageView
组件是安卓应用程序开发中展示图像数据的重要组件。它允许开发者从本地存储或互联网加载位图(图像数据集合)并将其显示在应用程序中。setImageBitmap()
方法是加载位图的关键入口,接受一个 Bitmap
参数,包含要加载到 ImageView
中的像素数据。
public void setImageBitmap(Bitmap bitmap) {
...
if (bitmap != null && !bitmap.isRecycled()) {
setImageBitmap(bitmap);
imageMatrix = null;
invalidate();
}
}
首先,该方法检查传入的位图是否有效,然后将它分配给 ImageView
的内部位图变量。它还清空 imageMatrix
(位图转换信息),并调用 invalidate()
重新绘制组件。
转换位图
setImageMatrix()
方法用于转换 ImageView
中的位图。它接受一个 Matrix
参数,包含平移、旋转和缩放等转换详细信息。
public void setImageMatrix(Matrix matrix) {
...
if (!object.equals(mImageMatrix)) {
mImageMatrix = matrix;
invalidate();
}
}
该方法检查传入的转换矩阵与当前矩阵是否不同,如果不同,则更新内部 mImageMatrix
并调用 invalidate()
重新绘制。
绘制位图
在 onDraw()
回调方法中绘制位图,该方法在 ImageView
需要重新绘制时调用。
protected void onDraw(Canvas canvas) {
...
if (mBitmap != null) {
drawBitmap(canvas);
}
}
private void drawBitmap(Canvas canvas) {
...
float[] values = new float[9];
mImageMatrix.getValues(values);
float scaleX = values[Matrix.MSCALEX];
float scaleY = values[Matrix.MSCALEY];
float transX = values[Matrix.MTRANSX];
float transY = values[Matrix.MTRANSY];
if (scaleX != 1 || scaleY != 1 || transX != 0 || transY != 0) {
canvas.save();
canvas.concat(mImageMatrix);
canvas.drawBitmap(mBitmap, 0, 0, mBitmap.density, null);
canvas.restore();
} else {
canvas.drawBitmap(mBitmap, 0, 0, mBitmap.density, null);
}
}
onDraw()
方法检查位图是否存在,如果存在,则调用 drawBitmap()
方法进行绘制。drawBitmap()
方法获取转换矩阵的值,如果这些值不等于单位矩阵(没有缩放、旋转或平移),它将变换画布并应用转换矩阵。然后,它将位图绘制到画布上,并通过传递位图的密度作为附加参数来确保正确的显示。
常见问题解答
1. ImageView
中如何加载本地位图?
通过调用 setImageResource()
方法并提供本地资源 ID。
2. ImageView
中如何应用滤镜?
使用 setColorFilter()
方法应用 ColorFilter
对象。
3. 如何裁剪 ImageView
中的位图?
使用 setImageBitmap()
方法加载位图,并调用 setScaleType()
方法将其设置为 CENTER_CROP
。
4. 如何让位图在 ImageView
中适应大小?
使用 setScaleType()
方法将其设置为 FIT_XY
或 FIT_CENTER
。
5. 如何获取 ImageView
中位图的像素数据?
通过调用 getPixelCopy()
方法并将结果复制到一个 Bitmap
对象中。