Autore Topic: Upload immagine: Out of memory on a 31961104-byte allocation  (Letto 1034 volte)

Offline ccmex

  • Nuovo arrivato
  • *
  • Post: 41
  • Respect: 0
    • Mostra profilo
Upload immagine: Out of memory on a 31961104-byte allocation
« il: 25 Settembre 2014, 11:56:31 CEST »
0
Upload immagine: Out of memory on a 31961104-byte allocation

Ciao, ho un problema quando provo ad inviare un file immagine dal mio smartphone ad un server remoto tramite un webservice.

L'errore è il seguente dal LogCat:

Codice: [Seleziona]
09-25 11:48:54.175: W/Choreographer(12979): Already have a pending vsync event.  There should only be one at a time.
09-25 11:48:54.235: D/dalvikvm(12979): GC_FOR_ALLOC freed 1497K, 19% free 46108K/56648K, paused 54ms, total 54ms
09-25 11:48:54.235: I/dalvikvm-heap(12979): Forcing collection of SoftReferences for 31961104-byte allocation
09-25 11:48:54.280: D/dalvikvm(12979): GC_BEFORE_OOM freed 10K, 19% free 46098K/56648K, paused 43ms, total 43ms
09-25 11:48:54.280: E/dalvikvm-heap(12979): Out of memory on a 31961104-byte allocation.
09-25 11:48:54.280: I/dalvikvm(12979): "Thread-9829" prio=5 tid=11 RUNNABLE
09-25 11:48:54.280: I/dalvikvm(12979):   | group="main" sCount=0 dsCount=0 obj=0x425e5cf8 self=0x5994b920
09-25 11:48:54.280: I/dalvikvm(12979):   | sysTid=13515 nice=0 sched=0/0 cgrp=apps handle=1498943496
09-25 11:48:54.280: I/dalvikvm(12979):   | state=R schedstat=( 87020166 10222375 29 ) utm=7 stm=1 core=1
09-25 11:48:54.280: I/dalvikvm(12979):   at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
09-25 11:48:54.285: I/dalvikvm(12979):   at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:623)
09-25 11:48:54.285: I/dalvikvm(12979):   at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:378)
09-25 11:48:54.285: I/dalvikvm(12979):   at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:417)
09-25 11:48:54.285: I/dalvikvm(12979):   at com.up.upload.MainActivity.UploadImage(MainActivity.java:202)
09-25 11:48:54.285: I/dalvikvm(12979):   at com.up.upload.MainActivity$2.run(MainActivity.java:148)
09-25 11:48:54.285: I/dalvikvm(12979):   at java.lang.Thread.run(Thread.java:841)
09-25 11:48:54.295: D/skia(12979): --- decoder->decode returned false
09-25 11:48:54.295: W/dalvikvm(12979): threadid=11: thread exiting with uncaught exception (group=0x41b55700)
09-25 11:48:54.300: E/AndroidRuntime(12979): FATAL EXCEPTION: Thread-9829
09-25 11:48:54.300: E/AndroidRuntime(12979): java.lang.OutOfMemoryError
09-25 11:48:54.300: E/AndroidRuntime(12979):         at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
09-25 11:48:54.300: E/AndroidRuntime(12979):         at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:623)
09-25 11:48:54.300: E/AndroidRuntime(12979):         at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:378)
09-25 11:48:54.300: E/AndroidRuntime(12979):         at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:417)
09-25 11:48:54.300: E/AndroidRuntime(12979):         at com.up.upload.MainActivity.UploadImage(MainActivity.java:202)
09-25 11:48:54.300: E/AndroidRuntime(12979):         at com.up.upload.MainActivity$2.run(MainActivity.java:148)
09-25 11:48:54.300: E/AndroidRuntime(12979):         at java.lang.Thread.run(Thread.java:841)
Questo il codice java in uso, cosa posso fare di più?
Grazie
Codice: [Seleziona]
        public void UploadImage(String image, String imageName) {

                SoapObject Request = new SoapObject(WSDL_TARGET_NAMESPACE,
                                OPERATION_NAME);

                File mFile = new File(imagepath);
                ByteArrayOutputStream stream = new ByteArrayOutputStream();
                Bitmap bmp = BitmapFactory.decodeFile(mFile.getAbsolutePath());
                bmp.recycle();
                bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
                byte[] byteArray = stream.toByteArray();
                Request.addProperty("docbinaryarray", byteArray);

                SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
                                SoapEnvelope.VER11);

                envelope.dotNet = true;

                envelope.setOutputSoapObject(Request);

                HttpTransportSE androidHttpTransport = new HttpTransportSE(SOAP_ADDRESS);
                androidHttpTransport.debug = true;

                try {

                        androidHttpTransport.call(SOAP_ACTION, envelope);

                        SoapPrimitive resultString = (SoapPrimitive) envelope.getResponse();
                        Log.d("MainActivity.class", "Valore restituito: " + resultString);

                } catch (Exception e) {
                        e.printStackTrace();
                }
        }



                        new Thread(new Runnable() {
                                public void run() {

                                        try {

                                                String lStr = imagepath;
                                                UploadImage(
                                                                imagepath,
                                                                lStr.substring(lStr.lastIndexOf("/")).replace(
                                                                                "/", ""));

                                        } catch (Exception e) {
                                                e.printStackTrace();
                                                Log.e("MainActivity.class", "Errore nel metodo 2...", e);
                                        }
                                }
                        }).start();
