当前位置: 首页 > 面试题库 >

加载大图像而没有OutOfMemoryError

邹阳
2023-03-14
问题内容

我有一个5000 x 4000像素的图像,想要绘制到画布上。

首先,我尝试从资源中加载它。我把它放进去了/res/drawable

我使用以下方法:

InputStream input = getResources().openRawResource(R.drawable.huge_image);
Drawable d = Drawable.createFromStream(input, "image");
d.setBounds(...);
d.draw(canvas);

它像魅力一样运作。

在这种情况下,InputStreamAssetManager.AssetInputStream

所以现在我想从sdcard加载它。

这是我尝试做的事情:

File f = new File(path);
Uri uri = Uri.fromFile(f);
InputStream input = mContext.getContentResolver().openInputStream(uri);
Drawable d = Drawable.createFromStream(input, "image");

在这种情况下,InputStream是,创建时FileInputStream得到OutOfMemoryErrorDrawable

所以我想知道:

有没有一种方法可以加载图像而不会出现该错误?还是有办法将a转换FileInputStreamAssetInputStream

注意:

我不想调整图像的大小,因为我正在实现缩放/平移功能。请不要告诉我阅读有效加载大位图。

您可以在此处查看完整课程。使用时发生错误setImageUri()

这是我的错误日志:

08-13 11:57:54.180: E/AndroidRuntime(23763): FATAL EXCEPTION: main
08-13 11:57:54.180: E/AndroidRuntime(23763): java.lang.OutOfMemoryError: bitmap size exceeds VM budget
08-13 11:57:54.180: E/AndroidRuntime(23763):    at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
08-13 11:57:54.180: E/AndroidRuntime(23763):    at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:468)
08-13 11:57:54.180: E/AndroidRuntime(23763):    at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:332)
08-13 11:57:54.180: E/AndroidRuntime(23763):    at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:697)
08-13 11:57:54.180: E/AndroidRuntime(23763):    at android.graphics.drawable.Drawable.createFromStream(Drawable.java:657)
08-13 11:57:54.180: E/AndroidRuntime(23763):    at com.benitobertoli.largeimagezoom.ZoomImageView.setDrawablefromUri(ZoomImageView.java:187)
08-13 11:57:54.180: E/AndroidRuntime(23763):    at com.benitobertoli.largeimagezoom.ZoomImageView.setImageUri(ZoomImageView.java:588)
08-13 11:57:54.180: E/AndroidRuntime(23763):    at com.benitobertoli.largeimagezoom.TestActivity.onKeyDown(TestActivity.java:30)
08-13 11:57:54.180: E/AndroidRuntime(23763):    at android.view.KeyEvent.dispatch(KeyEvent.java:1257)
08-13 11:57:54.180: E/AndroidRuntime(23763):    at android.app.Activity.dispatchKeyEvent(Activity.java:2075)
08-13 11:57:54.180: E/AndroidRuntime(23763):    at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1673)
08-13 11:57:54.180: E/AndroidRuntime(23763):    at android.view.ViewRoot.deliverKeyEventToViewHierarchy(ViewRoot.java:2493)
08-13 11:57:54.180: E/AndroidRuntime(23763):    at android.view.ViewRoot.handleFinishedEvent(ViewRoot.java:2463)
08-13 11:57:54.180: E/AndroidRuntime(23763):    at android.view.ViewRoot.handleMessage(ViewRoot.java:1752)
08-13 11:57:54.180: E/AndroidRuntime(23763):    at android.os.Handler.dispatchMessage(Handler.java:99)
08-13 11:57:54.180: E/AndroidRuntime(23763):    at android.os.Looper.loop(Looper.java:144)
08-13 11:57:54.180: E/AndroidRuntime(23763):    at android.app.ActivityThread.main(ActivityThread.java:4937)
08-13 11:57:54.180: E/AndroidRuntime(23763):    at java.lang.reflect.Method.invokeNative(Native Method)
08-13 11:57:54.180: E/AndroidRuntime(23763):    at java.lang.reflect.Method.invoke(Method.java:521)
08-13 11:57:54.180: E/AndroidRuntime(23763):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
08-13 11:57:54.180: E/AndroidRuntime(23763):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
08-13 11:57:54.180: E/AndroidRuntime(23763):    at dalvik.system.NativeStart.main(Native Method)

编辑:

我正在HTC Desire A8181上测试代码。在被告知第一个代码段在某些其他设备上不起作用后,我在三星Galaxy S2和仿真器上进行了测试。

结果:从资源加载时,仿真器给出了OutOfMemoryError,Galaxy S2没有引发异常,但返回Drawable为null。

因此,我认为目前唯一的解决方案是对图像进行下采样。


问题答案:

看一眼:

http://developer.android.com/reference/android/graphics/BitmapFactory.html

decodeStream (InputStream is, Rect outPadding, BitmapFactory.Options opts)

要么

decodeFile (String pathName, BitmapFactory.Options opts)

这样,您可以加载整个位图并将其显示在屏幕上。

您需要设置正确的选项。

http://developer.android.com/reference/android/graphics/BitmapFactory.Options.html

inSampleSize

我用您的代码尝试过:

 BitmapFactory.Options options = new BitmapFactory.Options();

 options.inSampleSize = 4;

 Bitmap myBitmap = BitmapFactory.decodeFile(mUri.getPath(),options);
 Drawable d = new BitmapDrawable(Resources.getSystem(),myBitmap);
 updateDrawable(d);

为我工作。



 类似资料:
  • 问题内容: 我试图让用户从其硬盘驱动器中加载图像,并在GUI中以缩略图列表的形式直观显示这些图像(JPanel的图标添加到JList)。我目前正在使用ImageIO.read()获取BufferedImage,并对每个图像使用getScaledInstance(听说您不应该使用它)。 它适用于小图像,但可以加载四张以上的照片(5000x3000或类似图片),并且出现“ java.lang.OutO

  • 我正在尝试优化一个页面,该页面由带有断点的图像网格组成,使其使用1、2、3或4列。 html看起来像这样:

  • 问题内容: 我正在使用MEDIUMBLOB将图像存储在DB中。当我尝试通过servlet加载图像时,可以看到这些图像。但是,如果图像很大(1 MB或更大),我可以在浏览器中看到一半或3/4的图像。 当我下载相同的图像并将其放在公共Web内容中时,它可以完美运行。任何想法如何克服这个问题?我需要在servlet或MySQL中设置任何变量吗? (由JSF生成的)HTML代码如下: 图像servlet执

  • 问题内容: 我从其他页面加载HTML以提取并显示该页面中的数据: 确实可以,但是由于我的浏览器尝试加载在205.html中链接的图像。这些图像在我的域中不存在,因此出现很多404错误。 有没有办法像解析页面一样但不将整个页面加载到浏览器中? 问题答案: 实际上,如果您查看jQuery文档,它说您可以将“所有者文档”作为第二个参数传递给。 因此,我们可以做的是创建一个虚拟文档,以使浏览器不会自动加载

  • 我使用intelliJ IDEA中的maven webapp原型创建了一个spring项目。我正在使用tomcat插件和maven插件。我可以在app name/home路径上运行这个应用程序,但是css和图像没有加载,它显示的是简单的文本和图像表情。 在项目内部,我创建了ApplicationInitializer类,这很好,ApplicationConfig看起来像这样- 下面是文件夹结构-

  • 我想在我的Android应用程序中增加位图的大小。 基本上,我想创建一个新的位图,其宽度与原始位图相同,但高度更大。(新)额外像素的背景可以是黑色、白色或透明。 我该怎么做?