Android Canvas:大きすぎるビットマップの描画


97

Ubuntu16.04を実行しています。また、Android Studioでエミュレーターでアプリケーションを実行しようとすると、次のエラーが発生します。

致命的な例外:メインプロセス:プロジェクト名はこちら、PID:2528 java.lang.RuntimeException:キャンバス:大きすぎる(216090000バイト)ビットマップを描画しようとしています。android.view.DisplayListCanvas.throwIfCannotDraw(DisplayListCanvas.java:260)at android.graphics.Canvas.drawBitmap(Canvas.java:1415)at android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:528)atandroid。 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年


11
私の場合、(高解像度の)スプラッシュビットマップをdrawableからdrawable-xxhdpiに移動することが解決策でした。 私も同じ問題を抱えていました。スプラッシュ画面はアプリの起動時に表示されるので問題ないと思いましたが、スプラッシュ画面が問題であることがわかりました。私の場合のスプラッシュ画面の解像度はxxhdpiであり、drawable-xxhdpiではなくdrawableフォルダーに誤って配置されていました。これにより、Androidはスプラッシュ画面の解像度がmdpiであると想定し、画像を必要なサイズの3 * 3倍に拡大縮小して、ビットマップを作成しようとしました。
Zubair Rehman 2017

エミュレーターでのみ発生しますか、それとも同じ画面サイズのデバイスでのみ発生しますか?
ドミトリー

回答:


209

(高解像度)で、あなたのイメージを移動描画可能描画可能xxhdpi。ただし、アプリ開発では、大きな画像を使用する必要はありません。APKファイルのサイズが大きくなります。


6
おかげで、それは私の画像が500 kbしかないときにも機能しましたが、解像度が高すぎました。
ashishdhiman2007 2017年

1
APIから画像を読み込んでいるときにこのエラーが発生します。その場合の解決策は何でしょうか?
RohitSingh20年

4
Firebase Crashlyticsで同じ問題が発生しましたが、正確なファイルと行のコードが記載されていないため、このクラッシュの原因となった正確な画像がわかりません。明らかに、私のresファイルにはたくさんの画像がありますが、問題のある画像を見つけるにはどうすればよいですか
ravidrinek20年

19

解決策は、他の人も言及しているように、画像をdrawable/フォルダからフォルダに移動することdrawable-xxhdpi/です。

しかしこのやや奇妙な提案が実際に役立つ理由を理解することも重要です。

その理由は、drawable/フォルダーがAndroidの初期バージョンから存在し、と同等であるためdrawable-mdpiです。drawable/フォルダ内にある画像のみがxxhdpiデバイスで使用される場合、潜在的にすでに大きな画像が3倍に拡大され、場合によっては画像のメモリフットプリントが爆発する可能性があります。


3
これはdrawable/、他のdrawable-xディレクトリにアセットがある場合にディレクトリを削除できることを意味しますか?
カールテイラー

14

私も同じ問題を抱えていました。一部の低解像度デバイスで大きすぎる画像をアップロードしようとすると、アプリが折りたたまれます。サイズの異なる複数の画像(hdpi、xxdpiなど)を作成することも、外部ライブラリを使用して問題を迅速かつ効率的に解決する画像を読み込むこともできます。グライドライブラリを使用しました(ピカソのような別のライブラリを使用できます)。

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

7

問題は、当時アプリで使用していたメイン画像であることが判明しました。画像の実際のサイズが大きすぎるため、圧縮しました。その後、それは魅力のように機能し、品質を損なうことなく、アプリはエミュレーターで正常に実行されました。


@BekaBot元の質問は少し前からのものでした。しかし、正しく思い出せば、オンライン画像コンプレッサーを介して画像を実行し、アプリを再実行すると、正常に実行されました。これがお役に立てば幸いです。
フランシスコ

3

また、launch_backgrgound.xmlを介してAndroidアプリにスプラッシュ画面を追加しようとしたときにもこの問題が発生しました。問題は解決でした。高すぎたため、画像のメモリフットプリントが爆発し、アプリがクラッシュしたため、このエラーが発生しました。したがって、nativescript image Builderと呼ばれるサイトを使用して画像のサイズを変更するだけで、ldpi、mdpi、その他すべてを取得でき、問題なく機能しました。


私の日を救ってください、同じ問題。
Abdul BasitRishi20年

2

このエラーは、他の人がドローアブルディレクトリにある大きな画像(1800px X 900px)と言ったように、フォトショップを使用して画像を編集し、比例してサイズを縮小しました... !!


2

ピカソを使用する場合は、このようにグライドに変更してください。

ピカソを削除

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

グライドを変更

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

ピカソが大きなビットマップに描画するよりも効率的なグライド


3
グライドでこれと同じエラーが発生しました。URLを介した画像の読み込みで、画像は2MBしかありません。
ドラキヤ王子

1

ディレクトリdrawable-xhdpi(必要に応じて変更できます)を作成し、すべての画像をそのディレクトリにコピーして貼り付けました。


1

この解決策は私のために働いた。

これらの行をマニフェストアプリケーションタグに追加します

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

    


0

私の場合、Androidプラットフォームを削除して、再度追加する必要がありました。何かがスタックし、すべてのコードを別のアプリにコピーすることは魅力のように機能しました-したがって、プラットフォームを削除して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

jpgまたはpngの代わりにxmlまたはベクターアセットを使用してみてください。

その理由は、例外名自体から明らかです。つまり、リソースの解像度が大きすぎてレンダリングできません。

https://svg2vector.com/などのオンラインツールを使用してxmlにpngするか、画像をdrawable-xxhdpiフォルダーに追加できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.