Android Canvas : 너무 큰 비트 맵 그리기


87

Ubuntu 16.04를 실행하고 있습니다. Android Studio에서 에뮬레이터에서 애플리케이션을 실행하려고하면 다음 오류가 발생합니다.

치명적 예외 : 주요 프로세스 : 여기에 프로젝트 이름, PID : 2528 java.lang.RuntimeException : 캔버스 : 너무 큰 (216090000bytes) 비트 맵을 그리려고합니다. android.view.DisplayListCanvas.throwIfCannotDraw (DisplayListCanvas.java:260) at android.graphics.Canvas.drawBitmap (Canvas.java:1415) at android.graphics.drawable.BitmapDrawable.draw (BitmapDrawable.java:528) at android. widget.ImageView.onDraw (ImageView.java:1316) at android.view.View.draw (View.java:17185) at android.view.View.updateDisplayListIfDirty (View.java:16167) at android.view.View.draw (View.java:16951) at android.view.ViewGroup.drawChild (ViewGroup.java:3727) at android.view.ViewGroup.dispatchDraw (ViewGroup.java :
기타...

에뮬레이터를 작동시키기 위해 몇 가지 후프를 거쳐야했지만 AMD에서 에뮬레이터를 실행할 수 있도록 심볼릭 링크를 만들어야했습니다. 이것이 문제의 일부인지 확실하지 않습니다. 그리고 제 삶을 위해 왜이 일을 계속하는지 알 수 없습니다. 내 그룹에는 동일한 에뮬레이트 된 전화 및 SDK에서 프로젝트를 잘 에뮬레이트하는 다른 사람들이 있습니다.


사용하여 더 작은 크기로 비트 맵을 읽으려고 BitmapOption.inSampleSize했습니까?
L. Swifter 2016


10
필자의 경우 (고해상도) 스플래시 비트 맵을 drawable에서 drawable-xxhdpi로 이동하는 것이 해결책이었습니다. 나는 같은 문제가 있었다. 앱이 시작될 때 표시되기 때문에 스플래시 화면이 문제라고 생각하지 않았지만 스플래시 화면이 문제인 것으로 판명되었습니다. 제 경우의 스플래시 화면은 xxhdpi 해상도를 가지며 drawable-xxhdpi 대신 drawable 폴더에 실수로 배치되었습니다. 이로 인해 Android는 스플래시 화면에 mdpi 해상도가 있다고 가정하고 이미지를 필요한 크기의 3 * 3 배로 조정하고 비트 맵을 만들려고했습니다.
Zubair Rehman

에뮬레이터에서만 발생하나요, 아니면 화면 크기가 같은 기기에서도 발생하나요?
Dmitry

답변:


200

(고해상도) 드로어 블 의 이미지 를 drawable-xxhdpi로 이동 합니다. 그러나 앱 개발에서는 큰 이미지를 사용할 필요가 없습니다. APK 파일 크기가 증가합니다.


6
감사합니다. 내 이미지가 500kb에 불과할 때도 효과가 있었지만 해상도가 너무 높았습니다.
ashishdhiman2007

1
API에서 이미지를로드하는 동안이 오류가 발생합니다. 이 경우 해결책은 무엇입니까?
Rohit Singh

2
Firebase Crashlytics 에서 동일한 문제가 발생 했지만 정확한 파일 + 줄 코드를 언급하지 않았 으므로이 충돌을 일으키는 정확한 이미지가 무엇인지 모르겠습니다. 분명히 내 res 파일에 많은 이미지가 있습니다. 문제가있는 이미지를 어떻게 찾을 수
있습니까?

15

해결책은 다른 사람들도 언급했듯이 이미지를 drawable/폴더 에서 폴더 로 이동하는 것 drawable-xxhdpi/입니다.

그러나이 다소 이상한 제안이 실제로 도움이되는 이유 를 이해하는 것도 중요합니다 .

그 이유는 drawable/폴더가 Android의 초기 버전에 존재하고 drawable-mdpi. drawable/폴더 에만있는 이미지가 xxhdpi장치에서 사용되는 경우 잠재적으로 이미 큰 이미지가 3 배로 업 스케일링되어 경우에 따라 이미지의 메모리 사용량이 폭발 할 수 있습니다.


2
drawable/다른 drawable-x디렉토리에 자산이있는 경우 디렉토리를 제거 할 수 있습니까?
Karl Taylor

14

나는 같은 문제가 있었다. 일부 저해상도 장치에서 너무 큰 이미지를 업로드하려고하면 앱이 축소됩니다. 크기가 다른 여러 이미지 (hdpi, xxdpi 등)를 만들거나 단순히 외부 라이브러리를 사용하여 문제를 빠르고 효율적으로 해결하는 이미지를로드 할 수 있습니다. 저는 Glide 라이브러리를 사용했습니다 (Picasso와 같은 다른 라이브러리를 사용할 수 있음).

    panel_IMG_back = (ImageView) findViewById(R.id.panel_IMG_back);
    Glide
            .with(this)
            .load(MyViewUtils.getImage(R.drawable.wallpaper)
            .into(panel_IMG_back);

6

문제는 당시 앱에서 사용했던 메인 이미지였습니다. 이미지의 실제 크기가 너무 커서 압축했습니다. 그런 다음 매력처럼 작동하고 품질 손실이 없었으며 앱이 에뮬레이터에서 제대로 실행되었습니다.


@BekaBot 원래 질문은 얼마 전의 질문이었습니다. 그러나 내가 올바르게 기억하면 온라인 이미지 압축기를 통해 이미지를 실행 한 다음 앱을 다시 실행하면 정상적으로 실행됩니다. 이게 도움이 되길 바란다.
Francisco

3

launch_backgrgound.xml을 통해 Android 앱에 스플래시 화면을 추가하려고 할 때도이 문제가 발생했습니다. 문제는 해결책이었습니다. 너무 높기 때문에 이미지 메모리 공간이 폭발하여 앱이 충돌하여이 오류의 원인이되었습니다. 그래서 nativescript 이미지 빌더라는 사이트를 사용하여 이미지의 크기를 조정하여 ldpi, mdpi 및 나머지를 모두 얻었고 잘 작동했습니다.


내 하루를 절약하십시오.
Abdul Basit Rishi

2

이 오류는 다른 사람들이 드로어 블 디렉토리에있는 큰 이미지 (1800px X 900px)라고 말한 것처럼 포토샵을 사용하여 이미지를 편집하고 비례 적으로 크기를 줄였고 작동했습니다 ... !!


2

Picasso를 사용하면 Glide로 변경됩니다.

피카소 제거

Picasso.get().load(Uri.parse("url")).into(imageView)

글라이드 변경

Glide.with(context).load("url").into(imageView)

Picasso가 큰 비트 맵으로 그리는 것보다 더 효율적인 글라이드


3
Glide에서 이와 동일한 오류가 발생하고 URL을 통해 이미지가로드되며 2MB의 이미지입니다.
Prince Dholakiya

1

방금 drawable-xhdpi 디렉터리를 만들고 (필요에 따라 변경할 수 있음) 모든 이미지를 해당 디렉터리에 붙여 넣었습니다.


0

제 경우에는 안드로이드 플랫폼을 제거하고 다시 추가해야했습니다. 무언가가 막혀서 내 모든 코드를 다른 앱에 복사하는 것이 매력처럼 작동했습니다. 따라서 플랫폼을 제거하여 Android 용 빌드를 정리하는 것이 좋습니다.

cordova platform remove android
cordova platform add android

나는 때때로 당신이해야 할 일종의 정리라고 생각합니다 :-(


0

이것은 Glide에서 문제가 될 수 있습니다. 많은 이미지를로드하려고 할 때 이것을 사용하고 그중 일부는 매우 큽니다.

Glide.load("your image path")
                       .transform(
                               new MultiTransformation<>(
                                       new CenterCrop(),
                                       new RoundedCorners(
                                               holder.imgCompanyLogo.getResources()
                                                       .getDimensionPixelSize(R.dimen._2sdp)
                                       )
                               )
                       )
                       .error(R.drawable.ic_nfs_default)
                       .into(holder.imgCompanyLogo);
           }

0

이 솔루션은 저에게 효과적이었습니다.

Manifest 애플리케이션 태그 에 다음 행을 추가하십시오.

android:largeHeap="true"
android:hardwareAccelerated="false"

    

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.