我有图片3264х2448
。
我将其加载到位图crudeImage = BitmapFactory.decodeFile(picturePath);
中,然后设置为ImageView imageCrop.setImageBitmap(crudeImage);
问题是它非常大(3264х2448
)和我的库cropper
使用此图片工作得非常慢。 我想将图像缩小到更小的尺寸。但要保持质量和比例。怎么办呢?
答案 0 :(得分:2)
您应该阅读Loading Large Bitmaps Efficiently。
基本上,首先按
计算样本量public static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) > reqHeight
&& (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
然后使用样本大小加载图像:
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}
答案 1 :(得分:0)
我用它来调整我的位图的大小。也许对你有用。
public Bitmap resizeBitmap(Bitmap bitmap, int newWidth, int newHeight)
{
//bitmap it's the bitmap you want to resize
//newWidth and newHeight are the with and height that you want to the new bitmap
int width = bitmap.getWidth();
int height = bitmap.getHeight();
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) /height;
Matrix matrix = new Matrix();
matrix.postScale(scaleWidth, scaleHeight);
Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, false);
return resizedBitmap;
}
我希望这对你有所帮助。
答案 2 :(得分:0)
如果您阅读了教程here,那么您会看到谷歌为您提供有关如何在不占用大量内存的情况下扩展位图的非常全面的指南。
特别是这两种方法(来自教程):
public static Bitmap decodeSampledBitmapFromResource(File file, int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(file, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(file, options);
}
public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight){
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) > reqHeight
&& (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
在保持宽高比的同时完成缩放。
这两种方法的技巧是第一个解码操作被设置为仅解码图像的属性(维度和其他信息),如下所示:
options.inJustDecodeBounds = true;
其中新比例因子通过calculateInSampleSize()方法按比例计算。
然后再次解码图像,这次是
options.inJustDecodeBounds = false;
以及比例因子设置,因此位图工厂会在解码时自动缩放,从而减少内存占用。
关于图像需要解码的分辨率,这实际上取决于您的用例。但是,如果特定图像不需要稍后放大,您只需要设备的物理屏幕尺寸,可以通过以下方式获得:
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getRealSize(size);
对象size
将保存设备的屏幕尺寸。