gpt4 book ai didi

java - Android 中的图像选择出现 OutOfMemoryError。如何在将图像解码为位图之前调整图像大小?

转载 作者:行者123 更新时间:2023-12-01 06:39:00 24 4
gpt4 key购买 nike

我正在我的 Android 应用程序中构建一个图像选择器,为此我使用了 example code on this page 。这基本上给了我一个按钮,可以从 SD 卡获取文件,或者通过拍照获取文件。一旦我选择了图像,它就会使用简单的 ImageView 显示图像。一般来说,这种方法效果很好;我可以选择一个图像,然后再次单击“选择图像”按钮并选择另一个图像。到目前为止一切顺利......小文件就是这样。

当我使用“更大的文件”时,问题就开始了;我只是用内置手机摄像头拍摄的照片。我可以选择一个,效果很好。当我再次点击选择图像按钮并选择另一个图像时,我在这一行收到 OutOfMemoryError(链接到页面的第 75 行):

bitmap = BitmapFactory.decodeFile(path);

我的测试设备是相当现代的设备(Galaxy S4 Mini),所以这不应该是问题。由于我需要将图像作为 base64 字符串发送到需要调整其大小的 API,因此我可以使用如下方式调整图像大小:

Bitmap yourBitmap;
Bitmap resized = Bitmap.createScaledBitmap(yourBitmap, newWidth, newHeight, true);

但不幸的是,为此我首先需要解码文件,这实际上首先导致了问题。

所以我的问题是;有没有一种方法可以在将图像解码为位图之前调整图像的大小?欢迎所有提示!

最佳答案

当您加载大型位图文件时,BitmapFactory 类提供了多种解码方法(decodeByteArray()、decodeFile()、decodeResource() 等)。

第 1 步

在解码时将 inJustDecodeBounds 属性设置为 true 可以避免内存分配,为位图对象返回 null,但设置 outWidth、outHeight 和 outMimeType。此技术允许您在构建位图(和内存分配)之前读取图像数据的尺寸和类型。

BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(getResources(), R.id.myimage, options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
String imageType = options.outMimeType;

为了避免 java.lang.OutOfMemory 异常,请在解码之前检查位图的尺寸。

第 2 步

要告诉解码器对图像进行二次采样,将较小的版本加载到内存中,请在 BitmapFactory.Options 对象中将 inSampleSize 设置为 true。

例如,分辨率为 2048x1536 的图像使用 inSampleSize 4 进行解码会生成大约 512x384 的位图。将其加载到内存中需要 0.75MB,而不是完整图像的 12MB。

这是一种根据目标宽度和高度计算样本大小值的方法,该值是 2 的幂:

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);
}

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;
}

请阅读此链接了解详细信息。 http://developer.android.com/training/displaying-bitmaps/load-bitmap.html

关于java - Android 中的图像选择出现 OutOfMemoryError。如何在将图像解码为位图之前调整图像大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20617094/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com