0
votes

I am using itext library in order to create a pdf of images and text. The following code works fine on 3 out of 4 devices but on the 4th device I get OutOfMemoryException. The code is being run inside an AsyncTask doinbackground method, it is checking the rotation of each jpg file (directory of files from sdcard) using a bimtmap object, measuring the width against the height, and rotating the itext Image object 90degrees if necessary.

        try {

            Document document = new Document();
            PdfWriter.getInstance(document, new FileOutputStream(
                    Environment.getExternalStorageDirectory()
                            + "/doc" + documentID + ".pdf"));
            document.open();
            document.setMargins(0f, 0f, 0f, 0f);
            document.add(new Paragraph(documentNameEt.getText().toString()));
            document.add(new Paragraph(makeUserDeets()));
            Bitmap b = null;
            Image image = null;
            Rectangle r = document.getPageSize();
            for (String d : paths[0]) {
                Log.d("senddataobj", d);
                image = Image.getInstance(d);
                b = BitmapFactory.decodeFile(d);
                if (b.getWidth() > b.getHeight()) {
                    image.setRotationDegrees(90);
                    Log.d(d, "rotating");
                }
                b.recycle();
                image.scaleToFit(r.getWidth(), r.getHeight());
                document.add(image);                
            }

            document.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }

java.lang.RuntimeException: An error occured while executing doInBackground() at android.os.AsyncTask$3.done(AsyncTask.java:278) at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273) at java.util.concurrent.FutureTask.setException(FutureTask.java:124) at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307) at java.util.concurrent.FutureTask.run(FutureTask.java:137) at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:208) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569) at java.lang.Thread.run(Thread.java:856) Caused by: java.lang.OutOfMemoryError at android.graphics.BitmapFactory.nativeDecodeStream(Native Method) at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:493) at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:299) at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:324) at com.wake.snapshot.CreateDocumentActivity$CreateAndSendPdf.doInBackground(CreateDocumentActivity.java:315) at com.wake.up.your.wealth.snapshot.CreateDocumentActivity$CreateAndSendPdf.doInBackground(CreateDocumentActivity.java:1) at android.os.AsyncTask$2.call(AsyncTask.java:264) at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305) ... 5 more

1
How big are the images (dimensions)? It's possible that you are genuinely running out of memory. Have you considered assembling the document image by image instead of keeping them all in memory?dmon
Thanks, I used the options class to get a null bitmap object with the dimensions, then used the dims in the options object.brux

1 Answers

1
votes

As you need only a size of the bitmap use BitmapFactory with inJustDecodeBounds Option http://developer.android.com/reference/android/graphics/BitmapFactory.Options.html#inJustDecodeBounds ... It will return null Bitmap but you will have size in outHeight and outWidth