« Ultima modifica: 25 Settembre 2014, 12:04:10 CEST da ccmex »

Offline BlackJad

  • Utente junior
  • **
  • Post: 59
  • Respect: +6
    • Google+
    • michele-ziparo/4/825/a99/
    • blackjad82
    • Mostra profilo
    • Datawit Systems
  • Dispositivo Android:
    Samsung Galaxy S3
  • Play Store ID:
    Michele Ziparo
  • Sistema operativo:
    Windows 8.1
Re:Upload immagine: Out of memory on a 31961104-byte allocation
« Risposta #1 il: 25 Settembre 2014, 13:10:58 CEST »
0
Se l'immagine è troppo grande è un problema abbastanza frequente, dovresti secondo me implementare il caricamento a chunk, tipo un servizio di streaming.

Offline ccmex

  • Nuovo arrivato
  • *
  • Post: 41
  • Respect: 0
    • Mostra profilo
Re:Upload immagine: Out of memory on a 31961104-byte allocation
« Risposta #2 il: 25 Settembre 2014, 13:19:34 CEST »
0
Grazie, a parte il fatto che sono file di piccola entità, ma sembra che il problema sia in fase di decode del file :

Codice: [Seleziona]
                                                Bitmap bmp = BitmapFactory.decodeFile(mFile
                                                                .getAbsolutePath());

Nel LogCat risulta questa segnalazione:
Codice: [Seleziona]
09-25 13:17:47.555: D/skia(27367): --- decoder->decode returned false
Forse non legge il file?

Offline BlackJad

  • Utente junior
  • **
  • Post: 59
  • Respect: +6
    • Google+
    • michele-ziparo/4/825/a99/
    • blackjad82
    • Mostra profilo
    • Datawit Systems
  • Dispositivo Android:
    Samsung Galaxy S3
  • Play Store ID:
    Michele Ziparo
  • Sistema operativo:
    Windows 8.1
Re:Upload immagine: Out of memory on a 31961104-byte allocation
« Risposta #3 il: 25 Settembre 2014, 13:24:17 CEST »
0
Uhm, un formato di immagine non compatibile?

Offline ccmex

  • Nuovo arrivato
  • *
  • Post: 41
  • Respect: 0
    • Mostra profilo
Re:Upload immagine: Out of memory on a 31961104-byte allocation
« Risposta #4 il: 25 Settembre 2014, 13:33:38 CEST »
0
Uhm, un formato di immagine non compatibile?
Forse hai ragione, ma è mai possibile?
Questo è il codice:
Codice: [Seleziona]
                File mFile = new File("/storage/emulated/0/DCIM/Camera/20140923_084731.jpg");
                ByteArrayOutputStream stream = new ByteArrayOutputStream();
                Bitmap bmp = BitmapFactory.decodeFile(mFile.getAbsolutePath());
                bmp.recycle();
                bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
                byte[] byteArray = stream.toByteArray();
                Request.addProperty("docbinaryarray", byteArray);


Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Re:Upload immagine: Out of memory on a 31961104-byte allocation
« Risposta #5 il: 25 Settembre 2014, 14:03:12 CEST »
0
Sicuro sia un'immagine di piccole dimensioni?

