Giới thiệu
Hầu hết các ứng dụng, web, game trên desktop, web, mobile đều sử dụng hình ảnh, trong Android để hiển thị hình ảnh, ImageView
được dựng sẵn trong Android SDK hỗ trợ rất tốt điều này, ImageView
là 1 View
có chức năng tải, và hiển thị hình ảnh, hoặc bất cứ drawable. ImageView
xử lý tất cả các công việc để hiển thị hình ảnh.
scaleType của ImageView có ý nghĩa như thế nào?
scaleType
là thuộc tính xác định cách thức mà hình ảnh được scale như thế nào để phù hợp với View
. ImageView
có thể hiển thị hình ảnh theo nhiều cách khác nhau, phụ thuộc vào các giá trị của thuộc tính scaleType
.
Giả sử 1 ImageView
có kích thước là width = 100px, height = 100px và hình ảnh có kích thước là 400x500.
<ImageView
android:scaleType="fitXY"
android:src="@drawable/my_image"
android:layout_width="100px"
android:layout_height="100px" />
Khi cài đặt scaleType="fitXY"
, có nghĩa là hình ảnh sẽ được scale về kích thước đúng bằng với kích thước của View là 100x100. Kết quả là hình ảnh phù hợp đúng với View nhưng hình ảnh không còn giữ được tỉ lệ của nó nữa.
ImageView
có các scaleType
dưới đây như sau:
fitXY
fitCenter
fitStart
fitEnd
matrix
center
centerCrop
centerInside
Giá trị mặc định scaleType của ImageView
Khởi tạo ImageView
bằng XML hoặc bằng mã Java và không đặt giá trị scaleType
, lúc đó giá trị mặc định của scaleType
sẽ là FIT_CENTER
.
Các giá trị scaleType và ý nghĩa
Ý nghĩa các giá trị scaleType
của ImageView
được mô tả chi tiết ở bảng dưới đây:
ScaleType | Mô tả |
---|---|
fitXY |
Scale hai chiều x, y của hình ảnh bằng đúng kích thước của View mà không quan tâm đến tỷ lệ của hình ảnh. |
fitCenter |
Scale hình ảnh sao cho fit hình ảnh trong View và giữ nguyên tỷ lệ của hình ảnh. Có ít nhất 1 chiều (x hoặc y) sẽ bằng đúng kích thước (width, height) của View và hiển thị hình ảnh ở giữa (center). Ví dụ như hình ảnh landscape (hình ảnh ngang) thì chiều rộng hình ảnh sẽ được scale cho cho bằng với chiều rộng của View. |
fitStart |
Giống với fitCenter nhưng hình ảnh sẽ hiển thi ở phía top-left của View . |
fitEnd |
Giống với fitCenter nhưng hình ảnh sẽ được hiển thị ở phía bottom-right của View |
matrix |
Scale hình ảnh dựa vào matrix , matrix được apply sử dụng phương thức setImageMatrix . |
center |
Scale hiển thị hình ảnh ở chính giữa View . |
centerCrop |
Scale hình ảnh cả hai chiều x và y lớn hơn hoặc bằng kích thước của |
centerInside |
Scale hình ảnh cả hai chiều x và y nhỏ hơn hoặc bằng kích thước của View trong khi vẫn giữ tỷ lệ của hình ảnh và hiển thị hình ảnh ở chính giữa View . |
Dưới đây là hình ảnh được hiển thị với ImageView
sử dụng các ScaleType khác nhau:

