【问题标题】:Large image from resource get exception来自资源的大图像获取异常
【发布时间】:2023-04-07 21:54:02
【问题描述】:

我按照此链接中的示例进行操作: Viewpager Example in android

它工作正常,但是当我放置自己的高分辨率图像(大尺寸)时,它给了我例外:

java.lang.OutOfMemoryError:位图大小超出 VM 预算

我发布了一个关于该问题的旧问题,但由于这个原因它关闭了它,我尝试并搜索了很多,最后我找到了解决方案:通过以下操作缩放我的图像以避免内存异常:

在stackfllow和android开发站点中作者的建议和答案,我以波纹管代码结束,也以同样的异常结束,我认为我的代码有一些错误,因为我还在学习java和android开发,但那是什么我可以结束,请任何帮助或建议将不胜感激,

谢谢。

我的代码:

ViewPagerAdapter

  public class ViewPagerAdapter extends PagerAdapter {

Activity activity;
int imageArray[];

public ViewPagerAdapter(Activity act, int[] imgArra) {
    imageArray = imgArra;
    activity = act;
                           }

public int getCount() {
    return imageArray.length;
                        }

public Object instantiateItem(View collection, int position) {
    ImageView view = new ImageView(activity);
    view.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
            LayoutParams.MATCH_PARENT));
    view.setScaleType(ScaleType.FIT_XY);
    view.setBackgroundResource(imageArray[position]);
    ((ViewPager) collection).addView(view, 0);
    return view;
                              }

@Override
public void destroyItem(View arg0, int arg1, Object arg2) {
    ((ViewPager) arg0).removeView((View) arg2);
                              }

@Override
public boolean isViewFromObject(View arg0, Object arg1) {
    return arg0 == ((View) arg1);
                                     }

@Override
public Parcelable saveState() {
    return null;
                                       }
public static Bitmap decodeSampledBitmapFromResource(String imageArra,
        int reqWidth, int reqHeight) {      

        // First decode with inJustDecodeBounds=true to check dimensions
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(imageArra, options);

 // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;
    return BitmapFactory.decodeFile(imageArra, 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) {
        if (width > height) {
            inSampleSize = Math.round((float)height / (float)reqHeight);
        } else {
            inSampleSize = Math.round((float)width / (float)reqWidth);
                      }
                          }
    return inSampleSize;}}

PageIndicatorActivity

    public class PageIndicatorActivity extends Activity {

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ViewPagerAdapter adapter = new ViewPagerAdapter(this, imageArra);
    ViewPager myPager = (ViewPager) findViewById(R.id.myfivepanelpager);
    myPager.setAdapter(adapter);
    myPager.setCurrentItem(0);
                                 }

private int imageArra[] = { R.drawable.one, R.drawable.two,
        R.drawable.three, R.drawable.four,
        R.drawable.five, R.drawable.six,
        R.drawable.seven, R.drawable.eight,R.drawable.nine,
                          R.drawable.ten };  }

logcat 堆栈

   FATAL EXCEPTION: main
     java.lang.OutOfMemoryError: bitmap size exceeds VM budget
at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:563)
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:439)
at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:697)
at android.content.res.Resources.loadDrawable(Resources.java:1709)
at android.content.res.Resources.getDrawable(Resources.java:581)
at android.view.View.setBackgroundResource(View.java:7586)
at com.horizontalscrollviewwithpageindicator.ViewPagerAdapter.instantiateItem
        (ViewPagerAdapter.java:33)
at android.support.v4.view.PagerAdapter.instantiateItem(PagerAdapter.java:110)
at android.support.v4.view.ViewPager.addNewItem(ViewPager.java:692)
at android.support.v4.view.ViewPager.populate(ViewPager.java:875)
at android.support.v4.view.ViewPager.populate(ViewPager.java:772)
at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1234)
at android.view.View.measure(View.java:8366)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3138)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1017)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:386)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:309)
at android.view.View.measure(View.java:8366)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3138)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:250)
at android.view.View.measure(View.java:8366)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3138)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:250)
at android.view.View.measure(View.java:8366)
at android.view.ViewRoot.performTraversals(ViewRoot.java:844)
at android.view.ViewRoot.handleMessage(ViewRoot.java:1865)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:3687)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:842)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
at dalvik.system.NativeStart.main(Native Method)

【问题讨论】:

    标签: java android bitmap android-viewpager


    【解决方案1】:

    试试以下提示。

    -Android 可以很好地处理.png 图像,其中.jpg 格式的相同大小的图像 会创建一个OutOfMemoryError

    有关官方 Android 开发者网站的解决方案,请参见此链接:

    http://developer.android.com/training/displaying-bitmaps/load-bitmap.html

    【讨论】:

    • 我尝试了您的答案,并使用与上述代码相同的 .png 图像替换图像,然后您运行应用程序,它在移动设备关闭时出现黑屏,然后我删除了部分调用位图的代码,从(public static Bitmap decodeSampledBitmapFromResource(String imageArra, int reqWidth, int reqHeight) {),直到代码结束并运行应用程序给出相同的结果黑屏,请提供任何建议
    • 我还放置了比我第一次尝试更小的 .png 图像:java.lang.OutOfMemoryError:位图大小超出 VM 预算。亲爱的主人有什么建议,谢谢
    • 您的模拟器/设备的内存设置有多大?
    • @wdziemia 我在galaxy s上试用该应用
    • @wdziemia 你能看一下我的缩放位图代码的第二部分吗?从 (public static Bitmap decodeSampledBitmapFromResource(String imageArra, int reqWidth, int reqHeight) { ) 开始直到代码结束。请
    【解决方案2】:

    您从不使用该方法来缩放图像,而且您的 inSampleSize 需要是 2 的幂(我相信)。这些图像太大了(您在上一篇文章中所说的 4.5 mb)。在存储一个巨大的位图之上,视图寻呼机在任何给定时间都在内存中保留 3 个视图。您为视图寻呼机分配的内存大约是 >13.5mb。将您的实例化视图替换为以下内容:

    ImageView myView = new ImageView(context);
    BitmapFactory.Options options = new BitmapFactory.Options();
        options.inSampleSize = 4;
    
    Bitmap bitmap = BitmapFactory.decodeResource(activity.getResouces(), imageArray[position], options );
    myView.setImageBitmap(bitmap);
    
    ((ViewPager) view).addView(myView);   
    
    return myView;
    

    如果这仍然提供错误,请使用 options.inSampleSize = 8;

    【讨论】:

    • 请我有几点意见,1-当应用这个(options.inSampleSize = 4;)或你的答案代码这会导致减少设备上显示的图像分辨率或只是调整图像的大小而不影响图像质量,
    • 在你回答的我之前的帖子中,我在我的代码位图中使用了从资源中加载图像,但在这个帖子代码中,我使用了 R.drawable.image,这更好或两者都相同。最后在我创建画廊应用程序并加载比这里更大尺寸的图像之前,没有任何例外,但是随着图像尺寸的增加,viewpager 异常增加,非常感谢我亲爱的
    • 嘿我有同样的问题,但不同的是我的寻呼机使用 xml 布局而不是图像数组。我如何使用您的代码来解决我的问题?期待一些回复。谢谢。
    猜你喜欢
    • 2019-12-24
    • 1970-01-01
    • 2022-01-04
    • 2019-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    相关资源
    最近更新 更多