繁体   English   中英

位图图像内存不足Android

[英]BitMap Image Out Of Memory Android

我的虚拟杂志上有数百张图片。 图像为1241* 1754像素,分辨率为150 pixels/inch 滑动到这些页面的3/4 ,我得到了内存不足的错误,如日志中所示。

12-04 10:20:50.781: E/AndroidRuntime(3236): java.lang.OutOfMemoryError
12-04 10:20:50.781: E/AndroidRuntime(3236):     at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
12-04 10:20:50.781: E/AndroidRuntime(3236):     at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:572)
12-04 10:20:50.781: E/AndroidRuntime(3236):     at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:440)
12-04 10:20:50.781: E/AndroidRuntime(3236):     at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:773)
12-04 10:20:50.781: E/AndroidRuntime(3236):     at android.content.res.Resources.loadDrawable(Resources.java:1974)
12-04 10:20:50.781: E/AndroidRuntime(3236):     at android.content.res.Resources.getDrawable(Resources.java:677)
12-04 10:20:50.781: E/AndroidRuntime(3236):     at fi.harism.curl.LPMagHome$PageProvider.loadBitmap(LPMagHome.java:192)
12-04 10:20:50.781: E/AndroidRuntime(3236):     at fi.harism.curl.LPMagHome$PageProvider.updatePage(LPMagHome.java:266)
12-04 10:20:50.781: E/AndroidRuntime(3236):     at fi.harism.curl.CurlView.updatePage(CurlView.java:713)
12-04 10:20:50.781: E/AndroidRuntime(3236):     at fi.harism.curl.CurlView.startCurl(CurlView.java:554)
12-04 10:20:50.781: E/AndroidRuntime(3236):     at fi.harism.curl.CurlView.onTouch(CurlView.java:280)
12-04 10:20:50.781: E/AndroidRuntime(3236):     at android.view.View.dispatchTouchEvent(View.java:5583)
12-04 10:20:50.781: E/AndroidRuntime(3236):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1968)
12-04 10:20:50.781: E/AndroidRuntime(3236):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1695)
12-04 10:20:50.781: E/AndroidRuntime(3236):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1968)
12-04 10:20:50.781: E/AndroidRuntime(3236):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1695)
12-04 10:20:50.781: E/AndroidRuntime(3236):     at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1968)

*

这是我加载位图图像的工作的一部分。 有人可以通过一些研究帮助我如何处理内存不足错误,我看到了此博客java.lang.OutOfMemoryError BitmapFactory.nativeDecodeAsset(),但是我无法将其应用于以下方法loadBitmap。