Và dưới đây là đoạn mã xử lý scaleType
của ImageView
:
private void configureBounds() {
if (mDrawable == null || !mHaveFrame)
return;
final int dwidth = mDrawableWidth;
final int dheight = mDrawableHeight;
final int vwidth = getWidth() - mPaddingLeft - mPaddingRight;
final int vheight = getHeight() - mPaddingTop - mPaddingBottom;
final boolean fits = (dwidth < 0 || vwidth == dwidth) && (dheight < 0 || vheight == dheight);
if (dwidth <= 0 || dheight <= 0 || ScaleType.FIT_XY == mScaleType) {
/* If the drawable has no intrinsic size, or we're told to
scaletofit, then we just fill our entire view.
*/
mDrawable.setBounds(0, 0, vwidth, vheight);
mDrawMatrix = null;
} else {
// We need to do the scaling ourself, so have the drawable
// use its native size.
mDrawable.setBounds(0, 0, dwidth, dheight);
if (ScaleType.MATRIX == mScaleType) {
// Use the specified matrix as-is.
if (mMatrix.isIdentity())
mDrawMatrix = null;
else
mDrawMatrix = mMatrix;
} else if (fits) {
// The bitmap fits exactly, no transform needed.
mDrawMatrix = null;
} else if (ScaleType.CENTER == mScaleType) {
// Center bitmap in view, no scaling.
mDrawMatrix = mMatrix;
mDrawMatrix.setTranslate(Math.round((vwidth - dwidth) * 0.5f),
Math.round((vheight - dheight) * 0.5f));
} else if (ScaleType.CENTER_CROP == mScaleType) {
mDrawMatrix = mMatrix;
float scale;
float dx = 0, dy = 0;
if (dwidth * vheight > vwidth * dheight) {
scale = (float)vheight/(float) dheight;
dx = (vwidth - dwidth * scale) * 0.5f;
} else {
scale = (float)vwidth/(float)dwidth;
dy = (vheight - dheight * scale) * 0.5f;
}
mDrawMatrix.setScale(scale, scale);
mDrawMatrix.postTranslate(Math.round(dx), Math.round(dy));
} else if (ScaleType.CENTER_INSIDE == mScaleType) {
mDrawMatrix = mMatrix;
float scale;
float dx;
float dy;
if (dwidth <= vwidth && dheight <= vheight)
scale = 1.0f;
else
scale = Math.min((float)vwidth/(float)dwidth, (float)vheight/(float)dheight);
dx = Math.round((vwidth - dwidth * scale) * 0.5f);
dy = Math.round((vheight - dheight * scale) * 0.5f);
mDrawMatrix.setScale(scale, scale);
mDrawMatrix.postTranslate(dx, dy);
} else {
// Generate the required transform.
mTempSrc.set(0, 0, dwidth, dheight);
mTempDst.set(0, 0, vwidth, vheight);
mDrawMatrix = mMatrix;
mDrawMatrix.setRectToRect(mTempSrc, mTempDst, scaleTypeToScaleToFit(mScaleType));
}
}
}
Scale Bitmap
Scale 1 hình ảnh trong Android như sau:
// Load a bitmap from the drawable folder
Bitmap bMap = BitmapFactory.decodeResource(getResources(), R.drawable.my_image);
// Resize the bitmap to 150x100 (width x height)
Bitmap bMapScaled = Bitmap.createScaledBitmap(bMap, 150, 100, true);
// Loads the resized Bitmap into an ImageView
ImageView image = (ImageView) findViewById(R.id.test_image);
image.setImageBitmap(bMapScaled);
Phương thức createScaledBitmap()
sử dụng để scale Bitmap
với các đối số truyền vào là width
, height
và filter
.
Nếu muốn scale hình ảnh mà vẫn giữ tỷ lệ thì sử dụng lớp sau:
public class BitmapScaler {
// Scale and maintain aspect ratio given a desired width
// BitmapScaler.scaleToFitWidth(bitmap, 100);
public static Bitmap scaleToFitWidth(Bitmap b, int width)
{
float factor = width/(float)b.getWidth();
return Bitmap.createScaledBitmap(b, width, (int)(b.getHeight() * factor), true);
}
// Scale and maintain aspect ratio given a desired height
// BitmapScaler.scaleToFitHeight(bitmap, 100);
public static Bitmap scaleToFitHeight(Bitmap b, int height)
{
float factor = height/(float)b.getHeight();
return Bitmap.createScaledBitmap(b, (int)(b.getWidth() * factor), height, true);
}
// ...
}
Tham khảo
https://guides.codepath.com/android/Working-with-the-ImageView#scale-types