我想按比例缩放位图,但要适应所需的尺寸。 这个答案 缩放位图并保持纵横比,但除非图像是完美的正方形,否则会留下一些空白区域。我需要填充宽度和高度,就像 ImageView
的 FIT_XY
ScaleType 属性一样。
基于波士顿街道的答案,我编写了这个方法,它可以将任何位图按所需的宽度和高度进行缩放并适配两个维度(没有空白空间!)。它会自动适应更多水平或更多垂直的图像。
public Bitmap resizeBitmapFitXY(int width, int height, Bitmap bitmap){
Bitmap background = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
float originalWidth = bitmap.getWidth(), originalHeight = bitmap.getHeight();
Canvas canvas = new Canvas(background);
float scale, xTranslation = 0.0f, yTranslation = 0.0f;
if (originalWidth > originalHeight) {
scale = height/originalHeight;
xTranslation = (width - originalWidth * scale)/2.0f;
}
else {
scale = width / originalWidth;
yTranslation = (height - originalHeight * scale)/2.0f;
}
Matrix transformation = new Matrix();
transformation.postTranslate(xTranslation, yTranslation);
transformation.preScale(scale, scale);
Paint paint = new Paint();
paint.setFilterBitmap(true);
canvas.drawBitmap(bitmap, transformation, paint);
return background;
}
import android.graphics.*;
public static Bitmap scalePreserveRatio(Bitmap imageToScale, int destinationWidth,
int destinationHeight) {
if (destinationHeight > 0 && destinationWidth > 0 && imageToScale != null) {
int width = imageToScale.getWidth();
int height = imageToScale.getHeight();
//Calculate the max changing amount and decide which dimension to use
float widthRatio = (float) destinationWidth / (float) width;
float heightRatio = (float) destinationHeight / (float) height;
//Use the ratio that will fit the image into the desired sizes
int finalWidth = (int)Math.floor(width * widthRatio);
int finalHeight = (int)Math.floor(height * widthRatio);
if (finalWidth > destinationWidth || finalHeight > destinationHeight) {
finalWidth = (int)Math.floor(width * heightRatio);
finalHeight = (int)Math.floor(height * heightRatio);
}
//Scale given bitmap to fit into the desired area
imageToScale = Bitmap.createScaledBitmap(imageToScale, finalWidth, finalHeight, true);
//Created a bitmap with desired sizes
Bitmap scaledImage = Bitmap.createBitmap(destinationWidth, destinationHeight, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(scaledImage);
//Draw background color
Paint paint = new Paint();
paint.setColor(Color.TRANSPARENT);
paint.setStyle(Paint.Style.FILL);
canvas.drawRect(0, 0, canvas.getWidth(), canvas.getHeight(), paint);
//Calculate the ratios and decide which part will have empty areas (width or height)
float ratioBitmap = (float)finalWidth / (float)finalHeight;
float destinationRatio = (float) destinationWidth / (float) destinationHeight;
float left = ratioBitmap >= destinationRatio ? 0 : (float)(destinationWidth - finalWidth) / 2;
float top = ratioBitmap < destinationRatio ? 0: (float)(destinationHeight - finalHeight) / 2;
canvas.drawBitmap(imageToScale, left, top, null);
return scaledImage;
} else {
return imageToScale;
}
}
答案基于Pablo的回答并解决了被裁剪的问题:
myBitmap?.let {
val originalWidth = it.width.toFloat()
val originalHeight = it.height.toFloat()
var scale = 0.0f
var xTranslation = 0.0f
var yTranslation = 0.0f
val widthRatio = viewWidth / originalWidth
val heightRatio = viewHeight / originalHeight
if (widthRatio > heightRatio) {
scale = viewHeight / originalHeight
xTranslation = (viewWidth - originalWidth * scale) / 2.0f
} else {
scale = viewWidth / originalWidth
yTranslation = (viewHeight - originalHeight * scale) / 2.0f
}
val matrix = Matrix()
matrix.postTranslate(xTranslation, yTranslation)
matrix.preScale(scale, scale)
canvas.drawBitmap(it, matrix, myBitmapPainter)
}