private Bitmap loadBitmap(int width, int height, int index) {
            Bitmap b = Bitmap.createBitmap(width, height,
                    Bitmap.Config.ARGB_8888);
            b.eraseColor(0xFFFFFFFF);
            c = new Canvas(b);
            d = getResources().getDrawable(mBitmapIds[index]);
            System.out.println("canvas width: "+c.getWidth());

            int margin = 3;//7
            int border = 3;//2
            Rect r = new Rect(margin, margin, width - margin, height - margin);
            int imageWidth = r.width() - (border * 2);
            int imageHeight = imageWidth * d.getIntrinsicHeight()
                    / d.getIntrinsicWidth();
            if (imageHeight > r.height() - (border * 2)) {
                imageHeight = r.height() - (border * 2);
                imageWidth = imageHeight * d.getIntrinsicWidth()
                        / d.getIntrinsicHeight();
            }
            Log.d("TAG", String.valueOf(imageHeight));
            if (lp.getWindow().getWindowManager().getDefaultDisplay()
                    .getOrientation() == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {
                // portrait mode
                r.left += ((r.width() - imageWidth) / 2) - border;
                r.right = r.left + imageWidth + border + border;
            } else if (lp.getWindow().getWindowManager().getDefaultDisplay()
                    .getOrientation() == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {
                // landscape
                r.left += ((r.width() - imageWidth)) - border-122;
                r.right = r.left + imageWidth + border + border+122;
            }
            r.top += ((r.height() - imageHeight) / 2) - border;
            r.bottom = r.top + imageHeight + border + border;
            Paint p = new Paint();
            p.setColor(0xFFC0C0C0);
            c.drawRect(r, p);
            r.left += border;
            r.right -= border;
            r.top += border;
            r.bottom -= border;
            d.setBounds(r);
            d.draw(c);
            return b;
        }*

更新:使用此方法滑动时页面会更新

@Override public void updatePage(CurlPage页面,int宽度,int高度,int索引){

        DisplayMetrics displaymetrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
        int wwidth = displaymetrics.widthPixels;
        int hheight = displaymetrics.heightPixels;


        if(wwidth > hheight){

            System.out.println("index "+(index*2));
            System.out.println("index2 "+(index*2)+1);
            System.out.println("case landscape orientation...");

            if (index >0){

                front = loadBitmap(width, height, (index*2));
                back = loadBitmap(width, height, (index*2)+1);

            }else {

                front = loadBitmap(width, height, (index));
                back = loadBitmap(width, height, (index));
            }

            Matrix matrix = new Matrix(); 
            matrix.preScale(-1.0f, 1.0f); 
            Bitmap mirroredBitmap = Bitmap.createBitmap(back, 0, 0, back.getWidth(), back.getHeight(), matrix, false);

            page.setTexture(front, CurlPage.SIDE_FRONT);
            page.setTexture(mirroredBitmap, CurlPage.SIDE_BACK);



        } else {

            System.out.println("case portrait orientation...");
            Bitmap front = loadBitmap(width, height, index);
            Bitmap back = loadBitmap(width, height, index);

            System.out.println( "MyActivity.onCreate debug message "+String.valueOf(index));

            page.setTexture(front, CurlPage.SIDE_FRONT);
            page.setTexture(back, CurlPage.SIDE_BACK);

        }

    }

}

您可能正在泄漏内存。 通过删除对内存的所有引用来检查是否释放了内存,以避免出现此问题。 另外请记住,某些设备的内存不足,因此您需要使用更少的内存。

另请参阅我有关如何查找内存泄漏的答案。

您可能需要调整位图的大小,我也遇到了这个问题并使用以下代码解决了这个问题:

public static Bitmap getResizedBitmap(Bitmap image, int newHeight, int newWidth) {
    int width = image.getWidth();
    int height = image.getHeight();
    float scaleWidth = ((float) newWidth) / width;
    float scaleHeight = ((float) newHeight) / height;
    // create a matrix for the manipulation
    Matrix matrix = new Matrix();
    // resize the bit map
    matrix.postScale(scaleWidth, scaleHeight);
    // recreate the new Bitmap
    Bitmap resizedBitmap = Bitmap.createBitmap(image, 0, 0, width, height,
            matrix, false);
    return resizedBitmap;
}

这是播放大量图像时的普遍问题。 Nikita我建议您使用一个api库,该库负责加载图像,并在图像出现问题或其他重要问题时清除缓存。 是github项目的链接,下载jar并将其添加到项目的libs文件夹中。

要配置图像,请检查

可能有内存泄漏。 如果该位图不再有用,则可以调用bitmap.recycle()来节省内存。 另外,您可以尝试按比例缩小位图:

Bitmap scale_down = Bitmap.createScaledBitmap(original_bmp, original_bmp.getWidth()/2, original_bmp.getHeight()/2, true);

我看不到您的所有代码,因此只能假设您将所有图像都放入了内存。 我想您可以将屏幕上显示的图像放入内存,然后将其他图像从内存中释放出来,这样可以实现并减少占用的内存。 请阅读以下内容: 将图像加载到Bitmap对象时出现内存不足的问题

对不起,我的英语不好!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM