Ho un'immagine di 5000 x 4000 px che voglio disegnare su una tela.Caricamento di immagini grandi senza OutOfMemoryError
Prima ho provato a caricarlo dalle risorse. L'ho messo in /res/drawable
.
ho usato il seguente metodo:
InputStream input = getResources().openRawResource(R.drawable.huge_image);
Drawable d = Drawable.createFromStream(input, "image");
d.setBounds(...);
d.draw(canvas);
Ha funzionato come un fascino.
In questo caso lo InputStream
è un AssetManager.AssetInputStream
.
Quindi ora voglio caricarlo dalla sdcard.
Qui è quello che ho cercato di fare:
File f = new File(path);
Uri uri = Uri.fromFile(f);
InputStream input = mContext.getContentResolver().openInputStream(uri);
Drawable d = Drawable.createFromStream(input, "image");
In questo caso il InputStream
è un FileInputStream
e ho ricevuto una OutOfMemoryError
durante la creazione del Drawable
.
Quindi mi chiedo:
C'è un modo per caricare l'immagine senza ottenere quell'errore? O c'è un modo per convertire un FileInputStream
in un AssetInputStream
?
Nota:
Non voglio per ridimensionare l'immagine, perché sto implementando funzionalità di zoom/pan. Per favore non dirmi di leggere Loading Large Bitmaps Efficiently.
È possibile controllare l'intera classe here. L'errore si verifica quando si utilizza setImageUri()
.
Ecco il mio Registro errori:
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)
EDIT:
stavo testando il mio codice su un A8181 HTC Desire. Dopo aver saputo che il primo frammento di codice non funzionava su altri dispositivi, ho provato su un Samsung Galaxy S2 e sull'emulatore.
Risultati: Quando si carica dalle risorse, l'emulatore ha dato un OutOfMemoryError
, il Galaxy S2 non ha un'eccezione, ma la tornata Drawable
era nullo.
Quindi immagino che per il momento l'unica soluzione sia il downsampling dell'immagine.
Ho provato a eseguire il codice su em em em e riscuote l'errore OutOfMemory anche nel metodo "From Res" :) Quali impostazioni di dispositivo e/o emulatore utilizzate è stato in grado di eseguirlo senza errori? – Joe