如何在Android中调整位图大小?

我有一个位图采取的Base64字符串从我的远程数据库,(encodedImage是字符串表示图像与Base64):

profileImage = (ImageView)findViewById(R.id.profileImage);


byte[] imageAsBytes=null;
try {
imageAsBytes = Base64.decode(encodedImage.getBytes());
} catch (IOException e) {e.printStackTrace();}


profileImage.setImageBitmap(
BitmapFactory.decodeByteArray(imageAsBytes, 0, imageAsBytes.length)
);

profileImage是我的ImageView

好的,但是我必须在布局的ImageView上显示它之前调整这个图像的大小。我得把它调整到120x120。

有人能告诉我调整大小的代码吗?

我发现的例子不能应用于base64字符串获得位图。

516530 次浏览

变化:

profileImage.setImageBitmap(
BitmapFactory.decodeByteArray(imageAsBytes, 0, imageAsBytes.length)

:

Bitmap b = BitmapFactory.decodeByteArray(imageAsBytes, 0, imageAsBytes.length)
profileImage.setImageBitmap(Bitmap.createScaledBitmap(b, 120, 120, false));
import android.graphics.Matrix
public Bitmap getResizedBitmap(Bitmap bm, int newWidth, int newHeight) {
int width = bm.getWidth();
int height = bm.getHeight();
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
// CREATE A MATRIX FOR THE MANIPULATION
Matrix matrix = new Matrix();
// RESIZE THE BIT MAP
matrix.postScale(scaleWidth, scaleHeight);


// "RECREATE" THE NEW BITMAP
Bitmap resizedBitmap = Bitmap.createBitmap(
bm, 0, 0, width, height, matrix, false);
bm.recycle();
return resizedBitmap;
}

编辑:根据@aveschini的建议,我添加了bm.recycle();,以避免内存泄漏。请注意,如果您将前一个对象用于其他用途,则应相应地处理。

如果你已经有一个位图,你可以使用下面的代码来调整大小:

Bitmap originalBitmap = <original initialization>;
Bitmap resizedBitmap = Bitmap.createScaledBitmap(
originalBitmap, newWidth, newHeight, false);
profileImage.setImageBitmap(
Bitmap.createScaledBitmap(
BitmapFactory.decodeByteArray(imageAsBytes, 0, imageAsBytes.length),
80, 80, false
)
);

试试这段代码:

BitmapDrawable drawable = (BitmapDrawable) imgview.getDrawable();
Bitmap bmp = drawable.getBitmap();
Bitmap b = Bitmap.createScaledBitmap(bmp, 120, 120, false);

希望对大家有用。

有人问在这种情况下如何保持纵横比:

计算用于缩放的因子,并将其用于两个维度。 假设你想让图像的高度占屏幕的20%

int scaleToUse = 20; // this will be our percentage
Bitmap bmp = BitmapFactory.decodeResource(
context.getResources(), R.drawable.mypng);
int sizeY = screenResolution.y * scaleToUse / 100;
int sizeX = bmp.getWidth() * sizeY / bmp.getHeight();
Bitmap scaled = Bitmap.createScaledBitmap(bmp, sizeX, sizeY, false);

获得屏幕分辨率,你有这样的解决方案: 以像素为单位获取屏幕尺寸 < / p >

基于纵横比的缩放:

float aspectRatio = yourSelectedImage.getWidth() /
(float) yourSelectedImage.getHeight();
int width = 480;
int height = Math.round(width / aspectRatio);


yourSelectedImage = Bitmap.createScaledBitmap(
yourSelectedImage, width, height, false);

使用高度作为基础而不是宽度更改为:

int height = 480;
int width = Math.round(height * aspectRatio);
< p >试试这个: 这个函数按比例调整位图的大小。当最后一个参数设置为"X"时,newDimensionXorY将被视为s的新宽度,当设置为"Y"时,newDimensionXorY将被视为新的高度
public Bitmap getProportionalBitmap(Bitmap bitmap,
int newDimensionXorY,
String XorY) {
if (bitmap == null) {
return null;
}


float xyRatio = 0;
int newWidth = 0;
int newHeight = 0;


if (XorY.toLowerCase().equals("x")) {
xyRatio = (float) newDimensionXorY / bitmap.getWidth();
newHeight = (int) (bitmap.getHeight() * xyRatio);
bitmap = Bitmap.createScaledBitmap(
bitmap, newDimensionXorY, newHeight, true);
} else if (XorY.toLowerCase().equals("y")) {
xyRatio = (float) newDimensionXorY / bitmap.getHeight();
newWidth = (int) (bitmap.getWidth() * xyRatio);
bitmap = Bitmap.createScaledBitmap(
bitmap, newWidth, newDimensionXorY, true);
}
return bitmap;
}

缩放位图的目标最大大小和宽度,同时保持纵横比:

int maxHeight = 2000;
int maxWidth = 2000;
float scale = Math.min(((float)maxHeight / bitmap.getWidth()), ((float)maxWidth / bitmap.getHeight()));


Matrix matrix = new Matrix();
matrix.postScale(scale, scale);


bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
在API 19中,位图setWidth(int width)和setHeight(int height)存在。 http://developer.android.com/reference/android/graphics/Bitmap.html < / p >
  public Bitmap scaleBitmap(Bitmap mBitmap) {
int ScaleSize = 250;//max Height or width to Scale
int width = mBitmap.getWidth();
int height = mBitmap.getHeight();
float excessSizeRatio = width > height ? width / ScaleSize : height / ScaleSize;
Bitmap bitmap = Bitmap.createBitmap(
mBitmap, 0, 0,(int) (width/excessSizeRatio),(int) (height/excessSizeRatio));
//mBitmap.recycle(); if you are not using mBitmap Obj
return bitmap;
}

位图调整基于任何显示大小

public Bitmap bitmapResize(Bitmap imageBitmap) {


Bitmap bitmap = imageBitmap;
float heightbmp = bitmap.getHeight();
float widthbmp = bitmap.getWidth();


// Get Screen width
DisplayMetrics displaymetrics = new DisplayMetrics();
this.getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
float height = displaymetrics.heightPixels / 3;
float width = displaymetrics.widthPixels / 3;


int convertHeight = (int) hight, convertWidth = (int) width;


// higher
if (heightbmp > height) {
convertHeight = (int) height - 20;
bitmap = Bitmap.createScaledBitmap(bitmap, convertWidth,
convertHighet, true);
}


// wider
if (widthbmp > width) {
convertWidth = (int) width - 20;
bitmap = Bitmap.createScaledBitmap(bitmap, convertWidth,
convertHeight, true);
}


return bitmap;
}
public static Bitmap resizeBitmapByScale(
Bitmap bitmap, float scale, boolean recycle) {
int width = Math.round(bitmap.getWidth() * scale);
int height = Math.round(bitmap.getHeight() * scale);
if (width == bitmap.getWidth()
&& height == bitmap.getHeight()) return bitmap;
Bitmap target = Bitmap.createBitmap(width, height, getConfig(bitmap));
Canvas canvas = new Canvas(target);
canvas.scale(scale, scale);
Paint paint = new Paint(Paint.FILTER_BITMAP_FLAG | Paint.DITHER_FLAG);
canvas.drawBitmap(bitmap, 0, 0, paint);
if (recycle) bitmap.recycle();
return target;
}
private static Bitmap.Config getConfig(Bitmap bitmap) {
Bitmap.Config config = bitmap.getConfig();
if (config == null) {
config = Bitmap.Config.ARGB_8888;
}
return config;
}

虽然接受的答案是正确的,但它不会通过保持相同的纵横比来调整Bitmap的大小。如果你正在寻找一种通过保持相同的纵横比来调整Bitmap大小的方法,你可以使用以下实用函数。函数的使用细节和解释在< >强这个链接< / >强中。

public static Bitmap resizeBitmap(Bitmap source, int maxLength) {
try {
if (source.getHeight() >= source.getWidth()) {
int targetHeight = maxLength;
if (source.getHeight() <= targetHeight) { // if image already smaller than the required height
return source;
}


double aspectRatio = (double) source.getWidth() / (double) source.getHeight();
int targetWidth = (int) (targetHeight * aspectRatio);


Bitmap result = Bitmap.createScaledBitmap(source, targetWidth, targetHeight, false);
if (result != source) {
}
return result;
} else {
int targetWidth = maxLength;


if (source.getWidth() <= targetWidth) { // if image already smaller than the required height
return source;
}


double aspectRatio = ((double) source.getHeight()) / ((double) source.getWidth());
int targetHeight = (int) (targetWidth * aspectRatio);


Bitmap result = Bitmap.createScaledBitmap(source, targetWidth, targetHeight, false);
if (result != source) {
}
return result;


}
}
catch (Exception e)
{
return source;
}
}
/**
* Kotlin method for Bitmap scaling
* @param bitmap the bitmap to be scaled
* @param pixel  the target pixel size
* @param width  the width
* @param height the height
* @param max    the max(height, width)
* @return the scaled bitmap
*/
fun scaleBitmap(bitmap:Bitmap, pixel:Float, width:Int, height:Int, max:Int):Bitmap {
val scale = px / max
val h = Math.round(scale * height)
val w = Math.round(scale * width)
return Bitmap.createScaledBitmap(bitmap, w, h, true)
}

保持纵横比,

  public Bitmap resizeBitmap(Bitmap source, int width,int height) {
if(source.getHeight() == height && source.getWidth() == width) return source;
int maxLength=Math.min(width,height);
try {
source=source.copy(source.getConfig(),true);
if (source.getHeight() <= source.getWidth()) {
if (source.getHeight() <= maxLength) { // if image already smaller than the required height
return source;
}


double aspectRatio = (double) source.getWidth() / (double) source.getHeight();
int targetWidth = (int) (maxLength * aspectRatio);


return Bitmap.createScaledBitmap(source, targetWidth, maxLength, false);
} else {


if (source.getWidth() <= maxLength) { // if image already smaller than the required height
return source;
}


double aspectRatio = ((double) source.getHeight()) / ((double) source.getWidth());
int targetHeight = (int) (maxLength * aspectRatio);


return Bitmap.createScaledBitmap(source, maxLength, targetHeight, false);


}
}
catch (Exception e)
{
return source;
}
}

虽然前面的答案确实缩放了图像并考虑了纵横比,但重新采样本身应该这样做,这样就不会出现混叠。注意尺度是一个正确修正参数的问题。有许多关于标准缩放调用输出图像质量的评论。为了保持图像的质量,应该使用标准调用:

Bitmap resizedBitmap = Bitmap.createScaledBitmap(originalBitmap, newWidth, newHeight, true);

最后一个参数设置为true,因为它将做双线性滤波重采样,以防止混叠。在这里阅读更多关于别名的信息:https://en.wikipedia.org/wiki/Aliasing

来自android文档:

https://developer.android.com/reference/android/graphics/Bitmap#createScaledBitmap(android.graphics.Bitmap,%20int,%20int,%20boolean)


public static Bitmap createScaledBitmap (Bitmap src,
int dstWidth,
int dstHeight,
boolean filter)

过滤器: boolean,当缩放位图时是否应该使用双线性过滤。如果这是真的,那么在缩放时将使用双线性滤波,它以更差的性能为代价,具有更好的图像质量。如果这是假的,那么使用最近邻缩放,这将有较差的图像质量,但更快。推荐的默认值是将filter设置为'true',因为双线性过滤的成本通常是最小的,并且图像质量的改善是显著的。

* For resize bitmap with width and height ratio.


public static Bitmap getResizedBitmap(Bitmap image, int maxSize) {
int width = image.getWidth();
int height = image.getHeight();
    

float bitmapRatio = (float) width / (float) height;
if (bitmapRatio > 1) {
width = maxSize;
height = (int) (width / bitmapRatio);
} else {
height = maxSize;
width = (int) (height * bitmapRatio);
}
return Bitmap.createScaledBitmap(image, width, height, true);
}

apply Matrix.ScaleToFit.CENTER)获取一个新的位图保持纵横比。

public static Bitmap getScaledwonBitmap(Bitmap srcBmp, int deisredWidth, int desiredHeight) {
        

Matrix matrix = new Matrix();
matrix.setRectToRect(new RectF(0, 0, srcBmp.getWidth(), srcBmp.getHeight()),
new RectF(0, 0, deisredWidth, desiredHeight),
Matrix.ScaleToFit.CENTER);
return Bitmap.createBitmap(srcBmp, 0, 0, srcBmp.getWidth(), srcBmp.getHeight(), matrix, true);
        

}
      Try this kotlin code for resize....Where Max size any size you
want


fun getResizedBitmap(image: Bitmap?, maxSize: Int): Bitmap {
var width = image!!.width
var height = image.height
val bitmapRatio = width.toFloat() / height.toFloat()
if (bitmapRatio > 0) {
width = maxSize
height = (width / bitmapRatio).toInt()
} else {
height = maxSize
width = (height * bitmapRatio).toInt()
}
return Bitmap.createScaledBitmap(image, width, height, true)
}