Dal path sembra che sia una foto, per cui si parla di milioni di pixel anche per terminali molto vecchi.
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

Offline ccmex

  • Nuovo arrivato
  • *
  • Post: 41
  • Respect: 0
    • Mostra profilo
Re:Upload immagine: Out of memory on a 31961104-byte allocation
« Risposta #6 il: 25 Settembre 2014, 14:11:50 CEST »
0
Sicuro sia un'immagine di piccole dimensioni?

Dal path sembra che sia una foto, per cui si parla di milioni di pixel anche per terminali molto vecchi.
Grazie per l'intervento.
L'immagine 20140923_084731.jpg pesa 1,85 MB.
La cosa che mi lascia perplesso è che l'upload sul server remoto funziona correttamente, il nome del file è corretto (20140923_084731.jpg) così come la cartella dove viene inserito ("D:\\Inetpub\\wwwroot\\uploads\\"), ma sempre con zero kilobytes ... non riesco a passare al webservice i bytes che costituiscono l'immagine ....  :-(

Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Re:Upload immagine: Out of memory on a 31961104-byte allocation
« Risposta #7 il: 25 Settembre 2014, 14:26:30 CEST »
0
L'immagine 20140923_084731.jpg pesa 1,85 MB.

I megabytes contano solo quando nella forma "codificata su file". Al memomento in cui viene decodificata e caricata tutta in memoria, assume dimensioni dipendenti dal numero di pixel (ad esempio 4bytes per pixel) e per le foto fatte con la Camera è molto molto probabile che si generi un OutOfMemory.

Se puoi mandare direttamente il file, senza fare decodifica e ri-codifica, dovresti riuscirci facilmente.
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

Offline ccmex

  • Nuovo arrivato
  • *
  • Post: 41
  • Respect: 0
    • Mostra profilo
Re:Upload immagine: Out of memory on a 31961104-byte allocation
« Risposta #8 il: 25 Settembre 2014, 14:33:32 CEST »
0
I megabytes contano solo quando nella forma "codificata su file". Al memomento in cui viene decodificata e caricata tutta in memoria, assume dimensioni dipendenti dal numero di pixel (ad esempio 4bytes per pixel) e per le foto fatte con la Camera è molto molto probabile che si generi un OutOfMemory.

Se puoi mandare direttamente il file, senza fare decodifica e ri-codifica, dovresti riuscirci facilmente.
Ti ringrazio molto per le indicazioni.
Ho provato così a mandare direttamente il file, senza fare decodifica e ri-codifica, ma non va.... allego LogCat:
Codice: [Seleziona]
File mFile = new File(imagepath);
Log.d("MainActivity.class", "mFile: " + mFile);
Request.addProperty("byteArray", mFile);


09-25 14:29:58.490: D/MainActivity.class(10919):
mFile: /storage/emulated/0/DCIM/Camera/20140923_084731.jpg

09-25 14:29:58.530: W/System.err(10919):
java.lang.RuntimeException: Cannot serialize: /storage/emulated/0/DCIM/Camera/20140923_084731.jpg

09-25 14:29:58.530: W/System.err(10919):        
at org.ksoap2.serialization.SoapSerializationEnvelope.writeElement(SoapSerializationEnvelope.java:708)

09-25 14:29:58.530: W/System.err(10919):        
at org.ksoap2.serialization.SoapSerializationEnvelope.writeProperty(SoapSerializationEnvelope.java:692)

09-25 14:29:58.530: W/System.err(10919):        
at org.ksoap2.serialization.SoapSerializationEnvelope.writeObjectBody(SoapSerializationEnvelope.java:661)

09-25 14:29:58.530: W/System.err(10919):        
at org.ksoap2.serialization.SoapSerializationEnvelope.writeObjectBody(SoapSerializationEnvelope.java:645)

09-25 14:29:58.530: W/System.err(10919):        
at org.ksoap2.serialization.SoapSerializationEnvelope.writeElement(SoapSerializationEnvelope.java:702)

09-25 14:29:58.530: W/System.err(10919):        
at org.ksoap2.serialization.SoapSerializationEnvelope.writeBody(SoapSerializationEnvelope.java:618)

09-25 14:29:58.530: W/System.err(10919):        
at org.ksoap2.SoapEnvelope.write(SoapEnvelope.java:198)

09-25 14:29:58.530: W/System.err(10919):        
at org.ksoap2.transport.Transport.createRequestData(Transport.java:111)

09-25 14:29:58.530: W/System.err(10919):        
at org.ksoap2.transport.HttpTransportSE.call(HttpTransportSE.java:119)

09-25 14:29:58.530: W/System.err(10919):        
at org.ksoap2.transport.HttpTransportSE.call(HttpTransportSE.java:95)

09-25 14:29:58.530: W/System.err(10919):        
at com.up.upload.MainActivity$2.run(MainActivity.java:237)

09-25 14:29:58.530: W/System.err(10919):        
at java.lang.Thread.run(Thread.java:841)
« Ultima modifica: 25 Settembre 2014, 15:08:01 CEST da ccmex »

Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Re:Upload immagine: Out of memory on a 31961104-byte allocation
« Risposta #9 il: 25 Settembre 2014, 15:24:54 CEST »
0
Credo tu debba cercare come fare a serializzare file generico, con Soap. Mi spiace ma non l'ho mai fatto.
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

Offline ccmex

  • Nuovo arrivato
  • *
  • Post: 41
  • Respect: 0
    • Mostra profilo
Re:Upload immagine: Out of memory on a 31961104-byte allocation
« Risposta #10 il: 25 Settembre 2014, 16:01:42 CEST »
0
Credo tu debba cercare come fare a serializzare file generico, con Soap. Mi spiace ma non l'ho mai fatto.

Grazie, ho risolto così.
Codice: [Seleziona]
        public void UploadImage(String image, String imageName) {

                String lStr = imagepath;

                File mFile = new File(imagepath);
                Log.d("MainActivity.class", "mFile: " + mFile);

                SoapObject Request = new SoapObject(WSDL_TARGET_NAMESPACE,
                                OPERATION_NAME);

                byte[] bytearray = null;
                try {
                        FileInputStream is = new FileInputStream(mFile);
                        if (mFile != null)
                                try {
                                        bytearray = streamToBytes(is);
                                } finally {
                                        is.close();
                                }
                } catch (Exception e) {
                }

                Request.addProperty("docbinaryarray", bytearray);

                SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
                                SoapEnvelope.VER11);

                new MarshalBase64().register(envelope);
                envelope.dotNet = true;
                envelope.encodingStyle = "UTF-8";
                envelope.setOutputSoapObject(Request);

                HttpTransportSE androidHttpTransport = new HttpTransportSE(SOAP_ADDRESS);
                androidHttpTransport.debug = true;

                try {

                        androidHttpTransport.call(SOAP_ACTION, envelope);

                        SoapPrimitive resultString = (SoapPrimitive) envelope.getResponse();
                        Log.d("MainActivity.class", "Valore restituito: " + resultString);

                } catch (Exception e) {
                        e.printStackTrace();
                }
        }


        public static byte[] streamToBytes(InputStream is) {
                ByteArrayOutputStream os = new ByteArrayOutputStream(1024);
                byte[] buffer = new byte[1024];
                int len;
                try {
                        while ((len = is.read(buffer)) >= 0) {
                                os.write(buffer, 0, len);
                        }
                } catch (java.io.IOException e) {
                }
                return os.toByteArray();
        }


                        new Thread(new Runnable() {
                                public void run() {
                                        try {

                                                String lStr = imagepath;
                                                UploadImage(
                                                                imagepath,
                                                                lStr.substring(lStr.lastIndexOf("/")).replace(
                                                                                "/", ""));
                                        } catch (Exception e) {
                                                e.printStackTrace();
                                                Log.e("MainActivity.class", "Errore nel metodo 2...", e);
                                        }
                                }
                        }).start();

Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Re:Upload immagine: Out of memory on a 31961104-byte allocation
« Risposta #11 il: 25 Settembre 2014, 16:08:54 CEST »
0
Grazie, ho risolto così.

Se ti funziona, ottimo e grazie per aver postato il codice usato (potrà essere utile ad altri).  :-)
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store