我找到了很多关于如何加载大型位图并避免outofmemory异常的文档。但问题是我必须从我的MediaStore.Images.media中获取图像所以经典
谷歌文档中指出的decodeFile(path,options)
对我不起作用
如下所示,我取消了行// Bitmap photo= Mediastore.Images
,即触发内存不足的行Bitmap bm=BitmapFactory.decodeFile(selectedImageToUri,options)
。在另一边补充
行null
返回selectedImageToUri
,虽然编译器可以看到BitMap photo
中的路径(表示图片所在的内容提供者)而不是选项值,我设置为8,因为我想要缩放所有图像
我的问题是如何在bm中插入引用用户在库中选择的图像的位图。行@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable final Bundle savedInstanceState) {
if (flagVariable) {
if (selectedImageToUri != null) {
// BitMap photo = MediaStore.Images.Media.getBitmap(getActivity().getContentResolver(), Uri.parse(selectedImageToUri));
final BitmapFactory.Options options= new BitmapFactory.Options();
options.inSampleSize=8;
Bitmap bm = BitmapFactory.decodeFile(selectedImageToUri, options);
pic = new BitmapDrawable(bm);
getActivity().getWindow().setBackgroundDrawable(pic);
} else {
getDefaultImageBackground(inflater, container);
}
hiddenList = inflater.inflate(R.layout.fragment_as_list_layout_temp, container, false);
} else {
getDefaultImageBackground(inflater, container);
}
listView = (ListView) hiddenList.findViewById(R.id.list_hidden);
中的行不会返回null并且工作得非常好,但是我已经取消注释,因为在我更改了几个图像之后会给我一些内存异常。
SELECT
[Measures].[Store sales]
*
{
[Occupation].[Occupation].MEMBERS * {[Essai].[All]}
,
{[Occupation].[All]} * [Essai].[Essai].MEMBERS
} ON COLUMNS
,{[Product].[Product Family].MEMBERS} ON ROWS
FROM test;
答案 0 :(得分:2)
MediaStore.getBitmap
只是一种简单的便利方法,它看起来像这样:
public static final Bitmap getBitmap(ContentResolver cr, Uri url)
throws FileNotFoundException, IOException {
InputStream input = cr.openInputStream(url);
Bitmap bitmap = BitmapFactory.decodeStream(input);
input.close();
return bitmap;
}
您可以根据此方法创建自己的方法options
,并在BitmapFactory
上调用不同的重载:
public static final Bitmap getBitmap(ContentResolver cr,
Uri url,
BitmapFactory.Options options)
throws FileNotFoundException, IOException {
InputStream input = cr.openInputStream(url);
Bitmap bitmap = BitmapFactory.decodeStream(input, null, options);
input.close();
return bitmap;
}
用法:
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 8;
Bitmap bm = getBitmap(getActivity().getContentResolver(),
Uri.parse(selectedImageToUri),
options);
答案 1 :(得分:1)
我在这个问题上花了很多时间,但是没有人会给我确切的答案,最后我解决了。首先创建方法并提供Image URI作为参数,这将基本上返回位图,我计算图像大小,我们可以管理内存和图像,并以位图形式获得精确的图像。
你甚至可以显示5000×8000和12MiB图片,没有任何错误代码被测试只需复制粘贴在你的班级并享受。
使用强>
Bitmap mBitmap = getPhoto(MYIMAGEURI);
为方法提供URI并获取位图
Bitmap getPhoto(Uri selectedImage) {
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int height = metrics.heightPixels;
int width = metrics.widthPixels;
Bitmap photoBitmap = null;
InputStream inputStream = null;
try {
inputStream = getContentResolver().openInputStream(selectedImage);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
bitmapOptions.inJustDecodeBounds = true;
BitmapFactory.decodeStream(inputStream, null, bitmapOptions);
int imageWidth = bitmapOptions.outWidth;
int imageHeight = bitmapOptions.outHeight;
@SuppressWarnings("unused")
InputStream is = null;
try {
is = getContentResolver().openInputStream(selectedImage);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
float scale = 1.0f;
if (imageWidth < imageHeight) {
if (imageHeight > width * 1.0f) {
scale = width * 1.0f / (imageHeight * 1.0f);
}
} else {
if (imageWidth > width * 1.0f) {
scale = width * 1.0f / (imageWidth * 1.0f);
}
}
photoBitmap = decodeSampledBitmapFromResource(this,
selectedImage, (int) (imageWidth * scale),
(int) (imageHeight * scale));
return photoBitmap;
}
使用图像尺寸解码位图示例
public static Bitmap decodeSampledBitmapFromResource(Context context,
Uri uri, int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
InputStream is = null;
try {
is = context.getContentResolver().openInputStream(uri);
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
BitmapFactory.decodeStream(is, null, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth,
reqHeight);
// Decode editBitmap with inSampleSize set
options.inJustDecodeBounds = false;
InputStream inputs = null;
try {
inputs = context.getContentResolver().openInputStream(uri);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return BitmapFactory.decodeStream(inputs, null, 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) {
// Calculate ratios of height and width to requested height and
// width
final int heightRatio = Math.round((float) height
/ (float) reqHeight);
final int widthRatio = Math.round((float) width / (float) reqWidth);
// Choose the smallest ratio as inSampleSize value, this will
// guarantee
// a final image with both dimensions larger than or equal to the
// requested height and width.
inSampleSize = Math.min(heightRatio, widthRatio);
// inSampleSize = heightRatio < widthRatio ? heightRatio :
// widthRatio;
}
return inSampleSize;
}
或者可以使用 manifiest.xml
中的一行代码解决
在应用程序标签中使用此
android:largeHeap="true"